{"id":28520,"date":"2021-08-06T18:55:36","date_gmt":"2021-08-06T18:55:36","guid":{"rendered":"http:\/\/Video-Skit-Maker-in-Next.js-Video-and-Audio-Upload"},"modified":"2021-08-06T18:55:36","modified_gmt":"2021-08-06T18:55:36","slug":"video-skit-maker-in-next-js-video-and-audio-upload","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/","title":{"rendered":"Video Skit Maker in Next.js &#8211; Video and Audio Upload"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>A skit is popularly known as a short video about anything, having different video and sound effects.\nIn this post, we will build a basic skit maker in Next.js that allows us to upload a video, add an audio clip, then add basic transformations to the resulting video.<\/p>\n<p>This part of this article covers how to upload audio and video, with the audio playing on the video, while a second article will cover further video transformations.<\/p>\n<h2>Sandbox<\/h2>\n<p>This portion of the project showing media upload was completed in a <a href=\"https:\/\/codesandbox.io\/s\/video-and-audio-upload-with-nextjs-zvuo9?file=\/pages\/index.js\">Codesandbox<\/a>. To get started quickly, fork the <a href=\"https:\/\/codesandbox.io\/s\/video-and-audio-upload-with-nextjs-zvuo9?file=\/pages\/index.js\">Codesandbox<\/a> or run the project.<\/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\/video-and-audio-upload-with-nextjs-zvuo9?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 and Audio Upload with NextJS\"\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>\nGitHub repository: https:\/\/github.com\/Olanetsoft\/video-and-audio-upload-with-nextJS\n\n## Getting Started with Next.js\n\n[Next.js](https:\/\/nextjs.org\/) is an open-source React-based front-end development web framework, that allows  server-side rendering and the generation of static web sites and applications.\n\nTo create a new project, we use the `npx create-next-app` command to scaffold a new project in a directory of our choice.\nOnce the app is created 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 \n\n```bash\n    cd &lt;project name&gt; &amp;&amp; npm start\n<\/code><\/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<p>For both audio and video files, we will use <a href=\"https:\/\/cloudinary.com\/\">C<\/a><a href=\"https:\/\/cloudinary.com\/\">loudinary<\/a> to handle our media upload. Cloudinary is a service that enables us deliver rich media experiences in media upload, storage, optimization, transformation and delivery.\n<a href=\"https:\/\/cloudinary.com\/documentation\/image_video_and_file_upload#upload_options_overview\">Cloudinary<\/a> provides a secure and comprehensive API for uploading media files fast and efficiently from the server-side, the browser, or a mobile application. We can upload media assets using Cloudinary\u2019s REST API or one of its client libraries (SDKs). These SDKs wrap the upload API and make it easier to integrate with websites and mobile apps.<\/p>\n<p>We require  the user interface to manage the upload on the home page. We create do this by updating the pages\/index.js file to a component:<\/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\">    import React, { useState } from \"react\";\n    \n    const App = () =&gt; {\n      const &#91;videoPublicId, setVideoPublicId] = useState(null);\n      const &#91;alt, setAlt] = useState(null);\n      const &#91;audioPublicId, setAudioPublicId] = useState(null);\n    \n      return (\n        <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\">\"left-side\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n                  <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span>\n                  <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"btn widget-btn\"<\/span>\n                &gt;<\/span>\n                  Upload Video\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n                  <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span>\n                  <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"btn widget-btn\"<\/span>\n                &gt;<\/span>\n                  Upload Audio\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/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\">p<\/span>&gt;<\/span>The resulting video with audio will be displayed here<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;&gt;<\/span>\n                  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span>\n                    <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"\"<\/span>\n                    <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{alt}<\/span>\n                    <span class=\"hljs-attr\">controls<\/span>\n                    <span class=\"hljs-attr\">autoPlay<\/span>\n                  &gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">video<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;\/&gt;<\/span>\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>\n      );\n    };\n    \n    export default App;\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>We created component state variables using the <code>useState<\/code> hook for <code>videoPublicId<\/code>, <code>audioPublicId<\/code>. Each being the Cloudinary public ID of the video and audio, initialized with a default value of null.<\/p>\n<p>We also created a state variable for the <code>alt<\/code> accessibility data on media assets and set the initial value to null.<\/p>\n<p>With the state variables we rendered a video element and buttons to handle video and audio upload. The video playback source URL will be determined after the media assets are uploaded.<\/p>\n<p>The current user interface doesn\u2019t look aesthetically pleasing, we\u2019ll add some styling with CSS. We create a <code>css<\/code> folder in the root directory and a style.css file in the folder with the following content in this GitHub Gist.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/Chuloo\/5a1c1cbf83fd827d6fb78308af15e23c\">https:\/\/gist.github.com\/Chuloo\/5a1c1cbf83fd827d6fb78308af15e23c<\/a><\/p>\n<p><a href=\"https:\/\/gist.github.com\/Chuloo\/5a1c1cbf83fd827d6fb78308af15e23c\">https:\/\/gist.github.com\/Chuloo\/5a1c1cbf83fd827d6fb78308af15e23c<\/a><\/p>\n<p>To properly align elements on the screen, we use CSS Flexbox. Our button also has background colors and hover effects.<\/p>\n<p>We also 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.<\/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 now 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_B1FCD2502725CB3D5CEC87B28CE445B6BC2160404292066EB7F16F68C17039B2_1623504696459_Screenshot+2021-06-12+at+14.31.00.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1154\"\/><\/p>\n<h2>Media upload<\/h2>\n<p>Cloudinary\u2019s upload widget lets us upload media assets from multiple sources including Dropbox, Facebook, Instagram, and images taken right from our device camera. We\u2019ll utilize the upload widget in this project.<\/p>\n<blockquote>\n<p><a href=\"https:\/\/cloudinary.com\/users\/register\/free\">Create a free cloudinary account<\/a> to obtain your cloud name and upload_preset.<\/p>\n<\/blockquote>\n<p>Upload presets allow us to centrally define a set of asset upload choices rather than providing them in each upload call. A Cloudinary cloud name is a unique identifier associated with our Cloudinary account.<\/p>\n<p>First, from a content delivery network (CDN) we will include the Cloudinary widget\u2019s JavaScript file in our index.js located in <code>pages\/index.``js<\/code>. We include this file using the <a href=\"https:\/\/www.npmjs.com\/package\/react-helmet\">react-helmet<\/a>\u2019s <code>&lt;Helmet&gt;<\/code> component, which lets us add data to the Head portion of our HTML document in React.<\/p>\n<p>In the project, we install the <a href=\"https:\/\/www.npmjs.com\/package\/react-helmet\">react-helmet<\/a> package using the command below:<\/p>\n<pre class=\"js-syntax-highlighted\"><span><code class=\"hljs shcb-wrap-lines\">    npm i react-helmet\n<\/code><\/span><\/pre>\n<p>Next, in <code>pages\/index.js<\/code> we import Helmet and add the script file.<\/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> 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\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      &#91;...]\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\">\"left-side\"<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">Helmet<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">meta<\/span> <span class=\"hljs-attr\">charSet<\/span>=<span class=\"hljs-string\">\"utf-8\"<\/span> \/&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>\n                  <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">\"https:\/\/widget.Cloudinary.com\/v2.0\/global\/all.js\"<\/span>\n                  <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"text\/javascript\"<\/span>\n                &gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">Helmet<\/span>&gt;<\/span>\n              &#91;...]\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-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>Next, in the App component, we create an instance of the widget in a function that will eventually be called on the click of a button.<\/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\">const<\/span> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n      <span class=\"hljs-comment\">\/\/ state variable declarations go here<\/span>\n      \n      <span class=\"hljs-keyword\">const<\/span> openWidget = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n        <span class=\"hljs-comment\">\/\/ create the widget<\/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-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(); <span class=\"hljs-comment\">\/\/ open up the widget after creation<\/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-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>The widget requires our Cloudinary <code>cloud_name<\/code> and <code>uploadPreset<\/code>. The <code>createWidget()<\/code> function creates a new upload widget and on the successful upload of either a video or audio, we assign the public_id of the asset to the relevant state variable.<\/p>\n<p>To get our <code>cloudname<\/code> and <code>uploadPreset<\/code> we follow the steps below:<\/p>\n<p>The cloud name is obtained from our Cloudinary dashboard as shown below.<\/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_B1FCD2502725CB3D5CEC87B28CE445B6BC2160404292066EB7F16F68C17039B2_1622826668451_Screenshot+2021-06-04+at+18.09.43.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1692\" height=\"540\"\/><\/p>\n<p>An upload preset can be found in the \u201cUpload\u201d tab of our Cloudinary settings page, which we access by clicking on the gear icon in the top right corner of the dashboard page.<\/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_B1FCD2502725CB3D5CEC87B28CE445B6BC2160404292066EB7F16F68C17039B2_1622826303905_Screenshot+2021-06-04+at+18.03.09.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"148\"\/><\/p>\n<p>We then click on the <code>Upload<\/code> tab on the settings page:<\/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_B1FCD2502725CB3D5CEC87B28CE445B6BC2160404292066EB7F16F68C17039B2_1622826506106_Screenshot+2021-06-04+at+18.07.09.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"977\"\/><\/p>\n<p>We scroll down to the bottom of the page to the upload presets section, where we see our upload preset or the option to create one if we don\u2019t have any.<\/p>\n<p>We call the <code>openWidget<\/code> function in the <code>onClick<\/code> handler of our upload buttons using:<\/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> App = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\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\">\"left-side\"<\/span>&gt;<\/span>\n              \/*Helmet goes here*\/\n              <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">form<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n                  <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span>\n                  <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"btn widget-btn\"<\/span>\n                  <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{openWidget}<\/span>\n                &gt;<\/span>\n                  Upload Video\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n                <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span>\n                  <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"button\"<\/span>\n                  <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"btn widget-btn\"<\/span>\n                  <span class=\"hljs-attr\">onClick<\/span>=<span class=\"hljs-string\">{openWidget}<\/span>\n                &gt;<\/span>\n                  Upload Audio\n                <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n              <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">form<\/span>&gt;<\/span>\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-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>When we open our app in the browser and click the \u201cUpload Video\u201d button, we should see something 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_B1FCD2502725CB3D5CEC87B28CE445B6BC2160404292066EB7F16F68C17039B2_1622827721246_Screenshot+2021-06-04+at+18.23.38.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1144\"\/><\/p>\n<p>We can further customize the widget with more information in this <a href=\"https:\/\/cloudinary.com\/documentation\/upload_widget#look_and_feel_customization\">documentation<\/a>.<\/p>\n<p>On asset upload, this is what the response looks like with the <code>public_id<\/code> of the asset uploaded:<\/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_B1FCD2502725CB3D5CEC87B28CE445B6BC2160404292066EB7F16F68C17039B2_1623505758371_Screenshot+2021-06-12+at+14.46.03.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1149\"\/><\/p>\n<p>We successfully uploaded a video file and retrieved the video properties from Cloudinary, we will further upload an audio file and construct the URL that will be added to the <code>src<\/code> attribute of the video element.<\/p>\n<p>Cloudinary provides on-the-fly URL media transformations via URL modifications. For this project, we\u2019ll use the same pattern to transform the video URL to include the audio file as a transformation parameter.\nWe took a standard Cloudinary-uploaded video URL and replaced the public ID portions of the video and audio with those set in the component\u2019s state variable on asset upload.<\/p>\n<p>The resulting URL looks like this with template literals<\/p>\n<pre><code>`https:\/\/res.cloudinary.com\/olanetsoft\/video\/upload\/l_video:${audioPublicId}\/fl_layer_apply\/${videoPublicId}.mp4`\n<\/code><\/pre>\n<p>We update the <code>src<\/code> attribute on the video element with the URL we constructed:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" 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\">p<\/span>&gt;<\/span>The resulting video with audio will be displayed here<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n    \/\/ Update the code below\n      {audioPublicId &amp;&amp; (\n        <span class=\"hljs-tag\">&lt;&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">video<\/span>\n            <span class=\"hljs-attr\">src<\/span>=<span class=\"hljs-string\">{<\/span>`<span class=\"hljs-attr\">https:<\/span>\/\/<span class=\"hljs-attr\">res.cloudinary.com<\/span>\/<span class=\"hljs-attr\">olanetsoft<\/span>\/<span class=\"hljs-attr\">video<\/span>\/<span class=\"hljs-attr\">upload<\/span>\/<span class=\"hljs-attr\">l_video:<\/span>${<span class=\"hljs-attr\">audioPublicId<\/span>}\/<span class=\"hljs-attr\">fl_layer_apply<\/span>\/${<span class=\"hljs-attr\">videoPublicId<\/span>}<span class=\"hljs-attr\">.mp4<\/span>`}\n            <span class=\"hljs-attr\">alt<\/span>=<span class=\"hljs-string\">{alt}<\/span>\n            <span class=\"hljs-attr\">controls<\/span>\n            <span class=\"hljs-attr\">autoPlay<\/span>\n          &gt;<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">video<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/&gt;<\/span>\n      )}\n    \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\">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>The resulting interface should look like this, having the transformed video with audio displayed on the right.<\/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_B1FCD2502725CB3D5CEC87B28CE445B6BC2160404292066EB7F16F68C17039B2_1623507315497_Screenshot+2021-06-12+at+15.14.44.png\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"2000\" height=\"1164\"\/><\/p>\n<h1>Conclusion<\/h1>\n<p>This article explains how to upload audio and video to Cloudinary seamlessly, with the audio serving as background music to the video. In the following tutorial, we\u2019ll learn how to add transformations to the video.<\/p>\n<h1>Resources<\/h1>\n<p>You may find these resources useful.<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/cloudinary.com\/documentation\/image_video_and_file_upload\">Media<\/a> <a href=\"https:\/\/cloudinary.com\/documentation\/image_video_and_file_upload\">upload on Cloudinary<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/www.npmjs.com\/package\/react-helmet\">React-Helmet<\/a>\n<\/li>\n<\/ul>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":28521,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[134,212,371,303],"class_list":["post-28520","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-guest-post","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 and Audio Upload<\/title>\n<meta name=\"description\" content=\"In this tutorial, the first part of a 2-part series, learn how to handle audio and video uploads 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-and-audio-upload\/\" \/>\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 and Audio Upload\" \/>\n<meta property=\"og:description\" content=\"In this tutorial, the first part of a 2-part series, learn how to handle audio and video uploads 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-and-audio-upload\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-08-06T18:55:36+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA\" \/>\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-and-audio-upload\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Video Skit Maker in Next.js &#8211; Video and Audio Upload\",\"datePublished\":\"2021-08-06T18:55:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/\"},\"wordCount\":11,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA\",\"keywords\":[\"Guest Post\",\"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-and-audio-upload\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/\",\"name\":\"Video Skit Maker in Next.js - Video and Audio Upload\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA\",\"datePublished\":\"2021-08-06T18:55:36+00:00\",\"description\":\"In this tutorial, the first part of a 2-part series, learn how to handle audio and video uploads while building a video skit maker.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA\",\"width\":5760,\"height\":3240},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#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 and Audio Upload\"}]},{\"@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 and Audio Upload","description":"In this tutorial, the first part of a 2-part series, learn how to handle audio and video uploads 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-and-audio-upload\/","og_locale":"en_US","og_type":"article","og_title":"Video Skit Maker in Next.js - Video and Audio Upload","og_description":"In this tutorial, the first part of a 2-part series, learn how to handle audio and video uploads while building a video skit maker.","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/","og_site_name":"Cloudinary Blog","article_published_time":"2021-08-06T18:55:36+00:00","twitter_card":"summary_large_image","twitter_image":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/"},"author":{"name":"","@id":""},"headline":"Video Skit Maker in Next.js &#8211; Video and Audio Upload","datePublished":"2021-08-06T18:55:36+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/"},"wordCount":11,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA","keywords":["Guest Post","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-and-audio-upload\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/","name":"Video Skit Maker in Next.js - Video and Audio Upload","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA","datePublished":"2021-08-06T18:55:36+00:00","description":"In this tutorial, the first part of a 2-part series, learn how to handle audio and video uploads while building a video skit maker.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA","width":5760,"height":3240},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/video-skit-maker-in-next-js-video-and-audio-upload\/#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 and Audio Upload"}]},{"@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\/v1681924459\/Web_Assets\/blog\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3\/0b6253a06f6e2ba15602c41b23d97dfc1fa05280-5760x3240-1_28521f16e3.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28520","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=28520"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28520\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/28521"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28520"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28520"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28520"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}