(function( $ ) { 'use strict'; /** * Init player. */ function initPlayer( $el ) { // Vars var playerId = $el.data( 'id' ); var settings = $el.data( 'params' ); // Player var loadPlayer = function() { settings.player.html5 = { vhs: { overrideNative: ! videojs.browser.IS_ANY_SAFARI, } }; var player = videojs( playerId, settings.player ); var overlays = []; var hasVideoStarted = false; // Trigger ready event. var options = { id: playerId, // Backward compatibility to 3.3.0 player_id: playerId, config: settings, // Backward compatibility to 3.3.0 settings: settings, player: player }; $el.trigger( 'player.init', options ); // Fired when the player is ready. player.ready(function() { $el.removeClass( 'vjs-waiting' ); $el.find( '.vjs-big-play-button' ).one( 'click', function() { if ( ! hasVideoStarted ) { $el.addClass( 'vjs-waiting' ); } }); }); // On metadata loaded. player.one( 'loadedmetadata', function() { // Standard quality selector. $el.find( '.vjs-quality-selector .vjs-menu-item' ).each(function() { var $this = $( this ); var text = $this.find( '.vjs-menu-item-text' ).html(); var resolution = text.replace( /\D/g, '' ); if ( resolution >= 2160 ) { $this.append( '4K' ); } else if ( resolution >= 720 ) { $this.append( 'HD' ); } }); // Add support for SRT. if ( settings.hasOwnProperty( 'tracks' ) ) { for ( var i = 0, max = settings.tracks.length; i < max; i++ ) { var track = settings.tracks[ i ]; var mode = ''; if ( i == 0 && settings.cc_load_policy == 1 ) { mode = 'showing'; } if ( /srt/.test( track.src.toLowerCase() ) ) { addSrtTextTrack( player, track, mode ); } else { var obj = { kind: 'subtitles', src: track.src, label: track.label, srclang: track.srclang }; if ( mode ) { obj.mode = mode; } player.addRemoteTextTrack( obj, true ); } } } // Chapters if ( settings.hasOwnProperty( 'chapters' ) ) { addMarkers( player, settings.chapters ); } }); // Chapters if ( settings.hasOwnProperty( 'chapters' ) ) { try { player.getDescendant([ 'controlBar', 'progressControl', 'seekBar', 'mouseTimeDisplay', 'timeTooltip', ]).update = function( seekBarRect, seekBarPoint, time ) { var markers = settings.chapters; var markerIndex = markers.findIndex(({ time: markerTime }) => markerTime == formatedTimeToSeconds( time )); if ( markerIndex > -1 ) { var label = markers[ markerIndex ].label; videojs.dom.emptyEl( this.el() ); videojs.dom.appendContent( this.el(), [labelEl( label ), timeEl( time )] ); return false; } this.write( time ); }; } catch ( error ) { /** console.log( error ); */ } } // Fired the first time a video is played. player.one( 'play', function( e ) { hasVideoStarted = true; $el.removeClass( 'vjs-waiting' ); updateViewsCount( settings ); $( '.aiovg-player-standard' ).trigger( 'playRequested', { playerId: playerId } ); }); $el.on( 'playRequested', function( event, args ) { if ( playerId != args.playerId ) { player.pause(); } }); player.on( 'playing', function() { player.trigger( 'controlsshown' ); }); player.on( 'ended', function() { player.trigger( 'controlshidden' ); }); // Standard quality selector. player.on( 'qualitySelected', function( event, source ) { var resolution = source.label.replace( /\D/g, '' ); player.removeClass( 'vjs-4k' ); player.removeClass( 'vjs-hd' ); if ( resolution >= 2160 ) { player.addClass( 'vjs-4k' ); } else if ( resolution >= 720 ) { player.addClass( 'vjs-hd' ); } }); // HLS quality selector. var src = player.src(); if ( /.m3u8/.test( src ) || /.mpd/.test( src ) ) { if ( settings.player.controlBar.children.indexOf( 'qualitySelector' ) !== -1 ) { player.qualityMenu(); } } // Offset var offset = {}; if ( settings.hasOwnProperty( 'start' ) ) { offset.start = settings.start; } if ( settings.hasOwnProperty( 'end' ) ) { offset.end = settings.end; } if ( Object.keys( offset ).length > 1 ) { offset.restart_beginning = false; player.offset( offset ); } // Share / Embed. if ( settings.hasOwnProperty( 'share' ) || settings.hasOwnProperty( 'embed' ) ) { overlays.push({ content: '', class: 'vjs-share', align: 'top-right', start: 'controlsshown', end: 'controlshidden', showBackground: false }); } // Download if ( settings.hasOwnProperty( 'download' ) ) { var className = 'vjs-download'; if ( settings.hasOwnProperty( 'share' ) || settings.hasOwnProperty( 'embed' ) ) { className += ' vjs-has-share'; } overlays.push({ content: 'Download', class: className, align: 'top-right', start: 'controlsshown', end: 'controlshidden', showBackground: false }); } // Logo if ( settings.hasOwnProperty( 'logo' ) ) { var attributes = []; attributes['src'] = settings.logo.image; if ( settings.logo.margin ) { settings.logo.margin = settings.logo.margin - 5; } var align = 'bottom-left'; attributes['style'] = 'margin: ' + settings.logo.margin + 'px;'; switch ( settings.logo.position ) { case 'topleft': align = 'top-left'; attributes['style'] = 'margin: ' + settings.logo.margin + 'px;'; break; case 'topright': align = 'top-right'; attributes['style'] = 'margin: ' + settings.logo.margin + 'px;'; break; case 'bottomright': align = 'bottom-right'; attributes['style'] = 'margin: ' + settings.logo.margin + 'px;'; break; } var logo = ''; if ( settings.logo.link ) { logo = '' + logo + ''; } overlays.push({ content: logo, class: 'vjs-logo', align: align, start: 'controlsshown', end: 'controlshidden', showBackground: false }); } // Overlay if ( overlays.length > 0 ) { player.overlay({ content: '', overlays: overlays }); if ( settings.hasOwnProperty( 'share' ) || settings.hasOwnProperty( 'embed' ) ) { var options = {}; options.content = $el.find( '.vjs-share-embed' ).get(0); options.temporary = false; var ModalDialog = videojs.getComponent( 'ModalDialog' ); var modal = new ModalDialog( player, options ); modal.addClass( 'vjs-modal-dialog-share-embed' ); player.addChild( modal ); var wasPlaying = true; $el.find( '.vjs-share-embed-button' ).on( 'click', function() { wasPlaying = ! player.paused; modal.open(); }); modal.on( 'modalclose', function() { if ( wasPlaying ) { player.play(); } }); } if ( settings.hasOwnProperty( 'embed' ) ) { $el.find( '.vjs-copy-embed-code' ).on( 'focus', function() { $( this ).select(); document.execCommand( 'copy' ); }); } } // Keyboard hotkeys. if ( settings.hotkeys ) { player.hotkeys(); } // Custom contextmenu. if ( settings.hasOwnProperty( 'contextmenu' ) ) { if ( ! $( '#aiovg-contextmenu' ).length ) { $( 'body' ).append( '' ); } var contextmenu = document.getElementById( 'aiovg-contextmenu' ); var timeoutHandler = ''; $( '#' + playerId ).on( 'contextmenu', function( e ) { if ( e.keyCode == 3 || e.which == 3 ) { e.preventDefault(); e.stopPropagation(); var width = contextmenu.offsetWidth, height = contextmenu.offsetHeight, x = e.pageX, y = e.pageY, doc = document.documentElement, scrollLeft = ( window.pageXOffset || doc.scrollLeft ) - ( doc.clientLeft || 0 ), scrollTop = ( window.pageYOffset || doc.scrollTop ) - ( doc.clientTop || 0 ), left = x + width > window.innerWidth + scrollLeft ? x - width : x, top = y + height > window.innerHeight + scrollTop ? y - height : y; contextmenu.style.display = ''; contextmenu.style.left = left + 'px'; contextmenu.style.top = top + 'px'; clearTimeout( timeoutHandler ); timeoutHandler = setTimeout(function() { contextmenu.style.display = 'none'; }, 1500); } }); document.addEventListener( 'click', function() { contextmenu.style.display = 'none'; }); } }; // ... if ( settings.cookie_consent ) { $el.find( '.aiovg-privacy-consent-button' ).on( 'click', function() { $( this ).html( '...' ); settings.player.autoplay = true; setCookie(); loadPlayer(); $el.find( '.aiovg-privacy-wrapper' ).remove(); $( '.aiovg-player-standard' ).trigger( 'cookieConsent' ); $( '.aiovg-player-element' ).removeAttr( 'cookieconsent' ); }); $el.on( 'cookieConsent', function( event, args ) { if ( $el.find( '.aiovg-privacy-wrapper' ).length > 0 ) { loadPlayer(); $el.find( '.aiovg-privacy-wrapper' ).remove(); } }); } else { loadPlayer(); } } /** * Add SRT Text Track. */ function addSrtTextTrack( player, track, mode ) { var xmlhttp; if ( window.XMLHttpRequest ) { xmlhttp = new XMLHttpRequest(); } else { xmlhttp = new ActiveXObject( 'Microsoft.XMLHTTP' ); } xmlhttp.onreadystatechange = function() { if ( xmlhttp.readyState == 4 && xmlhttp.status == 200 && xmlhttp.responseText ) { var text = srtToWebVTT( xmlhttp.responseText ); if ( text ) { var blob = new Blob([ text ], { type : 'text/vtt' }); var src = URL.createObjectURL( blob ); var obj = { kind: 'subtitles', src: src, label: track.label, srclang: track.srclang }; if ( mode ) { obj.mode = mode; } player.addRemoteTextTrack( obj, true ); } } }; xmlhttp.open( 'GET', track.src, true ); xmlhttp.send(); } /** * Convert SRT to WebVTT. */ function srtToWebVTT( data ) { // Remove dos newlines. var srt = data.replace( /\r+/g, '' ); // Trim white space start and end. srt = srt.replace( /^\s+|\s+$/g, '' ); // Get cues. var cuelist = srt.split( '\n\n' ); var result = ''; if ( cuelist.length > 0 ) { result += "WEBVTT\n\n"; for ( var i = 0; i < cuelist.length; i++ ) { result += convertSrtCue( cuelist[ i ] ); } } return result; } function convertSrtCue( caption ) { // Remove all html tags for security reasons. // srt = srt.replace( /<[a-zA-Z\/][^>]*>/g, '' ); var cue = ''; var s = caption.split( /\n/ ); // Concatenate muilt-line string separated in array into one. while ( s.length > 3 ) { for ( var i = 3; i < s.length; i++ ) { s[2] += "\n" + s[ i ]; } s.splice( 3, s.length - 3 ); } var line = 0; // Detect identifier. if ( ! s[0].match( /\d+:\d+:\d+/ ) && s[1].match( /\d+:\d+:\d+/ ) ) { cue += s[0].match( /\w+/ ) + "\n"; line += 1; } // Get time strings. if ( s[ line ].match( /\d+:\d+:\d+/ ) ) { // Convert time string. var m = s[1].match( /(\d+):(\d+):(\d+)(?:,(\d+))?\s*--?>\s*(\d+):(\d+):(\d+)(?:,(\d+))?/ ); if ( m ) { cue += m[1] + ":" + m[2] + ":" + m[3] + "." + m[4] + " --> " + m[5] + ":" + m[6] + ":" + m[7] + "." + m[8] + "\n"; line += 1; } else { // Unrecognized timestring. return ''; } } else { // File format error or comment lines. return ''; } // Get cue text. if ( s[ line ] ) { cue += s[ line ] + "\n\n"; } return cue; } /** * Helper functions for chapters. */ function addMarkers( player, markers ) { var total = player.duration(); var seekBar = document.querySelector( '.vjs-progress-control .vjs-progress-holder' ); if ( seekBar !== null ) { for ( var i = 0; i < markers.length; i++ ) { var elem = document.createElement( 'div' ); elem.className = 'vjs-marker'; elem.style.left = ( markers[ i ].time / total ) * 100 + '%'; seekBar.appendChild( elem ); } } } function formatedTimeToSeconds( time ) { var timeSplit = time.split( ':' ); var seconds = +timeSplit.pop(); return timeSplit.reduce(( acc, curr, i, arr ) => { if ( arr.length === 2 && i === 1 ) return acc + +curr * 60 ** 2; else return acc + +curr * 60; }, seconds); } function timeEl( time ) { return videojs.dom.createEl( 'span', undefined, undefined, '(' + time + ')' ); } function labelEl( label ) { return videojs.dom.createEl( 'strong', undefined, undefined, label ); } /** * Set GDPR cookie. */ function setCookie() { var data = { 'action': 'aiovg_set_cookie', 'security': aiovg_player.ajax_nonce }; $.post( aiovg_player.ajax_url, data, function( response ) { /** console.log( response ); */ }); } /** * Update video views count. */ function updateViewsCount( settings ) { if ( 'aiovg_videos' !== settings.post_type ) { return false; } var data = { 'action': 'aiovg_update_views_count', 'post_id': settings.post_id, 'security': aiovg_player.ajax_nonce }; $.post( aiovg_player.ajax_url, data, function( response ) { /** console.log( response ); */ }); } /** * Merge attributes. */ function mergeAttributes( attributes ) { var str = ''; for ( var key in attributes ) { str += ( key + '="' + attributes[ key ] + '" ' ); } return str; } /** * Refresh iframe player elements upon cookie confirmation. */ window.onmessage = function( event ) { if ( event.data == 'aiovg-cookie-consent' ) { $( '.aiovg-player-iframe iframe' ).each(function() { var src = $( this ).attr( 'src' ); if ( src.indexOf( 'refresh=1' ) == -1 ) { var separator = src.indexOf( '?' ) > -1 ? '&' : '?'; $( this ).attr( 'src', src + separator + 'refresh=1' ); } }); } }; /** * Called when the page has loaded. */ $(function() { // Update views count for the non-iframe embeds $( '.aiovg-player-raw' ).each(function() { var settings = $( this ).data( 'params' ); updateViewsCount( settings ); }); // Init player. $( '.aiovg-player-standard' ).each(function() { initPlayer( $( this ) ); }); // Custom error message. if ( typeof videojs !== "undefined" ) { videojs.hook( 'beforeerror', function( player, error ) { // Prevent current error from being cleared out. if ( error == null ) { return player.error(); } // But allow changing to a new error. if ( error.code == 2 || error.code == 4 ) { var src = player.src(); if ( /.m3u8/.test( src ) || /.mpd/.test( src ) ) { return { code: error.code, message: aiovg_player.i18n.stream_not_found } } } return error; }); } }); })( jQuery );