Introduction
In an increasingly video-dependent world, the need for ensuring video format compatibility is increasing. In this video, we explore how we can programmatically change the video format.
Codesandbox
The final project can be viewed on Codesandbox.
You can find the full source code on my Github repository.
Prerequisites
To follow along in this tutorial. Basic knowledge on HTML, JavaScript, and CSS is required. VueJs knowledge will be helpful but it is not a hard requirement.
Setup
Nuxt.Js project
We are going to use the create-nuxt-app utility. To use it, make sure you have installed yarn, npx (included by default with npm v5.2+), or npm (v6.1+).
Open the terminal in your working directory of choice and run the following command:
1yarn create nuxt-app nuxtjs-video-format-converter
The above command will result in a series of setup questions. Here are our recommended defaults:
Project name: nuxtjs-video-format-converter
Programming language: JavaScript
Package manager: Yarn
UI framework: Tailwind CSS
Nuxt.js modules: N/A
Linting tools: N/A
Testing framework: None
Rendering mode: Universal (SSR / SSG)
Deployment target: Server (Node.js hosting)
Development tools: N/A
What is your Github username? Eugene Musebe
Version control system: Git
You may now enter the project and run it:
1cd nuxtjs-video-format-converter23yarn dev
@nuxtjs/cloudinary
Cloudinary is a media management platform geared at allowing developers to unleash their full potential. We are going to set up the recommended @nuxtjs/cloudinary plugin.
Run the following command in the project folder:
1yarn add @nuxtjs/cloudinary2# OR3npm install @nuxtjs/cloudinary
Add @nuxtjs/cloudinary
as a module in the modules
section in the nuxt.config.js
file:
1// nuxt.config.js2export default {3 ...4 modules: [5 '@nuxtjs/cloudinary'6 ]7 ...8}
To configure our Cloudinary instance, add a cloudinary
section in the nuxt.config.js
file:
1// nuxt.config.js2export default {3 cloudinary: {4 cloudName: process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME,5 secure: true,6 useComponent: true7 }8}
The above piece of code refers to our environmental variables. These are values that are set in the code's environment as they are dependent on the environment in which the code is deployed. They can also be used to store sensitive values. Let's create our .env
file:
1touch .env
After creation, we can now set our environmental variable:
1NUXT_ENV_CLOUDINARY_CLOUD_NAME=secret-cloud-name
Uploading video
In order to convert the video, we are first going to upload it to Cloudinary. This is because the video format conversion is all done on Cloudinary's platform.
Let us create the HTML form that will be used for file selection. As visible below, we ensure that only videos are uploaded.
1<!-- pages/index.vue -->2<form @submit.prevent="submit">3 ...4 <input type="file" name="video" id="video" accept="video/*" v-on:change="handleFile" required />5 ...6 <div>7 <p v-if="uploading">Uploading...</p>8 <div v-else>9 <button type="reset">Reset</button>10 <button type="submit">Save</button>11 </div>12 </div>13 ...14</form>
Once the video has been selected, we trigger the handleFile
method. In this method, we are going to store the selected file in our state.
1// pages/index.vue2export default{3 data(){4 return {5 uploadVideo: null,6 cloudinaryVideo: null,7 uploading: false8 }9 },10 methods: {11 async handleFile(e){12 this.uploadVideo = e.target.files[0];13 },14 async readData(f) {15 return new Promise((resolve) => {16 const reader = new FileReader();17 reader.onloadend = () => resolve(reader.result);18 reader.readAsDataURL(f);19 });20 },21 async submit() {22 this.uploading = true;23 const videoData = await this.readData(this.uploadVideo);24 this.cloudinaryVideo = await this.$cloudinary.upload(videoData, {25 upload_preset: "default-preset",26 folder: "nuxtjs-video-format-converter",27 });28 this.uploading = false;29 ...30 },31 }32}
Once the form is submitted, we prevent submission and send then handle the event ourselves. We use the readData
method to create a FileReader instance and get the file data. We then send this data to Cloudinary for storage. We specify the folder to be used for storage as well as an upload preset. This is a set of configurations to be followed when processing the file upload.
To create an upload preset, open the Add Upload Preset page. We are then going to use the following settings:
Name: default-preset
Mode: unsigned
Unique filename: true
Delivery type: upload
Access mode: public
Once the upload is complete, we store the video in the `Cloudinary video local state variable.
Converting video formats
Since we are using Cloudinary to convert video formats, we first need to understand which video output formats are supported. We can easily understand this by checking the Supported video formats section in the documentation. We are now going to add the video formats to the form above so that our users can select the format they want to download their video in.
1<!-- pages/index.vue -->2<select3 id="format"4 name="format"5 v-model="format"6 required7>8 <option9 v-for="format in formats"10 :key="format.value"11 :value="format.value"12 >13 {{ format.text }}14 </option>15</select>
The formats
variable in the state is an array of all the supported output formats:
1// pages/index.vue2export default {3 data(){4 return {5 ...6 format: null,7 convertedUrl: null,8 formats: [9 { text: "FLV (Flash Video)", value: "flv" },10 { text: "HLS adaptive streaming", value: "m3u8" },11 { text: "MPEG-2 Transport Stream (ts)", value: "ts" },12 { text: "MPEG-2 Transport Stream (m2ts)", value: "m2ts" },13 { text: "MPEG-2 Transport Stream (mts)", value: "mts" },14 { text: "MOV", value: "mov" },15 { text: "MKV (Matroska Multimedia Container)", value: "mkv" },16 { text: "MP4", value: "mp4" },17 { text: "MPEG-DASH adaptive streaming ", value: "mpd" },18 { text: "OGV (Ogg Video)", value: "ogv" },19 { text: "WebM", value: "webm" },20 ],21 ...22 };23 }24 ...25}
Once the user selects their format of choice, we generate the converted URL once the upload is complete:
1// pages/index.vue2export default {3 ...4 methods:{5 ...6 async submit(){7 ...8 this.uploading = false;9 this.convertedUrl = this.$cloudinary.video.url(10 this.cloudinaryVideo.public_id,11 { format: this.format }12 );13 }14 }15}
We will use the cld-video
component to display the convered video as well as use the convertedUrl
to enable video download:
1<!-- pages/index.vue -->2<div v-if="convertedUrl">3 <h1>Video convertion complete</h1>4 <p>5 Here is a preview of your converted video. Use the button below to6 download7 </p>8 <cld-video9 controls="true"10 :public-id="cloudinaryVideo.public_id"11 :format="format"12 >13 </cld-video>14 <a15 target="_blank"16 :href="convertedUrl"17 >18 Download19 </a>20 </div>
Conclusion
In the above tutorial, we learn how to convert video formats programmatically. This information is very useful for optimizing our video content when building intensive applications. Feel free to review the entire video transformation documentation to learn what else is possible.