Video thumbnail with preview on hover in Nuxtjs

Demola Malomo

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

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 <div
6 class
7 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'
19
20 export default {
21 name: 'IndexPage',
22 data() {
23 return {
24 cld: null,
25 player: null,
26 videoList,
27 }
28 },
29
30 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 },
43
44 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 the player variable, create a Cloudinary instance, loop through the list of videos to initialize the video player and assign a source to the video using the publicId. We also leverage Cloudinary’s support for AI-Based transformation to apply the preview transformation effect with a duration of 5 seconds.
  • Create an onHoverEnter and onHoverLeave 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:

Demola Malomo

Software Engineer & Technical Writer

Demola is a software developer, technical writer, and product designer. He has a passion for designing and building scalable applications.