207 lines
6 KiB
JavaScript
207 lines
6 KiB
JavaScript
/**
|
|
* This script hunts for video tags and initializes the correct player
|
|
* depending on the platform:
|
|
* - web: jwplayer
|
|
* - iOS/Android: Native player
|
|
*
|
|
* Once jwplayer is initialized there's no follow up actions to be taken.
|
|
* Mobile Native players send back information into the DOM in order to
|
|
* interact and update the UI, therefore a MutationObserver is registered.
|
|
*/
|
|
|
|
/* eslint no-use-before-define: 0 */
|
|
/* eslint no-param-reassign: 0 */
|
|
/* eslint no-useless-escape: 0 */
|
|
/* global jwplayer, ahoy, Runtime */
|
|
|
|
function initializeVideoPlayback() {
|
|
var currentTime = '0';
|
|
var deviceType = 'web';
|
|
var lastEvent = '';
|
|
|
|
function getById(name) {
|
|
return document.getElementById(name);
|
|
}
|
|
|
|
function getParameterByName(name, url) {
|
|
if (!url) url = window.location.href;
|
|
name = name.replace(/[\[\]]/g, '\\$&');
|
|
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
|
|
results = regex.exec(url);
|
|
if (!results) return null;
|
|
if (!results[2]) return '';
|
|
return decodeURIComponent(results[2].replace(/\+/g, ' '));
|
|
}
|
|
|
|
function timeToSeconds(hms) {
|
|
var a;
|
|
if (hms.length < 3) {
|
|
return hms;
|
|
} else if (hms.length < 6) {
|
|
a = hms.split(':');
|
|
return (hms = +a[0] * 60 + +a[1]);
|
|
} else {
|
|
a = hms.split(':');
|
|
return (hms = +a[0] * 60 * 60 + +a[1] * 60 + +a[2]);
|
|
}
|
|
}
|
|
|
|
function videoPlayerEvent(isPlaying) {
|
|
// jwtplayer tends to send multiple 'play' actions. This check makes sure
|
|
// we're not tracking repeated 'play' events for a single interaction.
|
|
var eventName = isPlaying ? 'play' : 'pause';
|
|
if (lastEvent === eventName) {
|
|
return;
|
|
}
|
|
lastEvent = eventName;
|
|
|
|
var metadata = videoMetadata(getById('video-player-source'));
|
|
var properties = {
|
|
article: metadata.id,
|
|
deviceType: deviceType,
|
|
action: eventName,
|
|
};
|
|
ahoy.track('Video Player Streaming', properties);
|
|
}
|
|
|
|
function initWebPlayer(seconds, metadata) {
|
|
var waitingOnJWP = setInterval(function () {
|
|
if (typeof jwplayer !== 'undefined') {
|
|
clearInterval(waitingOnJWP);
|
|
var playerInstance = jwplayer(`video-player-${metadata.id}`);
|
|
playerInstance.setup({
|
|
file: metadata.video_source_url,
|
|
mediaid: metadata.video_code,
|
|
image: metadata.video_thumbnail_url,
|
|
playbackRateControls: true,
|
|
tracks: [
|
|
{
|
|
file: metadata.video_closed_caption_track_url,
|
|
label: 'English',
|
|
kind: 'captions',
|
|
default: false,
|
|
},
|
|
],
|
|
});
|
|
if (seconds) {
|
|
jwplayer().on('firstFrame', function () {
|
|
jwplayer().seek(seconds);
|
|
});
|
|
jwplayer().on('play', function () {
|
|
videoPlayerEvent(true);
|
|
});
|
|
jwplayer().on('pause', function () {
|
|
videoPlayerEvent(false);
|
|
});
|
|
}
|
|
}
|
|
}, 2);
|
|
}
|
|
|
|
function videoMetadata(videoSource) {
|
|
try {
|
|
return JSON.parse(videoSource.dataset.meta);
|
|
} catch (e) {
|
|
console.log('Unable to load Podcast Episode metadata', e); // eslint-disable-line no-console
|
|
}
|
|
}
|
|
|
|
function requestFocus() {
|
|
var metadata = videoMetadata(videoSource);
|
|
var playerElement = getById(`video-player-${metadata.id}`);
|
|
|
|
getById('pause-butt').classList.add('active');
|
|
getById('play-butt').classList.remove('active');
|
|
|
|
Runtime.videoMessage({
|
|
action: 'play',
|
|
url: metadata.video_source_url,
|
|
seconds: currentTime,
|
|
});
|
|
|
|
videoPlayerEvent(true);
|
|
}
|
|
|
|
function handleVideoMessages(mutation) {
|
|
if (mutation.type !== 'attributes') {
|
|
return;
|
|
}
|
|
|
|
var message = {};
|
|
try {
|
|
var messageData = getById('video-player-source').dataset.message;
|
|
message = JSON.parse(messageData);
|
|
} catch (e) {
|
|
console.log(e); // eslint-disable-line no-console
|
|
return;
|
|
}
|
|
|
|
switch (message.action) {
|
|
case 'play':
|
|
getById('pause-butt').classList.add('active');
|
|
getById('play-butt').classList.remove('active');
|
|
videoPlayerEvent(true);
|
|
break;
|
|
case 'pause':
|
|
getById('pause-butt').classList.remove('active');
|
|
getById('play-butt').classList.add('active');
|
|
videoPlayerEvent(false);
|
|
break;
|
|
case 'tick':
|
|
currentTime = message.currentTime;
|
|
break;
|
|
default:
|
|
console.log('Unrecognized video message: ', message); // eslint-disable-line no-console
|
|
}
|
|
}
|
|
|
|
function initializePlayer(videoSource) {
|
|
var seconds = timeToSeconds(getParameterByName('t') || '0');
|
|
var metadata = videoMetadata(videoSource);
|
|
|
|
if (Runtime.isNativeIOS('video')) {
|
|
deviceType = 'iOS';
|
|
Runtime.videoMessage = function (message) {
|
|
try {
|
|
window.webkit.messageHandlers.video.postMessage(message);
|
|
} catch (err) {
|
|
console.log(err.message); // eslint-disable-line no-console
|
|
}
|
|
};
|
|
} else if (Runtime.isNativeAndroid('videoMessage')) {
|
|
deviceType = 'Android';
|
|
Runtime.videoMessage = function (message) {
|
|
try {
|
|
AndroidBridge.videoMessage(JSON.stringify(message));
|
|
} catch (err) {
|
|
console.log(err.message); // eslint-disable-line no-console
|
|
}
|
|
};
|
|
} else {
|
|
// jwplayer is initialized and no further interaction is needed
|
|
initWebPlayer(seconds, metadata);
|
|
return;
|
|
}
|
|
|
|
var playerElement = getById(`video-player-${metadata.id}`);
|
|
playerElement.addEventListener('click', requestFocus);
|
|
|
|
playerElement.classList.add('native');
|
|
getById('play-butt').classList.add('active');
|
|
|
|
var mutationObserver = new MutationObserver(function (mutations) {
|
|
mutations.forEach(function (mutation) {
|
|
handleVideoMessages(mutation);
|
|
});
|
|
});
|
|
mutationObserver.observe(videoSource, { attributes: true });
|
|
|
|
currentTime = `${seconds}`;
|
|
}
|
|
|
|
// If an video player element is found initialize it
|
|
var videoSource = getById('video-player-source');
|
|
if (videoSource !== null) {
|
|
initializePlayer(videoSource);
|
|
}
|
|
}
|