JWPlayer to Video.js
Notes up front
Caching
Please do not cache the following files:
- //vod-vipdev.streaming.in2ip.nl/dorcel_vj/dorcel.js
- //vod-vipdev.streaming.in2ip.nl/dorcel_vj/dorcel-rest.js
- //vod-vipdev.streaming.in2ip.nl/dorcel_vj/dorcel-rest-live.js
These files are generated and adjusted on-demand. Variables such as android and is_mobile are determined by the user-agent and can thus differ on a per-request basis.
URL’s
Please keep in mind that the URL’s contained within this document are for the development environment. The URL’s for the production environment will be different. The production URL’s can be found in the section below this one.
Production URL’s
The production URL that should be used is as follows:
- //vod-vip.streaming.in2ip.nl
It’s available both on HTTP and HTTPS.
The Video.js javascript files can be found in the dorcel-vj folder. The full list of URL’s is as follows:
- //vod-vip.streaming.in2ip.nl/dorcel-vj/dorcel.js
- //vod-vip.streaming.in2ip.nl/dorcel-vj/dorcel2.js
- //vod-vip.streaming.in2ip.nl/dorcel-vj/dorcel-rest.js
- //vod-vip.streaming.in2ip.nl/dorcel-vj/dorcel-live.js
- //vod-vip.streaming.in2ip.nl/dorcel-vj/dorcel2-live.js
- //vod-vip.streaming.in2ip.nl/dorcel-vj/dorcel-rest-live.js
HTML-side
On the HTML-side not a whole lot of changes are needed, they are as follows:
from
<script type="text/javascript" src="http://vod-vip.streaming.in2ip.nl/dorcel/jwplayer.js" ></script>
to
<link rel="stylesheet" href="//vod-vipdev.streaming.in2ip.nl/dorcel_vj/videojs.min.css" />
<script type="text/javascript" src="//vod-vipdev.streaming.in2ip.nl/dorcel_vj/videojs.min.js" ></script>
This change will remove the inclusion of the JWPlayer javascript and include the javascript for Video.js and its CSS file. These files include all javascript/CSS needed for Video.js and its plugins.
from
<div id="myElement">Loading the player...</div>
to
<span id="playerMessage"></span>
<video id="myPlayer" class="video-js vjs-default-skin vjs-big-play-centered" crossorigin="anonymous"></video>
Video.js requires a video element to be used. This change removes the old div and replaces it with a video element with some classes assigned to it. Video.js uses these classes to assign itself to it, and apply themes. In this case the vjs-big-play-centered class ensures the play button is in the middle rather than in the top left-hand corner. The empty span element has been added so that we can show a message in case the player cannot be loaded for whatever reason. For example, on Android versions lower than 5 this will provide a hyperlink to an RTSP stream, rather than an HLS stream since old Android versions seem to have issues with HLS playback.
Javascript-side
On the javascript-side of things not a whole lot has changed either. The change mainly consists of creating a videojs object, rather than a jwplayer one.
from
jwplayer(element).setup({
playlist: [{
sources: [{
file: hls_prefix+token+hls_suffix
},{
file: fallback_prefix+token+fallback_suffix
}]<?php if ($thumbs) { ?>,
tracks: [{
file: thumb_prefix+token+".vtt",
kind: "thumbnails"
}]<?php }; ?>
}],
analytics: { enabled: false },
width: width,
height: height,
primary: "flash",
androidhls: true,
skin: "http<? if (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') echo 's'; ?>://<?= $_SERVER["SERVER_NAME"]; ?>/dorcel/skins/six-dorcel/six-dorcel.xml",
events:{
onError: function() {
jwplayer().stop();
}
},
autostart: true
});
}
jwplayer().onComplete(onComplete);
to
if (override_native) {
videojs.options.hls.overrideNative = true;
videojs.options.html5.nativeAudioTracks = false;
videojs.options.html5.nativeVideoTracks = false;
}
if (flash_enabled) {
videojs.options.flash.swf = "//vod-vipdev.streaming.in2ip.nl/dorcel_vj/videojs.swf"
}
if (strip_cors) {
document.getElementById(element).removeAttribute("crossorigin");
}
var player = videojs(element, {"controls": true,
"autoplay": true,
"preload": "auto",
"width": width,
"height": height,
"nativeControlsForTouch": is_mobile,
"sources": [{type: 'application/x-mpegurl', src: hls_prefix+token+hls_suffix}],
"plugins": {
videoJsResolutionSwitcher: {
}}
}, function(){
this.thumbnails({basePath : thumb_prefix});
});
player.ready(function() {
player.nativeTextTracks = false;
var thumbnail_track = {
kind: 'metadata',
src: thumb_prefix+token+".vtt",
srclang: 'en',
label: 'English',
default: 'default'
};
player.addRemoteTextTrack(thumbnail_track, true);
});
player.on('ended', onComplete);
}
Let’s start off with the if statement on the override_native variable at the beginning of the Video.js code. Most modern browsers support native HLS playback, which works fine but can lack some features, such as support for picking a resolution, subtitles, multiple audio tracks etc. In order to get this functionality back, Video.js has the ability to override this native HLS playback support, and handle everything in Video.js’s javascript instead. So far, we have to enable this on two browsers, Edge and IE11. If we do not enable this on those browsers, functionality will serverely lack. The override_native boolean is set in the backend PHP code.
The next if statement on the flash_enabled parameter sets a custom swf URL in case flash is used. This ensures that we load the swf file from our servers rather than the provided CDN. Then comes the if statement on strip_cors. This if statement ensures we disable the crossorigin="anonymous" when someone is using the “Samsung Internet” app. Samsung Internet is based on Chrome, and as of right now (version 5.4) it’s based on Chrome 51. Chrome up until version 57 refuses to play a video when the crossorigin attribute is present, hence we remove it.
Next up is the creation of the videojs object. We set a bunch of options, for example the size of the player, and we enforce ‘native’ controls on touch devices. More about these options can be read here. We also initialise two plugins, the plugin we use for enabling the user to switch resolutions and a plugin that allows us to show small thumbnails when hovering over the progressbar.
After we’ve created the videojs object, we add a text track to the player once it’s done initialising. This text track contains the thumbnails we’re going to show above the progressbar.
Finally we call the specified function once the video has ended.
from
if (android) {
document.getElementById(element).innerHTML = '<a href="'+fallback_prefix+token+fallback_suffix+'">click for video</a>.<br />If the previous link did not work, please try <a href="#" onClick="android=false; showPlayer(\''+element+'\', \''+token+'\', \''+width+'\', \''+height+'\', \''+onComplete+'\'); return true;">this link</a>.';
}
to
if (android) {
document.getElementById('playerMessage').innerHTML = '<a href="'+fallback_prefix+token+fallback_suffix+'">click for video</a>.<br />If the previous link did not work, please try <a href="#" onClick="android=false; showPlayer(\''+element+'\', \''+token+'\', \''+width+'\', \''+height+'\', \''+onComplete+'\'); return true;">this link</a>.';
var videoparent = document.getElementById(element);
videoparent.parentNode.removeChild(videoparent);
}
This change accompanies the aforementioned span element on the HTML-side of things. Since the element variable matches the player, which is a video element, we can’t set a text to it. What we do instead is set the text to the empty span element above it, and then remove the video element from the DOM.
REST call
The previous method works by us providing a javascript function which sets up the player for you. If you want more control over how the player is set up, you can use either of the following URL’s to obtain all the necessary variables:
//frontend-dev.streaming.in2ip.nl/dorcel_vj/dorcel-rest.js
or
//frontend-dev.streaming.in2ip.nl/dorcel_vj/dorcel-rest-live.js
dorcel-rest.js
If you call dorcel-rest, the data you will get back will look something like this:
var vjParams ={
"hls_prefix":"http:\/\/vod-vip3.streaming.in2ip.nl\/vod\/_definst_\/smil:smil\/",
"hls_suffix":".smil\/playlist.m3u8",
"rtsp_prefix":"rtsp:\/\/vod-vip4.streaming.in2ip.nl\/vod\/_definst_\/",
"rtsp_suffix":"_500.mp4",
"thumb_prefix":"\/\/vod-vip1.streaming.in2ip.nl\/thumbs\/",
"android":false,
"override_native":false,
"flash_enabled":false,
"is_mobile":false,
"strip_cors":false
};
You should use this data in the same way as the example above. Please also have a look at the notes below.
dorcel-rest-live.js
If you call dorcel-rest-live, the data you will get back will look something like this:
var vjParams ={
"hls_prefix":"http:\/\/vod-vip4.streaming.in2ip.nl\/dorcel-live\/_definst_\/smil:smil\/",
"hls_suffix":".smil\/playlist.m3u8",
"rtsp_prefix":"rtsp:\/\/vod-vip3.streaming.in2ip.nl\/dorcel-live\/_definst_\/",
"rtsp_suffix":"_350.mp4",
"android":false,
"override_native":false,
"flash_enabled":false,
"is_mobile":false,
"strip_cors":false
};
You should use this data in the same way as the example above. Please also have a look at the notes below.
Notes
There are a couple of notes regarding the REST call:
- Depending on whether you call dorcel-rest.js over HTTP or HTTPS, the
hls_prefixvariable will change accordingly. So calling it over HTTP will give you an HTTP URL. - The
thumb_prefixvariable is only available if you calldorcel-rest.js. Not when you calldorcel-rest-live.js. - The
androidvariable only changes to true on Android devices running an Android version lower than 5. This is because those Android versions have issues with native HLS playback.