Skip to content

Embedding video playlists

HTML allows us to easily embed video players on web pages, video playlists, however, is outside of the scope of the standard video element. This is regardless of the fact that for media-intensive applications, organizing our videos into playlists is priceless. Let us explore how we can add video playlists on our Nuxt.Js apps.

The final project can be viewed on Codesandbox.

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

Nuxt.Js is a performant Vue.Js framework that boasts of boosting developer experience and productivity. This has led it to be amongst the most widely used Vue.Js frameworks. Today, we will also be using it. To get started ensure you have yarn or npm v5.2+/v6.1+ installed. Open your terminal in your preferred working directory.

yarn create nuxt-app nuxtjs-video-player

npx create-nuxt-app nuxtjs-video-player

npm init nuxt-app nuxtjs-video-player

This will trigger a set of setup questions meant to customize your project. Here are our recommended defaults:

Project name: nuxtjs-video-playlists 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

This will customize the installation for you. Once the setup is complete you may enter the directory and run the project.

cd nuxtjs-video-playlists

yarn dev
# OR
npm run dev
Code language: PHP (php)

You should now be able to view your project on http://localhost:3000.

Before rendering our playlists, we need to first store our videos on Cloudinary. Cloudinary is a media management platform that offers a comprehensive toolset of SDKs, APIs and widgets to ensure you give your app users the best media experience.

To prevent storing the video files in our own app thus increasing hosting requirements as well as video load time, we will host them on Cloudinary. If you do not have an account, feel free to create one here.

Once signed in, proceed to the media library and create a nuxtjs-video-playlist. Within the folder upload the following videos:

The resultant folder should be like this: Video player

Once the videos are uploaded, select them all and tag them as mvp-animals. We’ll use this tag later.

Instead of using the stock HTML5 video element, we are going to be using Cloudinary’s video player.

Installation is simple, we will add the CSS and JS assets to our nuxt.config.js file. The assets will be pulled from unpkg, a fast global content delivery network for npm.

Let’s add the files in the head section.

// nuxt.config.js
export default {
  head: {
      ...
        link: [
            { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
            { rel: 'stylesheet', href: 'https://unpkg.com/cloudinary-video-player@1.5.9/dist/cld-video-player.min.css' }
        ],
        script: [
            { src: 'https://unpkg.com/cloudinary-core@latest/cloudinary-core-shrinkwrap.min.js' },
            { src: 'https://unpkg.com/cloudinary-video-player@1.5.9/dist/cld-video-player.min.js' },
        ],
  },
};
Code language: JavaScript (javascript)

We will also need to reference our Cloudinary account from our codebase. We will do this by configuring the NUXT_ENV_CLOUDINARY_CLOUD_NAME in the .env file. This is the file used to store environmental variables we don’t want to be stored in our codebase for either security or portability reasons. Create the file in the root project folder.

touch .env
Code language: CSS (css)

Then add your cloud name. This can be located on your Cloudinary dashboard.

NUXT_ENV_CLOUDINARY_CLOUD_NAME=<your-cloudinary-cloud-name>
Code language: HTML, XML (xml)

We will create this playlist in a component called FixedSourcePlaylist.vue located in the components folder. We will start by adding a video tag to the template section. For easy reference, let’s allocate the id fixed-source-player to it. To apply the Cloudinary video player styles, we will add the cld-video-player, cld-video-player-skin-dark classes to it. As we want the videos to autoplay and the video controls to appear, we will also add autoplay and controls to the video tag.

<!-- components/FixedSourcePlaylist.vue -->
<template>
    <video
        id="fixed-source-player"
        controls
        autoplay
        class="cld-video-player cld-video-player-skin-dark w-1/2 mx-auto h-96"
    >
    </video>
</template>
Code language: HTML, XML (xml)

Within our script section, we will manually store a list of the videos we want in the playlist. Here we will also initialize the video player as well as the playlist. We specify that the playlist should show the widget vertically, autoadvance, repeat, and show the upcoming video for eight seconds.

// components/FixedSourcePlaylist.vue
<script>
export default {
    data(){
        return {
            cld: null,
            player:null,
            sources:[
                "nuxtjs-video-playlist/production_ID_3987730.mp4",
                "nuxtjs-video-playlist/pexels-zlatin-georgiev-7173031.mp4",
                "nuxtjs-video-playlist/pexels-taryn-elliott-5220279.mp4",
                "nuxtjs-video-playlist/pexels-taryn-elliott-9116112.mp4",
                "nuxtjs-video-playlist/Pexels_Videos_1526909.mp4",
            ]
        }
    },
    mounted(){
        this.cld = cloudinary.Cloudinary.new({ cloud_name: process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME, secure: true});

        this.player = this.cld.videoPlayer(
            "fixed-source-player",
             {
                playlistWidget: {
                    direction:'vertical',
                    total:5
                }
             }
        );

        this.player.playlist(
            this.sources, 
            { autoAdvance: true, repeat: true, presentUpcoming: 8 }
        );
    }
}
</script>
Code language: HTML, XML (xml)

Let us now import this component into our homepage. We should now be able to see the video playing with the widget.

<!-- pages/index.vue -->
<template>
  <div>
    <h1 class="text-center text-2xl leading-8 font-extrabold tracking-tight text-gray-700 m-12 ">
      Fixed source playlist with widget
    </h1>
    
    <fixed-source-playlist class="m-24"/>
  </div>
</template>
Code language: HTML, XML (xml)
// pages/index.vue 
<script>
import FixedSourcePlaylist from '../components/FixedSourcePlaylist.vue'

export default {
  name: 'IndexPage',
  components: { 
    FixedSourcePlaylist, 
  },
}
</script>
Code language: HTML, XML (xml)

Playlist with widget

As opposed to hardcoding or fetching the images from the server, we may also configure the playlist to load from a specific tag. To do so, we initialize the playlist through playlistByTag instead of playlist.

Let us first setup the html on components/TagSpecificPlaylist.vue.

<!-- components/TagSpecificPlaylist.vue -->
<template>
    <video
        id="tag-source-player"
        controls
        autoplay
        class="cld-video-player cld-video-player-skin-dark w-1/2 mx-auto h-96"
    >
    </video>
</template>
Code language: HTML, XML (xml)

Let us now initialize the player, the playlist and specify the tag nvp-animals as the source. All other settings will remain the same.

// components/TagSpecificPlaylist.vue
<script>
export default {
    data(){
        return {
            cld: null,
            player:null,
        }
    },
    mounted(){
        this.cld = cloudinary.Cloudinary.new({ cloud_name: process.env.NUXT_ENV_CLOUDINARY_CLOUD_NAME, secure: true});

        this.player = this.cld.videoPlayer("tag-source-player");

        this.player.playlistByTag(
            "nvp-animals", 
            { autoAdvance: true, repeat: true, presentUpcoming: 8 }
        );
    }
}
</script>
Code language: HTML, XML (xml)

Let us now import this component on our homepage as well.

<!-- pages/index.vue -->
<template>
  <div>
    <h1 class="text-center text-2xl leading-8 font-extrabold tracking-tight text-gray-700 m-12 ">
      Fixed source playlist with widget
    </h1>
    
    <fixed-source-playlist class="m-24"/>
    
    <h1 class="text-center text-2xl leading-8 font-extrabold tracking-tight text-gray-700 m-12 ">
      Tag specific playlist without widget
    </h1>

    <tag-specific-playlist class="m-24"/>
  </div>
</template>
Code language: HTML, XML (xml)
// pages/index.vue
<script>
import FixedSourcePlaylist from '../components/FixedSourcePlaylist.vue'
import TagSpecificPlaylist from '../components/TagSpecificPlaylist.vue'

export default {
  name: 'IndexPage',
  components: { 
    FixedSourcePlaylist, 
    TagSpecificPlaylist
  },
}
</script>
Code language: HTML, XML (xml)

We should now be able to view the difference between both playlists.

Both playlists

To view additional configurations possible, feel free to go through the Cloudinary Video Player API reference.

Back to top

Featured Post