File: /var/www/studis.kauko.lt/wp-content/uploads/h5p/libraries/H5P.Video-1.6/scripts/panopto.js
/** @namespace H5P */
H5P.VideoPanopto = (function ($) {
/**
* Panopto video player for H5P.
*
* @class
* @param {Array} sources Video files to use
* @param {Object} options Settings for the player
* @param {Object} l10n Localization strings
*/
function Panopto(sources, options, l10n) {
var self = this;
self.volume = 100;
self.toSeek = undefined;
var player;
var playbackRate = 1;
let canHasAutoplay;
var id = 'h5p-panopto-' + numInstances;
numInstances++;
let isLoaded = false;
let isPlayerReady = false;
var $wrapper = $('<div/>');
var $placeholder = $('<div/>', {
id: id,
html: '<div>' + l10n.loading + '</div>'
}).appendTo($wrapper);
// Determine autoplay/play.
try {
if (document.featurePolicy.allowsFeature('autoplay') !== false) {
canHasAutoplay = true;
}
}
catch (err) {}
/**
* Use the Panopto API to create a new player
*
* @private
*/
var create = function () {
if (!$placeholder.is(':visible') || player !== undefined) {
return;
}
if (window.EmbedApi === undefined) {
// Load API first
loadAPI(create);
return;
}
var width = $wrapper.width();
if (width < 200) {
width = 200;
}
const videoId = getId(sources[0].path);
player = new EmbedApi(id, {
width: width,
height: width * (9/16),
serverName: videoId[0],
sessionId: videoId[1],
videoParams: { // Optional
interactivity: 'none',
showtitle: false,
autohide: true,
offerviewer: false,
autoplay: false,
showbrand: false,
start: 0,
hideoverlay: !options.controls,
},
events: {
onIframeReady: function () {
isPlayerReady = true;
$placeholder.children(0).text('');
if (options.autoplay && canHasAutoplay) {
player.loadVideo();
isLoaded = true;
}
self.trigger('containerLoaded');
self.trigger('resize'); // Avoid black iframe if loading is slow
},
onReady: function () {
self.videoLoaded = true;
self.trigger('loaded');
if (typeof self.oldTime === 'number') {
self.seek(self.oldTime);
}
else if (typeof self.startAt === 'number' && self.startAt > 0) {
self.seek(self.startAt);
}
if (player.hasCaptions()) {
const captions = [];
const captionTracks = player.getCaptionTracks();
for (trackIndex in captionTracks) {
captions.push(new H5P.Video.LabelValue(captionTracks[trackIndex], trackIndex));
}
// Select active track
currentTrack = player.getSelectedCaptionTrack();
currentTrack = captions[currentTrack] ? captions[currentTrack] : null;
self.trigger('captions', captions);
}
},
onStateChange: function (state) {
if ([H5P.Video.PLAYING, H5P.Video.PAUSED].includes(state) && typeof self.seekToTime === 'number') {
player.seekTo(self.seekToTime);
delete self.seekToTime;
}
// since panopto has different load sequence in IV, need additional condition here
if (self.WAS_RESET) {
self.WAS_RESET = false;
}
// TODO: Playback rate fix for IE11?
if (state > -1 && state < 4) {
self.trigger('stateChange', state);
}
},
onPlaybackRateChange: function () {
self.trigger('playbackRateChange', self.getPlaybackRate());
},
onError: function (error) {
if (error === ApiError.PlayWithSoundNotAllowed) {
// pause and allow user to handle playing
self.pause();
self.unMute(); // because player is automuted on this error
}
else {
self.trigger('error', l10n.unknownError);
}
},
onLoginShown: function () {
$placeholder.children().first().remove(); // Remove loading message
self.trigger('loaded'); // Resize parent
}
}
});
};
/**
* Indicates if the video must be clicked for it to start playing.
* This is always true for Panopto since all videos auto play.
*
* @public
*/
self.pressToPlay = true;
/**
* Appends the video player to the DOM.
*
* @public
* @param {jQuery} $container
*/
self.appendTo = function ($container) {
$container.addClass('h5p-panopto').append($wrapper);
create();
};
/**
* Get list of available qualities. Not available until after play.
*
* @public
* @returns {Array}
*/
self.getQualities = function () {
// Not available for Panopto
};
/**
* Get current playback quality. Not available until after play.
*
* @public
* @returns {String}
*/
self.getQuality = function () {
// Not available for Panopto
};
/**
* Set current playback quality. Not available until after play.
* Listen to event "qualityChange" to check if successful.
*
* @public
* @params {String} [quality]
*/
self.setQuality = function (quality) {
// Not available for Panopto
};
/**
* Start the video.
*
* @public
*/
self.play = function () {
if (!player || !player.playVideo || !isPlayerReady) {
return;
}
if (isLoaded || self.videoLoaded) {
player.playVideo();
}
else {
player.loadVideo(); // Loads and starts playing
isLoaded = true;
}
};
/**
* Pause the video.
*
* @public
*/
self.pause = function () {
if (!player || !player.pauseVideo) {
return;
}
try {
player.pauseVideo();
}
catch (err) {
// Swallow Panopto throwing an error. This has been seen in the authoring
// tool if Panopto has been used inside Iv inside CP
}
};
/**
* Seek video to given time.
*
* @public
* @param {Number} time
*/
self.seek = function (time) {
if (!player || !player.seekTo || !self.videoLoaded) {
return;
}
if (!player.isReady) {
self.seekToTime = time;
return;
}
player.seekTo(time);
if (self.WAS_RESET) {
// need to check just to be sure, since state === 1 is unusable
delete self.seekToTime;
self.WAS_RESET = false;
}
};
/**
* Recreate player with initial time
*
* @public
* @param {Number} time
*/
self.resetPlayback = function (time) {
if (player && player.isReady && self.videoLoaded) {
self.seek(time);
self.pause();
}
else {
self.seekToTime = time;
}
}
/**
* Get elapsed time since video beginning.
*
* @public
* @returns {Number}
*/
self.getCurrentTime = function () {
if (!player || !player.getCurrentTime) {
return;
}
return player.getCurrentTime();
};
/**
* Get total video duration time.
*
* @public
* @returns {Number}
*/
self.getDuration = function () {
if (!player || !player.getDuration) {
return;
}
return player.getDuration();
};
/**
* Get percentage of video that is buffered.
*
* @public
* @returns {Number} Between 0 and 100
*/
self.getBuffered = function () {
// Not available for Panopto
};
/**
* Turn off video sound.
*
* @public
*/
self.mute = function () {
if (!player || !player.muteVideo) {
return;
}
player.muteVideo();
};
/**
* Turn on video sound.
*
* @public
*/
self.unMute = function () {
if (!player || !player.unmuteVideo) {
return;
}
player.unmuteVideo();
// The volume is set to 0 when the browser prevents autoplay,
// causing there to be no sound despite unmuting
self.setVolume(self.volume);
};
/**
* Check if video sound is turned on or off.
*
* @public
* @returns {Boolean}
*/
self.isMuted = function () {
if (!player || !player.isMuted) {
return;
}
return player.isMuted();
};
/**
* Check video is loaded and ready to play
*
* @public
* @returns {Boolean}
*/
self.isLoaded = function () {
return isPlayerReady;
};
/**
* Return the video sound level.
*
* @public
* @returns {Number} Between 0 and 100.
*/
self.getVolume = function () {
if (!player || !player.getVolume) {
return;
}
return player.getVolume() * 100;
};
/**
* Set video sound level.
*
* @public
* @param {Number} level Between 0 and 100.
*/
self.setVolume = function (level) {
if (!player || !player.setVolume) {
return;
}
player.setVolume(level/100);
self.volume = level;
};
/**
* Get list of available playback rates.
*
* @public
* @returns {Array} available playback rates
*/
self.getPlaybackRates = function () {
return [0.25, 0.5, 1, 1.25, 1.5, 2];
};
/**
* Get current playback rate.
*
* @public
* @returns {Number} such as 0.25, 0.5, 1, 1.25, 1.5 and 2
*/
self.getPlaybackRate = function () {
if (!player || !player.getPlaybackRate) {
return;
}
return player.getPlaybackRate();
};
/**
* Set current playback rate.
* Listen to event "playbackRateChange" to check if successful.
*
* @public
* @params {Number} suggested rate that may be rounded to supported values
*/
self.setPlaybackRate = function (newPlaybackRate) {
if (!player || !player.setPlaybackRate) {
return;
}
player.setPlaybackRate(newPlaybackRate);
};
/**
* Set current captions track.
*
* @param {H5P.Video.LabelValue} Captions track to show during playback
*/
self.setCaptionsTrack = function (track) {
if (!track) {
player.disableCaptions();
currentTrack = null;
}
else {
player.enableCaptions(track.value + '');
currentTrack = track;
}
};
/**
* Figure out which captions track is currently used.
*
* @return {H5P.Video.LabelValue} Captions track
*/
self.getCaptionsTrack = function () {
return currentTrack; // No function for getting active caption track?
};
// Respond to resize events by setting the player size.
self.on('resize', function () {
if (!$wrapper.is(':visible')) {
return;
}
if (!player) {
// Player isn't created yet. Try again.
create();
return;
}
// Use as much space as possible
$wrapper.css({
width: '100%',
height: '100%'
});
var width = $wrapper[0].clientWidth;
var height = options.fit ? $wrapper[0].clientHeight : (width * (9/16));
// Set size
$wrapper.css({
width: width + 'px',
height: height + 'px'
});
const $iframe = $placeholder.children('iframe');
if ($iframe.length) {
$iframe.attr('width', width);
$iframe.attr('height', height);
}
});
let currentTrack;
}
/**
* Check to see if we can play any of the given sources.
*
* @public
* @static
* @param {Array} sources
* @returns {Boolean}
*/
Panopto.canPlay = function (sources) {
return getId(sources[0].path);
};
/**
* Find id of YouTube video from given URL.
*
* @private
* @param {String} url
* @returns {String} Panopto video identifier
*/
var getId = function (url) {
const matches = url.match(/^[^\/]+:\/\/([^\/]*panopto\.[^\/]+)\/Panopto\/.+\?id=(.+)$/);
if (matches && matches.length === 3) {
return [matches[1], matches[2]];
}
};
/**
* Load the IFrame Player API asynchronously.
*/
var loadAPI = function (loaded) {
if (window.onPanoptoEmbedApiReady !== undefined) {
// Someone else is loading, hook in
var original = window.onPanoptoEmbedApiReady;
window.onPanoptoEmbedApiReady = function (id) {
loaded(id);
original(id);
};
}
else {
// Load the API our self
var tag = document.createElement('script');
tag.src = 'https://developers.panopto.com/scripts/embedapi.min.js';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
window.onPanoptoEmbedApiReady = loaded;
}
};
/** @private */
var numInstances = 0;
return Panopto;
})(H5P.jQuery);
// Register video handler
H5P.videoHandlers = H5P.videoHandlers || [];
H5P.videoHandlers.push(H5P.VideoPanopto);