Demo THEOplayer
Playlist and Caching
This page demonstrates how you can create a playlist and use the Cache API.
We have two objectives in this demo:
- Create a playlist.
- Preload (cache) upcoming content.
The playlist is created through a combination of HTML, CSS, JavaScript and the THEOplayer API. The following events from the API are used:
- ended: thrown when the current stream ends.
- playing: thrown when the playback of media starts.
The preloading mechanism is built with the Caching API and the Player API:
- timeupdate: thrown periodically when currentTime changes. We use this event to compute how much of the current video has already been played. If this exceeds 75%, we cache the upcoming playlist item.
- CachingTask: a CachingTask can be started to preload content.
The result:
The HTML code:
<div class="container playlist">
<div class="video-js vjs-fluid theoplayer theoplayer-skin theo-seekbar-above-controls"><!--42--></div>
<div class="theoplayer-playlist-holder">
<div class="theoplayer-playlist-menu"> </div>
<div class="theoplayer-playlist-button-holder"><span class="fa fa-step-backward" onclick="goPrevious()"> </span> <span class="fa fa-step-forward" onclick="goNext()"> </span></div>
</div>
</div>
The JavaScript code:
// information on setting up THEOplayer and the player object can be found at https://docs.portal.theoplayer.com/docs/docs/getting-started/web/web
var element = document.querySelector('.theoplayer');
var player = new THEOplayer.Player(element, {
fluid: true,
libraryLocation: 'https://cdn.theoplayer.com/dash/theoplayer/'
});
player.autoplay = true;
// configure video playlist items
var playlist = [
{
source : {
sources: {
src : 'https://cdn.theoplayer.com/video/big_buck_bunny/big_buck_bunny_metadata.m3u8'
}
},
title: 'Big Buck Bunny',
description: 'Big Buck Bunny',
poster: 'https://cdn.theoplayer.com/video/big_buck_bunny/poster.jpg'
},
{
source : {
sources: {
src : 'https://cdn.theoplayer.com/video/star_wars_episode_vii-the_force_awakens_official_comic-con_2015_reel_(2015)/index.m3u8'
}
},
title: 'Star Wars Reel',
description: 'Star Wars Reel',
poster: 'https://cdn.theoplayer.com/video/star_wars_episode_vii-the_force_awakens_official_comic-con_2015_reel_(2015)/poster.jpg'
},
{
source : {
sources: {
src : 'https://cdn.theoplayer.com/video/tears_of_steel/index.m3u8'
}
},
title: 'Tears of Steel',
description: 'Tears of Steel',
poster: 'https://cdn.theoplayer.com/video/tears_of_steel/poster.jpg'
}
];
// create playlist UI
var listElement = document.createElement('ul');
var li;
for (i = 0; i < playlist.length; i++) {
li = createPlaylistElement(i);
listElement.appendChild(li);
}
var playlistMenu = document.querySelector('.theoplayer-playlist-menu');
playlistMenu.innerHTML = "";
playlistMenu.appendChild(listElement);
function createPlaylistElement(trackNumber) {
var track = playlist[trackNumber];
var trackLiElement = document.createElement('li');
var trackNumberElement = document.createElement('span');
trackNumberElement.className = 'number';
trackNumberElement.innerText = trackNumber + 1;
trackLiElement.appendChild(trackNumberElement);
var trackThumbnail = document.createElement('span');
trackThumbnail.className = 'thumbnail';
var trackThumbnailImage = document.createElement('img');
trackThumbnailImage.setAttribute('src', track.poster);
trackThumbnail.appendChild(trackThumbnailImage);
trackLiElement.appendChild(trackThumbnail);
var trackTitleElement = document.createElement('span');
trackTitleElement.className = 'title';
trackTitleElement.innerText = track.title;
trackLiElement.appendChild(trackTitleElement);
trackLiElement.onclick = function () {
player.source = track.source;
active = trackNumber;
};
trackLiElement.setAttribute('id', 'theoplayer-playlist-menu-' + trackNumber);
return trackLiElement;
}
// set initial item of the playlist
player.source = playlist[0].source;
var active = 0; // Which track from the playlist is now playing
player.addEventListener('ended', onEnded);
player.addEventListener('playing',changeActiveTrack);
// continue with the next item of the playlist when the current video has ended
function onEnded () {
goNext();
}
// update selected item in the playlist
function changeActiveTrack () {
var activeElement = document.querySelector('.active');
if (activeElement) {
activeElement.classList.remove('active');
}
document.querySelector('#theoplayer-playlist-menu-' + active).className = 'active';
}
// go to the previous item in the playlist
function goPrevious () {
if (active > 0) {
active -= 1;
player.source = playlist[active].source;
}
}
// go to the next item in the playlist
function goNext () {
if (active + 1 < playlist.length) {
active += 1;
player.source = playlist[active].source;
}
}
// caching logic
function configureCachingOfPlaylist() {
var cached = []; // var to store which playlist item has already been cached
player.addEventListener('timeupdate', function() {
var videoPercentage = Math.round(player.currentTime/player.duration*100);
// check if cache should happen
if ((active < (playlist.length - 1)) && !cached[active+1] && videoPercentage >= 75) {
cached[active+1] = true;
var task = THEOplayer.cache.createTask(playlist[active+1].source, {amount: '25%'});
task.start();
}
});
}
configureCachingOfPlaylist();