{"id":28465,"date":"2021-08-06T18:54:28","date_gmt":"2021-08-06T18:54:28","guid":{"rendered":"http:\/\/Video-Skit-Maker-in-Next.js-Video-Transformations"},"modified":"2025-03-02T14:50:59","modified_gmt":"2025-03-02T22:50:59","slug":"video-skit-maker-in-next-js-video-transformations","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/","title":{"rendered":"Video Skit Maker in Next.js &#8211; Video Transformations"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>In the first part of this post, we discussed how to upload a video with an audio clip to make a skit (short video clip). In this tutorial, we will learn how to add further transformations to the video. The transformations will add text, a progress bar, blur, and crop to the video as desired.<\/p>\n<p>You don\u2019t need to read the first part of this tutorial to follow through with this one.<\/p>\n<h2>Sandbox<\/h2>\n<p>We completed the project on <a href=\"https:\/\/codesandbox.io\/s\/audio-video-transformation-6q9x2\">CodeSandbox<\/a>; you can fork it to get started quickly.<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    \n<\/code><\/span><\/pre>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/audio-video-transformation-6q9x2?theme=dark&amp;codemirror=1&amp;highlights=&amp;editorsize=50&amp;fontsize=14&amp;expanddevtools=0&amp;hidedevtools=0&amp;eslint=0&amp;forcerefresh=0&amp;hidenavigation=0&amp;initialpath=%2F&amp;module=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"Video Transformation\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n  <div class=\"wp-block-cloudinary-markdown \"><pre class=\"js-syntax-highlighted\"><code>GitHub repository: https:\/\/github.com\/Olanetsoft\/audio-video-transformation\n\n## Prerequisites &amp; Installation\n\nThe knowledge of JavaScript and React.js is required to follow through with this article. Also, you require [Node.js](https:\/\/nodejs.org\/en\/) and its package manager NPM installed to proceed.\n\nVerify you have Node installed using the following terminal command:\n\n```bash\n    node -v &amp;&amp; npm -v \n<\/code><\/pre>\n<p>The above command should output their respective version number if installed.<\/p>\n<h2>Scaffolding a Next.js Project<\/h2>\n<p>In the first part of this post, we built a <a href=\"https:\/\/codesandbox.io\/s\/video-and-audio-upload-with-nextjs-zvuo9\">Next.js app<\/a> that allowed us to upload videos and add an audio transformation using Cloudinary. In that part, we used the Cloudinary upload widget to upload media assets to Cloudinary. The component\u2019s state stores the returned asset\u2019s Cloudinary public ID.<\/p>\n<p><strong>We will continue development on the first part\u2019s Next.js app.<\/strong> You can fork it to proceed.\n<a href=\"https:\/\/codesandbox.io\/s\/video-and-audio-upload-with-nextjs-zvuo9\">https:\/\/codesandbox.io\/s\/video-and-audio-upload-with-nextjs-zvuo9<\/a><\/p>\n<p>Alternatively, we can create a new Next.js project using the <code>npx create-next-app<\/code> command.<\/p>\n<p>Once the app is initialized and the dependencies automatically installed, we will see a message with instructions for navigating to our site and running it locally. We do this with the command.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    cd <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">project<\/span> <span class=\"hljs-attr\">name<\/span>&gt;<\/span> &amp;&amp; npm start\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Next.js will start a hot-reloading development environment accessible by default at <a href=\"http:\/\/localhost:3000\">http:\/\/localhost:3000<\/a>.<\/p>\n<h2>Installing Cloudinary<\/h2>\n<p>We will use the <a href=\"https:\/\/www.npmjs.com\/package\/react-cloudinary\">C<\/a><a href=\"https:\/\/www.npmjs.com\/package\/react-cloudinary\">loudinary React package<\/a>, a React.js library that helps us optimally render Cloudinary videos and handles video transformations.<\/p>\n<p>We can use <a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery\">Cloudinary\u2019s robust transformation features<\/a> to modify the video distributed through an integrated content delivery network (CDN).<\/p>\n<p>We install the cloudinary-react package in the project\u2019s directory using npm with:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm i cloudinary-react\n<\/code><\/span><\/pre>\n<h2>Adding video transformation controls<\/h2>\n<p>We will display the controls for the video transformations on the home page by updating the functional component, <code>pages\/index.js<\/code> created in part one, to include the following code snippet in this GitHub Gist.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/Chuloo\/420595bb7e083a6d9d9ec84f85e0aa85\">https:\/\/gist.github.com\/Chuloo\/420595bb7e083a6d9d9ec84f85e0aa85<\/a><\/p>\n<p><a href=\"https:\/\/gist.github.com\/Chuloo\/420595bb7e083a6d9d9ec84f85e0aa85\">https:\/\/gist.github.com\/Chuloo\/420595bb7e083a6d9d9ec84f85e0aa85<\/a><\/p>\n<p>Here, we added form fields for:<\/p>\n<ul>\n<li>A progress bar with a color of either red or blue<\/li>\n<li>Video crop with two options of <em>scale<\/em> and <em>crop<\/em>\n<\/li>\n<li>Custom text input<\/li>\n<li>A blur effect on the video<\/li>\n<\/ul>\n<p>The current user interface doesn\u2019t look aesthetically pleasing; thus, we add some style with CSS. We update the CSS styles in <code>\/css\/style.css<\/code> to the following content in this GitHub Gist:<\/p>\n<p><a href=\"https:\/\/gist.github.com\/Chuloo\/33434d6ed74109bb032313c33652efff\">https:\/\/gist.github.com\/Chuloo\/33434d6ed74109bb032313c33652efff<\/a><\/p>\n<p><a href=\"https:\/\/gist.github.com\/Chuloo\/33434d6ed74109bb032313c33652efff\">https:\/\/gist.github.com\/Chuloo\/33434d6ed74109bb032313c33652efff<\/a><\/p>\n<p>We imported this CSS file in the <code>_app.js<\/code> file in the <code>pages<\/code> directory of the project. If it isn\u2019t imported or non-existent, we need to create an <code>_app.js<\/code> file inside the <code>pages<\/code> directory. This file is native to Next.js and wraps the whole application. We\u2019ll import the CSS file we created into this <code>_app.js<\/code> file with:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">\"..\/css\/style.css\"<\/span>;\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">MyApp<\/span>(<span class=\"hljs-params\">{ Component, pageProps }<\/span>) <\/span>{\n      <span class=\"hljs-keyword\">return<\/span> <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Component<\/span> {<span class=\"hljs-attr\">...pageProps<\/span>} \/&gt;<\/span><\/span>;\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Our application should look like this on <a href=\"http:\/\/localhost:3000\/\">http:\/\/localhost:3000\/<\/a>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_F19353A25A84E43375C9979AC164224999C0327144AD9A30CD12AB6070584D48_1625009120556_Screenshot+2021-06-30+at+00.24.45.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1156\"\/><\/p>\n<h2>Implement transformation functions<\/h2>\n<p>To handle video transformations, we need to create a component that handles the transformation depending on the props passed to the component. We create a <code>components\/<\/code> folder in the root directly and create a file <code>video.js<\/code> in the folder with the following content.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> { CloudinaryContext, Transformation, Video } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary-react\"<\/span>;\n    <span class=\"hljs-keyword\">const<\/span> TransformVideo = <span class=\"hljs-function\">(<span class=\"hljs-params\">{video, audio}<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">\"olanetsoft\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Video<\/span> <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">{video}<\/span> <span class=\"hljs-attr\">controls<\/span> <span class=\"hljs-attr\">autoplay<\/span>=<span class=\"hljs-string\">\"true\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">overlay<\/span>=<span class=\"hljs-string\">{<\/span>`<span class=\"hljs-attr\">video:<\/span>${<span class=\"hljs-attr\">audio<\/span>}`} \/&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Video<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/span>&gt;<\/span><\/span>\n      );\n    };\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> TransformVideo;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Here, we imported <code>CloudinaryContext<\/code>, a wrapper Cloudinary component used to manage shared information across all its children\u2019s Cloudinary components. The rendered <code>TransformVideo<\/code> component takes data of video and audio as props. This video information (public ID) passed is sent to the video component. We set the audio data as a transformation on the video.<\/p>\n<p>The above code block will render the uploaded video with the background audio when we import it into <code>pages\/index.js<\/code>:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> React, { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { Helmet } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-helmet\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> TransformVideo <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/components\/video\"<\/span>;\n    <span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> &#91;videoPublicId, setVideoPublicId] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;alt, setAlt] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;audioPublicId, setAudioPublicId] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> openWidget = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        <span class=\"hljs-comment\">\/\/ widget creation logic<\/span>\n        <span class=\"hljs-keyword\">const<\/span> widget = <span class=\"hljs-built_in\">window<\/span>.cloudinary.createUploadWidget(\n              {\n                <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">\"olanetsoft\"<\/span>,\n                <span class=\"hljs-attr\">uploadPreset<\/span>: <span class=\"hljs-string\">\"w42epls6\"<\/span>\n              },\n              (error, result) =&gt; {\n                <span class=\"hljs-keyword\">if<\/span> (result.event === <span class=\"hljs-string\">\"success\"<\/span>) {\n                  <span class=\"hljs-built_in\">console<\/span>.log(result.info);\n                  <span class=\"hljs-keyword\">if<\/span> (result.info.is_audio === <span class=\"hljs-literal\">true<\/span>) {\n                    setAudioPublicId(result.info.public_id);\n                    setAlt(<span class=\"hljs-string\">`A file of <span class=\"hljs-subst\">${result.info.original_filename}<\/span>`<\/span>);\n                  } <span class=\"hljs-keyword\">else<\/span> {\n                    setVideoPublicId(result.info.public_id);\n                    setAlt(<span class=\"hljs-string\">`A file of <span class=\"hljs-subst\">${result.info.original_filename}<\/span>`<\/span>);\n                  }\n                 }\n              }\n            );\n            widget.open();\n      };\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"App\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">section<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"right-side\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>The resulting video with audio will be displayed here<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n              {videoPublicId &amp;&amp; (\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">TransformVideo<\/span>\n                  <span class=\"hljs-attr\">audio<\/span>=<span class=\"hljs-string\">{audioPublicId}<\/span>\n                  <span class=\"hljs-attr\">video<\/span>=<span class=\"hljs-string\">{videoPublicId}<\/span>\n                \/&gt;<\/span>\n              )}\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span>\n            {\/*JSX code in there including form fields and buttons*\/}\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n      );\n    };\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>After importing the <code>TransformVideo<\/code> component and uploading a video, we should have had a video playing, which should look like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/cloudinary-marketing-res.cloudinary.com\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/media_jams\/s_F19353A25A84E43375C9979AC164224999C0327144AD9A30CD12AB6070584D48_1625754160403_Screenshot+2021-07-08+at+15.22.15.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1156\"\/><\/p>\n<p>We\u2019ll update our <code>TransformVideo<\/code> component to accept props for various video transformation operations. Let\u2019s start with changing the color of the progress bar. We update the <code>TransformVideo<\/code> component to include the <code>color<\/code> props.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">const<\/span> TransformVideo = <span class=\"hljs-function\">(<span class=\"hljs-params\">{color, video, audio}<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">\"olanetsoft\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Video<\/span> <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">{video}<\/span> <span class=\"hljs-attr\">controls<\/span> <span class=\"hljs-attr\">autoplay<\/span>=<span class=\"hljs-string\">\"true\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">overlay<\/span>=<span class=\"hljs-string\">{<\/span>`<span class=\"hljs-attr\">video:<\/span>${<span class=\"hljs-attr\">audio<\/span>}`} \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">effect<\/span>=<span class=\"hljs-string\">{<\/span>`<span class=\"hljs-attr\">progressbar:bar:<\/span>${<span class=\"hljs-attr\">color<\/span>}<span class=\"hljs-attr\">:30<\/span>`} \/&gt;<\/span>\n            \n            {\/*Add the color here*\/}\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">effect<\/span>=<span class=\"hljs-string\">{<\/span>`<span class=\"hljs-attr\">progressbar:bar:<\/span>${<span class=\"hljs-attr\">color<\/span>}<span class=\"hljs-attr\">:30<\/span>`} \/&gt;<\/span>\n    \n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Video<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/span>&gt;<\/span><\/span>\n      );\n    };\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In <code>pages\/index.js<\/code>, we create a state variable to contain the selected color using the <code>useState<\/code> hook, with a default color of <em>green<\/em>.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> React, { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n    \n    <span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> &#91;color, setColor] = useState(<span class=\"hljs-string\">\"green\"<\/span>);\n      <span class=\"hljs-comment\">\/\/...<\/span>\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>We add an <code>onChange<\/code> event handler on the radio inputs rendered to update the <code>color<\/code> state variable once an option is selected.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-comment\">\/\/ ...<\/span>\n        &lt;input\n          type=<span class=\"hljs-string\">\"radio\"<\/span>\n          value=<span class=\"hljs-string\">\"blue\"<\/span>\n          name=<span class=\"hljs-string\">\"color\"<\/span>\n          <span class=\"hljs-comment\">\/\/ Add the onChange attribute here<\/span>\n          onChange={(event) =&gt; setColor(event.target.value)}\n        \/&gt;\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span>&gt;<\/span>Blue<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span><\/span>\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n          <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"radio\"<\/span>\n          <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"red\"<\/span>\n          <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"color\"<\/span>\n        \n          \/\/ <span class=\"hljs-attr\">Add<\/span> <span class=\"hljs-attr\">the<\/span> <span class=\"hljs-attr\">onChange<\/span> <span class=\"hljs-attr\">attribute<\/span> <span class=\"hljs-attr\">here<\/span>\n          <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> setColor(event.target.value)}\n        \/&gt;<\/span>\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span>&gt;<\/span>Red<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span><\/span>    \n    <span class=\"hljs-comment\">\/\/ ...<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Next, we update the <code>TransformVideo<\/code> component rendered in <code>pages\/index.js<\/code> to include the progress bar color information.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> React, { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { Helmet } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-helmet\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> TransformVideo <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/components\/video\"<\/span>;\n    <span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-comment\">\/\/ state variables and methond definitions go in here<\/span>\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">main<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"App\"<\/span>&gt;<\/span>\n            {\/*JSX rendered in here...*\/}\n    \n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">section<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"right-side\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h1<\/span>&gt;<\/span>The resulting video with audio will be displayed here<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h1<\/span>&gt;<\/span>\n              {videoPublicId &amp;&amp; (\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">TransformVideo<\/span>\n                  <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">{color}<\/span>\n                  <span class=\"hljs-attr\">audio<\/span>=<span class=\"hljs-string\">{audioPublicId}<\/span>\n                  <span class=\"hljs-attr\">video<\/span>=<span class=\"hljs-string\">{videoPublicId}<\/span>\n                \/&gt;<\/span>\n              )}\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">main<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n      );\n    };\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Similarly, to add Cloudinary transformations including <code>crop<\/code>, <code>text<\/code>, and <code>blur<\/code> effect, we modify the <code>TransformVideo<\/code> component\u2019s definition to accept the values as props and create the state variables in the <code>pages\/index.js<\/code>.<\/p>\n<p>We modify <code>TransformVideo<\/code> to:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> { CloudinaryContext, Transformation, Video } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"cloudinary-react\"<\/span>;\n    \n    <span class=\"hljs-keyword\">const<\/span> TransformVideo = <span class=\"hljs-function\">(<span class=\"hljs-params\">{ crop, color, text, blur, audio, video }<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-keyword\">return<\/span> (\n        <span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">CloudinaryContext<\/span> <span class=\"hljs-attr\">cloudName<\/span>=<span class=\"hljs-string\">\"olanetsoft\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Video<\/span> <span class=\"hljs-attr\">publicId<\/span>=<span class=\"hljs-string\">{video}<\/span> <span class=\"hljs-attr\">controls<\/span> <span class=\"hljs-attr\">autoplay<\/span>=<span class=\"hljs-string\">\"true\"<\/span>&gt;<\/span>\n           <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">overlay<\/span>=<span class=\"hljs-string\">{<\/span>`<span class=\"hljs-attr\">video:<\/span>${<span class=\"hljs-attr\">audio<\/span>}`} \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">effect<\/span>=<span class=\"hljs-string\">{<\/span>`<span class=\"hljs-attr\">progressbar:bar:<\/span>${<span class=\"hljs-attr\">color<\/span>}<span class=\"hljs-attr\">:30<\/span>`} \/&gt;<\/span>\n           \n            {\/*Added more transformation effect below*\/}\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span>\n              <span class=\"hljs-attr\">overlay<\/span>=<span class=\"hljs-string\">{{<\/span>\n                <span class=\"hljs-attr\">fontFamily:<\/span> \"<span class=\"hljs-attr\">arial<\/span>\",\n                <span class=\"hljs-attr\">fontSize:<\/span> <span class=\"hljs-attr\">60<\/span>,\n                <span class=\"hljs-attr\">text<\/span>\n              }}\n              <span class=\"hljs-attr\">endOffset<\/span>=<span class=\"hljs-string\">\"9.0\"<\/span>\n              <span class=\"hljs-attr\">gravity<\/span>=<span class=\"hljs-string\">\"south\"<\/span>\n              <span class=\"hljs-attr\">startOffset<\/span>=<span class=\"hljs-string\">\"2.0\"<\/span>\n              <span class=\"hljs-attr\">y<\/span>=<span class=\"hljs-string\">\"80\"<\/span>\n            \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">effect<\/span>=<span class=\"hljs-string\">{<\/span>`<span class=\"hljs-attr\">blur:<\/span>${<span class=\"hljs-attr\">blur<\/span>}`} <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">{crop}<\/span> \/&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Transformation<\/span> <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"500\"<\/span> <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"350\"<\/span> <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">{crop}<\/span> \/&gt;<\/span> \n    \n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Video<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">CloudinaryContext<\/span>&gt;<\/span><\/span>\n      );\n    };\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> TransformVideo;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>In <code>pages\/index.js<\/code>, we add state variables to manage the <code>blur<\/code>, <code>crop<\/code>, and <code>text<\/code> transformations.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">    <span class=\"hljs-keyword\">import<\/span> React, { useState } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> { Helmet } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react-helmet\"<\/span>;\n    <span class=\"hljs-keyword\">import<\/span> TransformVideo <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/components\/video\"<\/span>;\n    <span class=\"hljs-keyword\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-keyword\">const<\/span> &#91;videoPublicId, setVideoPublicId] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;alt, setAlt] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;audioPublicId, setAudioPublicId] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;textValue, setTextValue] = useState(<span class=\"hljs-string\">\" \"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;color, setColor] = useState(<span class=\"hljs-string\">\"green\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;crop, setCrop] = useState(<span class=\"hljs-string\">\"scale\"<\/span>);\n      <span class=\"hljs-keyword\">const<\/span> &#91;blur, setBlur] = useState(<span class=\"hljs-string\">\"\"<\/span>);\n      };\n      <span class=\"hljs-keyword\">return<\/span> (\n        {<span class=\"hljs-comment\">\/*Returned JSX goes in here*\/<\/span>}\n      );\n    };\n    <span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> App;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>We also set default state values for each variable.<\/p>\n<p>For each transformation\u2019s input element, we add an <code>onChange<\/code> event handler to update its state value.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/...\n          \n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span>Crop Video<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"label\"<\/span>&gt;<\/span>Select Type<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n          <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"radio\"<\/span>\n          <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"scale\"<\/span>\n          <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"crop\"<\/span>\n    \n          \/\/ <span class=\"hljs-attr\">Add<\/span> <span class=\"hljs-attr\">the<\/span> <span class=\"hljs-attr\">onChange<\/span> <span class=\"hljs-attr\">attribute<\/span> <span class=\"hljs-attr\">for<\/span> <span class=\"hljs-attr\">crop<\/span> <span class=\"hljs-attr\">transformation<\/span> <span class=\"hljs-attr\">here<\/span>\n          <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> setCrop(event.target.value)}\n    \n        \/&gt;\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span>&gt;<\/span>Scale<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n            <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"radio\"<\/span>\n            <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"crop\"<\/span>\n            <span class=\"hljs-attr\">name<\/span>=<span class=\"hljs-string\">\"crop\"<\/span>\n           \n            \/\/ <span class=\"hljs-attr\">Add<\/span> <span class=\"hljs-attr\">the<\/span> <span class=\"hljs-attr\">onChange<\/span> <span class=\"hljs-attr\">attribut<\/span> <span class=\"hljs-attr\">for<\/span> <span class=\"hljs-attr\">crop<\/span> <span class=\"hljs-attr\">transformation<\/span> <span class=\"hljs-attr\">here<\/span>\n            <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> setCrop(event.target.value)}\n    \n          \/&gt;\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span>&gt;<\/span>Crop<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span>Text<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"label\"<\/span>&gt;<\/span>Add Text<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n            <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"text\"<\/span>\n            <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\"<\/span>\n    \n            \/\/ <span class=\"hljs-attr\">Add<\/span> <span class=\"hljs-attr\">the<\/span> <span class=\"hljs-attr\">onChange<\/span> <span class=\"hljs-attr\">attribute<\/span> <span class=\"hljs-attr\">for<\/span> <span class=\"hljs-attr\">textValue<\/span> <span class=\"hljs-attr\">effect<\/span> <span class=\"hljs-attr\">here<\/span>\n            <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> setTextValue(event.target.value)}\n          \/&gt;\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h3<\/span>&gt;<\/span>Blur Effect<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h3<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"label\"<\/span>&gt;<\/span>Adjust Blur Effect<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span>\n          <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"number\"<\/span>\n    \n          \/\/ <span class=\"hljs-attr\">Add<\/span> <span class=\"hljs-attr\">the<\/span> <span class=\"hljs-attr\">onChange<\/span> <span class=\"hljs-attr\">attribute<\/span> <span class=\"hljs-attr\">for<\/span> <span class=\"hljs-attr\">blur<\/span> <span class=\"hljs-attr\">transformation<\/span> <span class=\"hljs-attr\">here<\/span>\n          <span class=\"hljs-attr\">onChange<\/span>=<span class=\"hljs-string\">{(event)<\/span> =&gt;<\/span> setBlur(event.target.value)}\n        \/&gt;\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n    \n    \/\/ ...\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Lastly, we pass props of the state data to the rendered <code>TransformVideo<\/code> with:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml shcb-wrap-lines\">    \/\/ ...\n    \n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">section<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"right-side\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">TransformVideo<\/span>\n          <span class=\"hljs-attr\">crop<\/span>=<span class=\"hljs-string\">{crop}<\/span>\n          <span class=\"hljs-attr\">color<\/span>=<span class=\"hljs-string\">{color}<\/span>\n          <span class=\"hljs-attr\">text<\/span>=<span class=\"hljs-string\">{textValue}<\/span>\n          <span class=\"hljs-attr\">blur<\/span>=<span class=\"hljs-string\">{blur}<\/span>\n          \/\/<span class=\"hljs-attr\">...<\/span>\n        \/&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span>\n    \n    \/\/ ...\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>You can see what the the final App.js file looks like in this GitHub Gist. This includes audio\/video upload and video transformation.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/Chuloo\/36d3ddcb643452f01530197b8a49c8d1\">https:\/\/gist.github.com\/Chuloo\/36d3ddcb643452f01530197b8a49c8d1<\/a><\/p>\n<p>With this, we complete our application development, and it looks like this:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/chuloo\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1626468578\/ezgif.com-gif-maker_jeb1uf.gif\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1200\" height=\"694\"\/><\/p>\n<h1>Conclusion<\/h1>\n<p>This article discussed how to add multiple transformations to a video file, completing an app that lets you upload a video, having an audio file playing in the background while displaying multiple transformations.\nFurthermore, you can add multiple video transformations and controls for each of them.<\/p>\n<!-- Please check over the project, during rebuild unable to play videos, scale, and crop as well as in demo -->\n<h1>Resources<\/h1>\n<p>You may find these resources useful.<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery\">Cloudinary video transformations<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/transformation_reference\">Cloudinary transformation URL reference<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28466,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,175,212,371,303],"class_list":["post-28465","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","tag-jamstack","tag-next-js","tag-under-review","tag-video"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Video Skit Maker in Next.js - Video Transformations<\/title>\n<meta name=\"description\" content=\"In this tutorial, the second part of a 2-part series, learn how to handle video transformations while building a video skit maker.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Video Skit Maker in Next.js - Video Transformations\" \/>\n<meta property=\"og:description\" content=\"In this tutorial, the second part of a 2-part series, learn how to handle video transformations while building a video skit maker.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-08-06T18:54:28+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-03-02T22:50:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c-jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"5143\" \/>\n\t<meta property=\"og:image:height\" content=\"3429\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Video Skit Maker in Next.js &#8211; Video Transformations\",\"datePublished\":\"2021-08-06T18:54:28+00:00\",\"dateModified\":\"2025-03-02T22:50:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/\"},\"wordCount\":9,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"JAMStack\",\"Next.js\",\"Under Review\",\"Video\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/\",\"name\":\"Video Skit Maker in Next.js - Video Transformations\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c.jpg?_i=AA\",\"datePublished\":\"2021-08-06T18:54:28+00:00\",\"dateModified\":\"2025-03-02T22:50:59+00:00\",\"description\":\"In this tutorial, the second part of a 2-part series, learn how to handle video transformations while building a video skit maker.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c.jpg?_i=AA\",\"width\":5143,\"height\":3429},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Video Skit Maker in Next.js &#8211; Video Transformations\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Video Skit Maker in Next.js - Video Transformations","description":"In this tutorial, the second part of a 2-part series, learn how to handle video transformations while building a video skit maker.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/","og_locale":"en_US","og_type":"article","og_title":"Video Skit Maker in Next.js - Video Transformations","og_description":"In this tutorial, the second part of a 2-part series, learn how to handle video transformations while building a video skit maker.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/","og_site_name":"Cloudinary Blog","article_published_time":"2021-08-06T18:54:28+00:00","article_modified_time":"2025-03-02T22:50:59+00:00","og_image":[{"width":5143,"height":3429,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c-jpg?_i=AA","type":"image\/jpeg"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/"},"author":{"name":"","@id":""},"headline":"Video Skit Maker in Next.js &#8211; Video Transformations","datePublished":"2021-08-06T18:54:28+00:00","dateModified":"2025-03-02T22:50:59+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/"},"wordCount":9,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c.jpg?_i=AA","keywords":["Guest Post","JAMStack","Next.js","Under Review","Video"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/","name":"Video Skit Maker in Next.js - Video Transformations","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c.jpg?_i=AA","datePublished":"2021-08-06T18:54:28+00:00","dateModified":"2025-03-02T22:50:59+00:00","description":"In this tutorial, the second part of a 2-part series, learn how to handle video transformations while building a video skit maker.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c.jpg?_i=AA","width":5143,"height":3429},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-transformations\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Video Skit Maker in Next.js &#8211; Video Transformations"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924469\/Web_Assets\/blog\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c\/6630b061263efc1a770419bb4f4717ad7fe0e5a2-5143x3429-1_28466cd59c.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=28465"}],"version-history":[{"count":1,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28465\/revisions"}],"predecessor-version":[{"id":37095,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28465\/revisions\/37095"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28466"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}