'use strict'; var player_data = JSON.parse(document.getElementById('player_data').textContent); var video_data = JSON.parse(document.getElementById('video_data').textContent); var options = { preload: 'auto', liveui: true, playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0], controlBar: { children: [ 'playToggle', 'volumePanel', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'remainingTimeDisplay', 'Spacer', 'captionsButton', 'audioTrackButton', 'qualitySelector', 'playbackRateMenuButton', 'fullscreenToggle' ] }, html5: { preloadTextTracks: false, vhs: { overrideNative: true } } }; if (player_data.aspect_ratio) { options.aspectRatio = player_data.aspect_ratio; } var embed_url = new URL(location); embed_url.searchParams.delete('v'); var short_url = location.origin + '/' + video_data.id + embed_url.search; embed_url = location.origin + '/embed/' + video_data.id + embed_url.search; var save_player_pos_key = 'save_player_pos'; videojs.Vhs.xhr.beforeRequest = function(options) { // set local if requested not videoplayback if (!options.uri.includes('videoplayback')) { if (!options.uri.includes('local=true')) options.uri += '?local=true'; } return options; }; var player = videojs('player', options); player.on('error', function () { if (video_data.params.quality === 'dash') return; var localNotDisabled = ( !player.currentSrc().includes('local=true') && !video_data.local_disabled ); var reloadMakesSense = ( player.error().code === MediaError.MEDIA_ERR_NETWORK || player.error().code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED ); if (localNotDisabled) { // add local=true to all current sources player.src(player.currentSources().map(function (source) { source.src += '&local=true'; return source; })); } else if (reloadMakesSense) { setTimeout(function () { console.warn('An error occurred in the player, reloading...'); // After load() all parameters are reset. Save them var currentTime = player.currentTime(); var playbackRate = player.playbackRate(); var paused = player.paused(); player.load(); if (currentTime > 0.5) currentTime -= 0.5; player.currentTime(currentTime); player.playbackRate(playbackRate); if (!paused) player.play(); }, 5000); } }); if (video_data.params.quality === 'dash') { player.reloadSourceOnError({ errorInterval: 10 }); } /** * Function for add time argument to url * @param {String} url * @returns {URL} urlWithTimeArg */ function addCurrentTimeToURL(url) { var urlUsed = new URL(url); urlUsed.searchParams.delete('start'); var currentTime = Math.ceil(player.currentTime()); if (currentTime > 0) urlUsed.searchParams.set('t', currentTime); else if (urlUsed.searchParams.has('t')) urlUsed.searchParams.delete('t'); return urlUsed; } var shareOptions = { socials: ['fbFeed', 'tw', 'reddit', 'email'], get url() { return addCurrentTimeToURL(short_url); }, title: player_data.title, description: player_data.description, image: player_data.thumbnail, get embedCode() { // Single quotes inside here required. HTML inserted as is into value attribute of input return ""; } }; if (location.pathname.startsWith('/embed/')) { var overlay_content = '

' + player_data.title + '

'; player.overlay({ overlays: [ { start: 'loadstart', content: overlay_content, end: 'playing', align: 'top'}, { start: 'pause', content: overlay_content, end: 'playing', align: 'top'} ] }); } // Detect mobile users and initialize mobileUi for better UX // Detection code taken from https://stackoverflow.com/a/20293441 function isMobile() { try{ document.createEvent('TouchEvent'); return true; } catch(e){ return false; } } if (isMobile()) { player.mobileUi({ touchControls: { seekSeconds: 5 * player.playbackRate() } }); var buttons = ['playToggle', 'volumePanel', 'captionsButton']; if (!video_data.params.listen && video_data.params.quality === 'dash') buttons.push('audioTrackButton'); if (video_data.params.listen || video_data.params.quality !== 'dash') buttons.push('qualitySelector'); // Create new control bar object for operation buttons const ControlBar = videojs.getComponent('controlBar'); let operations_bar = new ControlBar(player, { children: [], playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0] }); buttons.slice(1).forEach(function (child) {operations_bar.addChild(child);}); // Remove operation buttons from primary control bar var primary_control_bar = player.getChild('controlBar'); buttons.forEach(function (child) {primary_control_bar.removeChild(child);}); var operations_bar_element = operations_bar.el(); operations_bar_element.classList.add('mobile-operations-bar'); player.addChild(operations_bar); // Playback menu doesn't work when it's initialized outside of the primary control bar var playback_element = document.getElementsByClassName('vjs-playback-rate')[0]; operations_bar_element.append(playback_element); // The share and http source selector element can't be fetched till the players ready. player.one('playing', function () { var share_element = document.getElementsByClassName('vjs-share-control')[0]; operations_bar_element.append(share_element); if (!video_data.params.listen && video_data.params.quality === 'dash') { var http_source_selector = document.getElementsByClassName('vjs-http-source-selector vjs-menu-button')[0]; operations_bar_element.append(http_source_selector); } }); } // Enable VR video support if (!video_data.params.listen && video_data.vr && video_data.params.vr_mode) { player.crossOrigin('anonymous'); switch (video_data.projection_type) { case 'EQUIRECTANGULAR': player.vr({projection: 'equirectangular'}); default: // Should only be 'MESH' but we'll use this as a fallback. player.vr({projection: 'EAC'}); } } // Add markers if (video_data.params.video_start > 0 || video_data.params.video_end > 0) { var markers = [{ time: video_data.params.video_start, text: 'Start' }]; if (video_data.params.video_end < 0) { markers.push({ time: video_data.length_seconds - 0.5, text: 'End' }); } else { markers.push({ time: video_data.params.video_end, text: 'End' }); } player.markers({ onMarkerReached: function (marker) { if (marker.text === 'End') player.loop() ? player.markers.prev('Start') : player.pause(); }, markers: markers }); player.currentTime(video_data.params.video_start); } player.volume(video_data.params.volume / 100); player.playbackRate(video_data.params.speed); // Dirty hack to set a property in