Popular video streaming platforms like Netflix, Hulu, Youtube, e.t.c; give users an option to watch previews of listed videos while hovering. This feature helps users save time by watching preliminaries and quickly determining if it is relevant to them before watching it.
This post will discuss creating video thumbnail previews on hover using Cloudinary and Nuxt.js. At the end of this tutorial, we will learn how to use Cloudinary’s AI-Based video preview feature to generate video previews that improve users’ experience while browsing through videos.
Sandbox
We completed this project in a CodeSandbox, and you can fork it to run the code.
Github link here.
Prerequisites
The following steps in this post require JavaScript and Vue.js experience. Experience with Nuxt.js isn’t a requirement, but it’s nice to have.
We also need a Cloudinary account to store and transform media assets. Signup is completely free.
Getting Started
We need to create a Nuxt.js starter project by navigating to the desired directory and running the command below in our terminal.
1npx create-nuxt-app video_thumbnail && cd video_thumbnail
This command will ask us some questions on how to configure our application. We can answer the questions as shown below:
1Ok to proceed? (y) < PRESS "y" and hit ENTER>2 project name: <PRESS ENTER>3 programming langauge: <JAVASCRIPT>4 package manager: <NPM>5 UI framework: <TAILWIND CSS>6 Nuxt.js modules: <AXIOS - PROMISE BASED HTTP CLIENT>7 Linting tools: <ESLINT, PRETTIER>8 Testing framework: <NONE>9 Rendering mode: <UNIVERSAL (SSR/STATIC)10 Deployment target: <STATIC/JAMSTACK HOSTING>11 Deployment tools: <JSCONFIG.JSON>12 Continous integration: <NONE>13 Version control system: <GIT>
The command creates a Nuxt.js project with TailwindCSS called video_thumbnail
, and navigates into the project directory.
TailwindCSS is a utility-first CSS framework packed with classes to help us style our web page.
Configuring Cloudinary in Nuxt.js
First, we need to modify the nuxt.config.js
file by adding Cloudinary CDNs to the link
and script
section as shown below:
1head: {2 ...3 htmlAttrs: {4 ...5 },6 meta: [7 ...8 ],9 link: [10 { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },11 {12 rel: 'stylesheet',13 href: 'https://unpkg.com/cloudinary-video-player@1.5.9/dist/cld-video-player.min.css',14 },15 ],16 script: [17 {18 src: 'https://unpkg.com/cloudinary-core@latest/cloudinary-core-shrinkwrap.min.js',19 },20 {21 src: 'https://unpkg.com/cloudinary-video-player@1.5.9/dist/cld-video-player.min.js',22 },23 ],24 },
Next, we need to include our Cloudinary’s cloud name as an environment variable. To do this, first, we need to create a .env
file in the root directory, and in this file, add the snippet below:
1NUXT_ENV_CLOUDINARY_CLOUD_NAME=<YOUR CLOUD NAME HERE>
PS: We can get Cloudinary’s cloud name by logging into the Cloudinary console.
Video sourcing and upload to Cloudinary
Next, we need to upload sample videos to generate thumbnails and previews. Video URLs
- https://res.cloudinary.com/dtgbzmpca/video/upload/v1635669808/jkffravgmvsumnnv8qs0.mp4
- https://res.cloudinary.com/dtgbzmpca/video/upload/v1635528649/h77edtixvdz0ddkvspsy.mp4
- https://res.cloudinary.com/dtgbzmpca/video/upload/v1645539487/dancing-catvideo.webm
- https://res.cloudinary.com/dtgbzmpca/video/upload/v1621302254/ouszrok1zgkeuqqsuzit.mkv
In our Cloudinary dashboard, we uploaded the videos by clicking on the Media Library tab, clicking on Upload, selecting Web Address option, input the url, and clicking on the Arrow Button to upload.
After uploading all the videos, we will see them displayed on the console with their publicId
. The IDs will come in handy when creating video thumbnails and previews.
Setup collection for our videos
Next, we need to create a utils
folder in the project root directory. In this folder, we create a videoList.json
file to save data about the uploaded videos.
Here is the JSON data for the file.
1[2 {3 "id": 1,4 "publicId": "<REPLACE THIS WITH YOUR IMAGE PUBLICID>"5 },6 {7 "id": 2,8 "publicId": "<REPLACE THIS WITH YOUR IMAGE PUBLICID>"9 },10 {11 "id": 3,12 "publicId": "<REPLACE THIS WITH YOUR IMAGE PUBLICID>"13 },14 {15 "id": 4,16 "publicId": "<REPLACE THIS WITH YOUR IMAGE PUBLICID>"17 }18]
Creating the Video Previews
Next, we modify the index.vue
file in the pages
folder to the following:
1<template>2 <div class="flex flex-col items-center p-8">3 <h1 class="text-xl font-medium text-blue-900 mb-8">Cloudinary Video Preview</h1>4 <div class="grid grid-cols-1 lg:grid-cols-3 gap-3">5 <div6 class7 v-for="(video, i) in videoList"8 :key="i"9 @mouseenter="onHoverEnter(i)"10 @mouseleave="onHoverLeave(i)"11 >12 <video class="w-96 h-96" :id="`video-player${video.id}`" muted controls></video>13 </div>14 </div>15 </div>16 </template>17 <script>18 import videoList from '@/utils/videoList.json'1920 export default {21 name: 'IndexPage',22 data() {23 return {24 cld: null,25 player: null,26 videoList,27 }28 },2930 mounted() {31 this.player = this.videoList;32 this.cld = cloudinary.Cloudinary.new({33 cloud_name: process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME,34 secure: true,35 })36 this.videoList.forEach((video, i) => {37 this.player[i] = this.cld.videoPlayer(`video-player${video.id}`, {38 transformation: { effect: "preview:duration_5" }39 })40 this.player[i].source(`${video.publicId}.jpg`)41 });42 },4344 methods: {45 onHoverEnter(id) {46 this.player[id].source(this.videoList[id].publicId)47 this.player[id].play()48 },49 onHoverLeave(id) {50 this.player[id].source(this.videoList[id].publicId)51 this.player[id].stop()52 },53 },54 }55 </script>
The snippet above does the following:
- Import the video collection.
- Create
data
properties to manage imported video collection, Cloudinary instance, and video element. - Use the
mounted
lifecycle method to assign the list of imported videos to theplayer
variable, create a Cloudinary instance, loop through the list of videos to initialize the video player and assign a source to the video using thepublicId
. We also leverage Cloudinary’s support for AI-Based transformation to apply thepreview
transformation effect with a duration of 5 seconds. - Create an
onHoverEnter
andonHoverLeave
method to assign, play and stop a video while hovering. - Markup while hovering to show the list of videos with corresponding functions to play and pause a video.
With that done, we can start a development server using the command below:
1npm run dev
Conclusion
This post discussed creating a video thumbnail with a preview on hover using Cloudinary and Nuxt.js.
These resources might be helpful: