Read more about VideoJS components
<!-- We used FontAwesome for the 'Previous' and 'Next' controlBar buttons --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <!-- Add required CSS for displaying the fonts --> <style type="text/css"> .vjs-control.vjs-playlist-control:before { font-family: FontAwesome; font-size: 1.5em; line-height: 2.0; } .vjs-playlist-control.vjs-playlist-next-control:before { content: "\f050"; } .vjs-playlist-control.vjs-playlist-previous-control:before { content: "\f049"; } </style><video id="player" controls muted autoplay class="cld-video-player" width="500" ></video> <div id="source-data"> <span id="public-id-placeholder"></span><br> <span id="source-url-placeholder"></span> </div>// Code for creating the VideoJS components // =============================================== // Get the ClickableComponent base class from Video.js var ClickableComponent = videojs.default.getComponent('ClickableComponent'); // Create a common class for playlist buttons var PlaylistButton = videojs.default.extend(ClickableComponent, { constructor: function(player, options) { var type = options.type; if (!type && type != 'previous' && type != 'next') { throw new Error("Playlist must be either 'previous' or 'next'"); } this.type = type; // It is important to invoke the superclass before anything else, // to get all the features of components out of the box! ClickableComponent.apply(this, arguments); }, // The `createEl` function of a component creates its DOM element. createEl: function() { var typeCssClass = 'vjs-playlist-' + this.type + '-control'; return videojs.default.createEl('button', { // Prefixing classes of elements within a player with "vjs-" // is a convention used in Video.js. className: 'vjs-control vjs-playlist-control vjs-button ' + typeCssClass }); }, }); // Create the NextButton component var NextButton = videojs.default.extend(PlaylistButton, { constructor: function(player, options) { PlaylistButton.apply(this, [player, { type: 'next' }]); }, handleClick: function() { PlaylistButton.prototype.handleClick.call(this); // Since the component has a VideoJS Player object, we use the internal // Cloudinary plugin to reach to the playlist object. this.player().cloudinary.playlist().playNext(); } }); // Create the PreviousButton component var PreviousButton = videojs.default.extend(PlaylistButton, { constructor: function(player, options) { PlaylistButton.apply(this, [player, { type: 'previous' }]); }, handleClick: function() { PlaylistButton.prototype.handleClick.call(this); this.player().cloudinary.playlist().playPrevious(); } }); // Register the component with Video.js, so it can be used in players. videojs.default.registerComponent('NextButton', NextButton); videojs.default.registerComponent('PreviousButton', PreviousButton); // Cloudinary Video Player related code // ==================================== var cld = cloudinary.Cloudinary.new({ cloud_name: 'demo' }); // Initialize player with only the controlBar's 'playToggle' and our // custom components set. var player = cld.videoPlayer('player', { videojs: { controlBar: { children: ['PreviousButton', 'playToggle', 'NextButton'] } } }); player.playlist([ { publicId: 'elephants' }, 'sea_turtle'], { autoAdvance: 0, repeat: true }); function updateSource() { var divElem = document.querySelector("div#source-data"); publicIdElem = divElem.querySelector("#public-id-placeholder"); sourceUrlElem = divElem.querySelector("#source-url-placeholder"); publicIdElem.innerText = "Public Id: " + player.currentPublicId(); sourceUrlElem.innerText = "Source URL: " + player.currentSourceUrl(); divElem.style.display = 'block'; } player.on('sourcechanged', updateSource);