Skip to content

RESOURCES / BLOG

Audio track Changer with Nuxt.js

As media content consumption increases, the needs and wants of the consumers increase as well. This is not due to entitlement but rather the diverse nature of our society. Multiple languages being used across multiple countries creates a need for us to be able to have dynamic audio tracks for our video content. In this article, we review how we can easily be able to do this in a programmatic way without additional production input.

The final project can be viewed on Codesandbox.

You can find the full source code on my Github repository.

To be able to follow through with this tutorial, basic knowledge of HTML, CSS, and JavaScript is required. Knowledge of VueJs is recommended but is not required.

For this project, we will be using a VueJs framework known as NuxtJs. It is an open-source framework intended to make web development simple and powerful.

In order to create a NuxtJs project, npx is required. It is shipped by default since npm 5.2.0 or npm v6.1 or yarn.

Open the terminal in your preferred working directory and run the following command:


yarn create nuxt-app nuxtjs-audio-track-change

# OR

npx create-nuxt-app nuxtjs-audio-track-change

# OR

npm init nuxt-app nuxtjs-audio-track-change

Code language: PHP (php)

Running the above command will result in an interactive series of questions. Here are the questions and our recommended defaults:

Project name: nuxtjs-audio-track-change

Programming language: JavaScript

Package manager: Yarn

UI framework: Tailwind CSS

Nuxt.js modules: N/A

Linting tools: N/A

Testing frameworks: None

Rendering mode: Universal (SSR / SSG)

Deployment target: Server (Node.js hosting)

Development tools: N/A

What is your Github username? <your-github-username>

Version control system: Git

Once setup is complete, you may enter the project and run it:


cd nuxtjs-audio-track-change

  

yarn dev

#OR

npm run dev

Code language: CSS (css)

[@nuxt/cloudinary] is the recommended Cloudinary integration for Nuxt.Js. Cloudinary is a media management platform that allows us to make the most out of our media content. You may create an account on the SignUp page here.

To install the Cloudinary plugin, run the following command in the project folder:


yarn add @nuxtjs/cloudinary

# OR

npm install @nuxtjs/cloudinary

Code language: CSS (css)

Once installation is complete, add @nuxtjs/cloudinary as a module in the modules section of the nuxt.config.js file:


// nuxt.config.js

export  default  {

...

modules: [

'@nuxtjs/cloudinary'

]

...

}

Code language: JavaScript (javascript)

We will also add a cloudinary configuration section to our nuxt.config.js file.


// nuxt.config.js

export  default  {

...

cloudinary: {

cloudName:  process.env.NUXT_CLOUDINARY_CLOUD_NAME,

useComponent:  true

}

}

Code language: JavaScript (javascript)

As visible in the code above, we refer to a NUXT_CLOUDINARY_CLOUD_NAME variable in our process environment. This is called an environmental variable. These are variables that are configured and managed on the project’s hosting environment. They can also be used for configuration details as well as sensitive credentials.

To configure our environmental variables, we will create a .env file at the root of our project.


touch .env

Code language: CSS (css)

We are going to add our environmental variable to the .env file:


<!-- .env -->

NUXT_CLOUDINARY_CLOUD_NAME=<your-cloudinary-cloud-name>

Code language: HTML, XML (xml)

To get your Cloudinary cloud name, proceed to the Console page. You will see it under Account Details.

Upload presets are a pre-configured set of options that will be applied to our uploads. It is a requirement to have an upload preset configured for client-side unsecured uploads. To create an upload preset proceed to add upload preset page. We recommend using the following settings.

Name: default-preset

Mode: unsigned

Unique filename: true

Delivery type: upload

Access mode: public

To upload video files to Cloudinary, we will first create an HTML form.


<!-- pages/index.vue -->

<template>

...

<form @submit.prevent="handleVideoUpload">

<input

type="file"

name="file"

@change="handleVideo"

accept="video/*"

required

class="block mx-auto"

/>

<button

type="submit"

:disabled="uploadingVideo"

>

Upload Video

</button>

<div v-if="uploadingVideo">Uploading video...</div>

</form>

...

</template>

Code language: HTML, XML (xml)

When a user selects a video, the handleVideo method will be triggered. On form submission, the handleVideoUpload method will be triggered as well. The Uploading video... text will be toggled depending on the value of the uploadingVideo variable. The same variable we use to disable the button to prevent double submissions.

Let’s review the structure of the JavaScript logic:


// pages/index.vue

<script>

export default {

data()  {

return {

...

uploadVideo: null,

uploadingVideo:  false,

video:  null,

...

};

},

methods: {

...

handleVideo(e)  {

this.uploadVideo  =  e.target.files[0];

},

async  handleVideoUpload(e)  {

this.uploadingVideo  =  true;

  

const fileData  =  await  this.readData(this.uploadVideo);

  

this.video  =  await  this.$cloudinary.upload(fileData,  {

upload_preset:  "default-preset",

folder:  "nuxtjs-audio-track-change",

});

  

this.uploadingVideo  =  false;

},

async  readData(f)  {

return new Promise((resolve)  =>  {

const  reader  =  new  FileReader();

reader.onloadend  =  ()  =>  resolve(reader.result);

reader.readAsDataURL(f);

});

},

...

},

};

</script>

Code language: HTML, XML (xml)

The handleVideo method sets the selected upload file into the uploadVideo variable. The handleVideoUpload method reads the file, uploads it to Cloudinary, stores the Cloudinary instance, and updates the uploadingVideo variable.

We use the same logic when uploading the audio files. The only difference is that instead of updating the Cloudinary instance into a video object variable, we add the Cloudinary instance into a JavaScript array as shown below:


// pages/index.js

  

<script>

export default {

data()  {

return {

...

uploadAudio: null,

uploadingAudio:  false,

audios:  [],

...

};

},

methods: {

...

handleAudio(e)  {

this.uploadAudio  =  e.target.files[0];

},

async  handleAudioUpload(e)  {

this.uploadingAudio  =  true;

  

const fileData  =  await  this.readData(this.uploadAudio);

  

const audio  =  await  this.$cloudinary.upload(fileData,  {

upload_preset:  "default-preset",

folder:  "nuxtjs-audio-track-change",

});

  

this.audios.push(audio);

  

this.uploadingAudio  =  false;

},

async  readData(f)  {

return new Promise((resolve)  =>  {

const  reader  =  new  FileReader();

reader.onloadend  =  ()  =>  resolve(reader.result);

reader.readAsDataURL(f);

});

},

...

},

};

</script>

Code language: HTML, XML (xml)

To change the audio tracks, we loop through the audio array rendering the video using the cld-video cloudinary component. We then apply an overlay transformation using the cld-transformation cloudinary component.


<!-- pages/index.vue -->

<template>

<div

v-for="(track, index) in audios"

:key="index"

>

<cld-video

:publicId="video.public_id"

height="250"

width="500"

crop="fill"

quality="auto"

controls="true"

>

<cld-transformation

:overlay="`video:${track.public_id.replace('/', ':')}`"

/>

<cld-transformation flags="layer_apply"  />

</cld-video>

<p>

Video: {{ video.public_id }}

</p>

<p>

Audio: {{ track.public_id }}

</p>

</div>

</template>

Code language: HTML, XML (xml)

When using the overlay transformation, we cannot pass a public_id with a (forward) slash E.g. nuxtjs-audio-track-change/boom-boom-audio. We need to replace the slashes with full colons to result in the following: nuxtjs-audio-track-change:boom-boom-audio. This is why we have the replace code snipped in the transformation above.

With the above-detailed tutorial, we can now change the audio track of any video dynamically. Cloudinary allows us to even add more advanced configurations such as the Audio codec, volume level as well as additional configurations. Feel free to review the documentation to learn more about what is possible. Together let’s make our video content as accessible as possible.

Start Using Cloudinary

Sign up for our free plan and start creating stunning visual experiences in minutes.

Sign Up for Free