The representation of content in video format has grown substantially. It's arguably the primary means of sharing moments with the rest of the world.
YouTube is one of the many platforms online that accepts the streaming and upload of videos, making it easy to watch on any device.
This article highlights how to build a YouTube-like application using Cloudinary in Nuxt.js. A video plays muted on mobile and allows the user to listen to the audio by clicking the unmute button.
Sandbox
The working demo is in a CodeSandbox. Fork and run it to quickly get started.
1<CodeSandbox title="YouTube unmute sound" id="youtube-unmute-sound-c8bpdn" />
Check out the complete source code for reference.
Prerequisites
We need to have the following for this post:
- A Cloudinary account — sign up here for free!
- Familiarity with Vue.
- Basic knowledge of JavaScript.
Getting started
To begin, run the following command to create a new Nuxt.js app.
1npx create-nuxt-app unmute-feature
The process above presents a series of prompts that should look like this:
1create-nuxt-app v4.0.02 ✨ Generating Nuxt.js project in unmute-feature3 Project name: accept the default, press Enter4 Programming language: JAVASCRIPT5 Package manager: Npm6 UI framework: Tailwind CSS7 Nuxt.js modules: N/A8 Linting tools: N/A9 Testing framework: None10 Rendering mode: Universal (SSR / SSG)11 Deployment target: Static (Static/Jamstack hosting)12 Development tools: jsconfig.json13 What is your GitHub username? <your-github-username>14 Version control system: GIT
With the boilerplate files and folders in place, run the command to start the development environment accessible on http://localhost:3000
.
1# change directory to project folder2 cd unmute-feature34 # start the development environment5 npm run dev
Creating the YouTube-like video
Before building the YouTube unmute video feature, we'll use the Cloudinary Video Player, a JavaScript-based HTML5 video player. Navigate to the nuxt.config.js
file and include the video player package files from the Unpkg CDN in the head object section.
1export default {2 ...3 head: {4 link: [5 {6 href:"https://unpkg.com/cloudinary-video-player@1.9.0/dist/cld-video-player.min.css", rel:"stylesheet"7 }8 ],9 script: [10 {11 src:"https://unpkg.com/cloudinary-video-player@1.9.0/dist/cld-video-player.min.js",12 type:"text/javascript"13 }14 ]15 }
Next, in the pages/index.vue
file, remove the component <Tutorial />
and add the following code.
1<template>2 <div>3 <div class="relative">4 <video id="doc-player" muted class="cld-video-player cld-fluid"></video>5 <button class="absolute bg-blue-700 text-white top-0 left-0 px-3 py-2">Unmute</button>6 </div>7 </div>8 </template>91011 <script>12 export default {13 name: 'IndexPage',14 data() {15 return {16 player: null,17 videoId: 'video-player/early_morning'18 }19 },20 mounted() {21 this.player = cloudinary.videoPlayer('doc-player', {22 cloud_name: 'terieyenike',23 autoplay: true,24 controls: true25 })26 this.player.source(this.videoId)27 }28 }29 </script>
In the code block above, we rendered the Cloudinary Video Player with the video
tag and a button
that allows for the unmute/mute click event. The muted attribute on the video tag mutes the video.
For the data
object property, we pass a set of reactive data such as the player
variable set to null and the videoId
set to the uploaded video asset with a public ID, early_morning
, placed in a folder called video-player
.
Finally, we call the lifecycle hook mounted
function after the app is mounted on the document object model (DOM). Also included within the mounted
function is our Cloudinary cloud name and the video features such as autoplay and the player controls set to true.
Our app should look like the image below.
Adding Button to Listen to Audio
Now that we have successfully set up the video on our browser, we need to create a function that conditionally changes the text from unmute to mute on the button
tag based on the user interaction. Doing this will allow us to hear the video.
Let's update our code and include the ref
parameter to the video
and button
tags, which will allow us to reference the HTML element attributes.
1<template>2 <div>3 <div class="relative">4 <video @click.prevent="unmuteVideo" id="doc-player" ref="video" muted class="cld-video-player cld-fluid"></video>5 <button @click.prevent="unmuteVideo" ref="text" class="absolute bg-blue-700 text-white top-0 left-0 px-3 py-2">Unmute</button>67 </div>8 </div>9 </template>1011 <script>12 export default {13 name: 'IndexPage',14 ...15 methods: {16 unmuteVideo() {17 const vid = this.$refs.video18 if (!vid.muted) {19 this.$refs.text.textContent = "Unmute"20 } else {21 this.$refs.text.textContent = "Mute"22 }23 vid.muted = !vid.muted24 }25 },26 }27 </script>
From the code above, we have:
@click.prevent
: av-on
that listens to DOM events and prevents the reloading of the page- The
unmuteVideo
function defined on the Vue instance triggers themuted
attribute on the video tag, enabling us to toggle between listening to the audio or not using the refs and changing the button text on each click refs
: an object that contains a property for each element pointed by theref
attribute defined in thetemplate
With the YouTube-like video app completed, here's how it should look:
Conclusion
This post showed us the implementation of a YouTube-like app with the "click to unmute" feature on videos, giving users control over whether to listen to the audio.