2020-10-04 21:48:37 +02:00
window . HELP _IMPROVE _VIDEOJS = false ; ( function ( global , factory ) { typeof exports === "object" && typeof module !== "undefined" ? module . exports = factory ( require ( "global/window" ) , require ( "global/document" ) ) : typeof define === "function" && define . amd ? define ( [ "global/window" , "global/document" ] , factory ) : ( global = global || self , global . videojs = factory ( global . window , global . document ) ) } ) ( this , function ( window $1 , document ) { window $1 = window $1 && window $1 . hasOwnProperty ( "default" ) ? window $1 [ "default" ] : window $1 ; document = document && document . hasOwnProperty ( "default" ) ? document [ "default" ] : document ; var version = "7.6.6" ; var history = [ ] ; var LogByTypeFactory = function LogByTypeFactory ( name , log ) { return function ( type , level , args ) { var lvl = log . levels [ level ] ; var lvlRegExp = new RegExp ( "^(" + lvl + ")$" ) ; if ( type !== "log" ) { args . unshift ( type . toUpperCase ( ) + ":" ) } args . unshift ( name + ":" ) ; if ( history ) { history . push ( [ ] . concat ( args ) ) } if ( ! window $1 . console ) { return } var fn = window $1 . console [ type ] ; if ( ! fn && type === "debug" ) { fn = window $1 . console . info || window $1 . console . log } if ( ! fn || ! lvl || ! lvlRegExp . test ( type ) ) { return } fn [ Array . isArray ( args ) ? "apply" : "call" ] ( window $1 . console , args ) } } ; function createLogger ( name ) { var level = "info" ; var logByType ; var log = function log ( ) { for ( var _len = arguments . length , args = new Array ( _len ) , _key = 0 ; _key < _len ; _key ++ ) { args [ _key ] = arguments [ _key ] } logByType ( "log" , level , args ) } ; logByType = LogByTypeFactory ( name , log ) ; log . createLogger = function ( subname ) { return createLogger ( name + ": " + subname ) } ; log . levels = { all : "debug|log|warn|error" , off : "" , debug : "debug|log|warn|error" , info : "log|warn|error" , warn : "warn|error" , error : "error" , DEFAULT : level } ; log . level = function ( lvl ) { if ( typeof lvl === "string" ) { if ( ! log . levels . hasOwnProperty ( lvl ) ) { throw new Error ( '"' + lvl + '" in not a valid log level' ) } level = lvl } return level } ; log . history = function ( ) { return history ? [ ] . concat ( history ) : [ ] } ; log . history . filter = function ( fname ) { return ( history || [ ] ) . filter ( function ( historyItem ) { return new RegExp ( ".*" + fname + ".*" ) . test ( historyItem [ 0 ] ) } ) } ; log . history . clear = function ( ) { if ( history ) { history . length = 0 } } ; log . history . disable = function ( ) { if ( history !== null ) { history . length = 0 ; history = null } } ; log . history . enable = function ( ) { if ( history === null ) { history = [ ] } } ; log . error = function ( ) { for ( var _len2 = arguments . length , args = new Array ( _len2 ) , _key2 = 0 ; _key2 < _len2 ; _key2 ++ ) { args [ _key2 ] = arguments [ _key2 ] } return logByType ( "error" , level , args ) } ; log . warn = function ( ) { for ( var _len3 = arguments . length , args = new Array ( _len3 ) , _key3 = 0 ; _key3 < _len3 ; _key3 ++ ) { args [ _key3 ] = arguments [ _key3 ] } return logByType ( "warn" , level , args ) } ; log . debug = function ( ) { for ( var _len4 = arguments . length , args = new Array ( _len4 ) , _key4 = 0 ; _key4 < _len4 ; _key4 ++ ) { args [ _key4 ] = arguments [ _key4 ] } return logByType ( "debug" , level , args ) } ; return log } var log = createLogger ( "VIDEOJS" ) ; var createLogger$1 = log . createLogger ; var toString = Object . prototype . toString ; var keys = function keys ( object ) { return isObject ( object ) ? Object . keys ( object ) : [ ] } ; function each ( object , fn ) { keys ( object ) . forEach ( function ( key ) { return fn ( object [ key ] , key ) } ) } function reduce ( object , fn , initial ) { if ( initial === void 0 ) { initial = 0 } return keys ( object ) . reduce ( function ( accum , key ) { return fn ( accum , object [ key ] , key ) } , initial ) } function assign ( target ) { for ( var _len = arguments . length , sources = new Array ( _len > 1 ? _len - 1 : 0 ) , _key = 1 ; _key < _len ; _key ++ ) { sources [ _key - 1 ] = arguments [ _key ] } if ( Object . assign ) { return Object . assign . apply ( Object , [ target ] . concat ( sources ) ) } sources . forEach ( function ( source ) { if ( ! source ) { return } each ( source , function ( value , key ) { target [ key ] = value } ) } ) ; return target } function isObject ( value ) { return ! ! value && typeof value === "object" } function isPlain ( value ) { return isObject ( value ) && toString . call ( value ) === "[object Object]" && value . constructor === Object } function computedStyle ( el , prop ) { if ( ! el || ! prop ) { return "" } if ( typeof window $1 . getComputedStyle === "function" ) { var computedStyleValue = window $1 . getComputedStyle ( el ) ; return computedStyleValue ? computedStyleValue . getPropertyValue ( prop ) || computedStyleValue [ prop ] : "" } return "" } function isNonBlankString ( str ) { return typeof str === "string" && /\S/ . test ( str ) } function throwIfWhitespace ( str ) { if ( /\s/ . test ( str ) ) { throw new Error ( "class has illegal whitespace characters" ) } } function classReg
2020-10-03 18:44:16 +02:00
const vd = ( function ( ) {
let vd = { } ;
2020-11-05 17:18:16 +01:00
function createEl ( tagName = 'div' , properties = { } , attributes = { } , content ) {
const el = document . createElement ( tagName ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
Object . getOwnPropertyNames ( properties ) . forEach ( function ( propName ) {
const val = properties [ propName ] ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
// See #2176
// We originally were accepting both properties and attributes in the
// same object, but that doesn't work so well.
if ( propName . indexOf ( 'aria-' ) !== - 1 || propName === 'role' || propName === 'type' ) {
log . warn ( tsml ` Setting attributes in the second argument of createEl()
2020-10-03 18:44:16 +02:00
has been deprecated . Use the third argument instead .
createEl ( type , properties , attributes ) . Attempting to set $ { propName } to $ { val } . ` );
2020-11-05 17:18:16 +01:00
el . setAttribute ( propName , val ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
// Handle textContent since it's not supported everywhere and we have a
// method for it.
} else if ( propName === 'textContent' ) {
textContent ( el , val ) ;
} else {
el [ propName ] = val ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
} ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
return el ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
function findPosition ( el ) {
let box ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( el . getBoundingClientRect && el . parentNode ) {
box = el . getBoundingClientRect ( ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( ! box ) {
2020-10-03 18:44:16 +02:00
return {
2020-11-05 17:18:16 +01:00
left : 0 ,
top : 0
2020-10-03 18:44:16 +02:00
} ;
}
2020-11-05 17:18:16 +01:00
const docEl = document . documentElement ;
const body = document . body ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
const clientLeft = docEl . clientLeft || body . clientLeft || 0 ;
const scrollLeft = window . pageXOffset || body . scrollLeft ;
const left = box . left + scrollLeft - clientLeft ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
const clientTop = docEl . clientTop || body . clientTop || 0 ;
const scrollTop = window . pageYOffset || body . scrollTop ;
const top = box . top + scrollTop - clientTop ;
// Android sometimes returns slightly off decimal values, so need to round
return {
left : Math . round ( left ) ,
top : Math . round ( top )
} ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
function getBoundingClientRect ( el ) {
if ( el && el . getBoundingClientRect && el . parentNode ) {
const rect = el . getBoundingClientRect ( ) ;
const result = { } ;
[ 'bottom' , 'height' , 'left' , 'right' , 'top' , 'width' ] . forEach ( k => {
if ( rect [ k ] !== undefined ) {
result [ k ] = rect [ k ] ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
} ) ;
if ( ! result . height ) {
result . height = parseFloat ( computedStyle ( el , 'height' ) ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( ! result . width ) {
result . width = parseFloat ( computedStyle ( el , 'width' ) ) ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
return result ;
}
}
function getPointerPosition ( el , event ) {
const position = { } ;
const box = findPosition ( el ) ;
const boxW = el . offsetWidth ;
const boxH = el . offsetHeight ;
const boxY = box . top ;
const boxX = box . left ;
let pageY = event . pageY ;
let pageX = event . pageX ;
if ( event . changedTouches ) {
pageX = event . changedTouches [ 0 ] . pageX ;
pageY = event . changedTouches [ 0 ] . pageY ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
position . y = Math . max ( 0 , Math . min ( 1 , ( ( boxY - pageY ) + boxH ) / boxH ) ) ;
position . x = Math . max ( 0 , Math . min ( 1 , ( pageX - boxX ) / boxW ) ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
return position ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
let vjs = { } ;
vjs . Component = videojs . getComponent ( 'Component' ) ;
vjs . Menu = videojs . getComponent ( 'Menu' ) ;
vjs . MenuButton = videojs . getComponent ( 'MenuButton' ) ;
vjs . MenuItem = videojs . getComponent ( 'MenuItem' ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
class MenuButton extends vjs . MenuButton {
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
constructor ( player , options ) {
super ( player , options ) ;
this . updateLabel ( options === undefined ? "" : options . label || "" ) ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
createEl ( ) {
const el = super . createEl ( ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
this . labelEl _ = createEl ( 'div' , {
className : 'vjs-playback-rate-value' ,
innerHTML : 'auto'
} ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
el . appendChild ( this . labelEl _ ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
return el ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
dispose ( ) {
this . labelEl _ = null ;
super . dispose ( ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
buildCSSClass ( ) {
return ` vjs-playback-rate ${ super . buildCSSClass ( ) } ` ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
buildWrapperCSSClass ( ) {
return ` vjs-playback-rate ${ super . buildWrapperCSSClass ( ) } ` ;
}
2020-11-05 16:17:05 +01:00
2020-11-05 17:18:16 +01:00
createMenu ( ) {
const menu = new vjs . Menu ( this . player ( ) ) ;
return menu ;
2020-11-05 16:17:05 +01:00
}
2020-11-05 17:18:16 +01:00
updateARIAAttributes ( ) {
this . el ( ) . setAttribute ( 'aria-valuenow' , this . labelEl _ . innerHTML ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
updateLabel ( newLabel ) {
this . labelEl _ . innerHTML = newLabel ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
class ResolutionItem extends vjs . MenuItem {
constructor ( ) {
super ( ... arguments ) ;
this . representation = arguments [ 1 ] . representation ;
this . menuButton = arguments [ 1 ] . menuButton ;
this . label = arguments [ 1 ] . label ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
handleClick ( ) {
if ( this . representation === undefined ) {
// Clicked on the auto button
this . player ( ) . tech ( { IWillNotUseThisInPlugins : true } ) . hls . representations ( ) . forEach ( function ( rep ) {
rep . enabled ( true ) ;
} ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
} else {
// Clicked on another button
let self = this ;
this . player ( ) . tech ( { IWillNotUseThisInPlugins : true } ) . hls . representations ( ) . forEach ( function ( rep ) {
rep . enabled ( rep . height === self . options _ . representation . height ) ;
2020-10-03 18:44:16 +02:00
} ) ;
2020-11-05 17:18:16 +01:00
}
this . menuButton . updateLabel ( this . label ) ;
}
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
class SpeedItem extends vjs . MenuItem {
constructor ( ) {
super ( ... arguments ) ;
this . label = arguments [ 1 ] . label ;
this . speed = arguments [ 1 ] . speed ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
handleClick ( ) {
this . player ( ) . playbackRate ( this . speed ) ;
}
}
class Thumbnail extends vjs . Component {
constructor ( ) {
super ( ... arguments ) ;
this . thumbnails = arguments [ 1 ] . thumbnails ;
this . width = arguments [ 1 ] . width ;
this . height = arguments [ 1 ] . height ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
createEl ( ) {
let el = super . createEl ( 'img' , {
src : this . options _ . thumbnails [ 0 ] ,
width : '0px' ,
} ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
el . style . position = 'absolute' ;
el . style . left = '0px' ;
el . style . top = - this . options _ . height + "px" ;
el . style . border = "solid" ;
el . style . borderColor = "black" ;
el . style . borderWidth = "1px" ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
return el ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
update ( ratio ) {
this . el ( ) . src = this . options _ . thumbnails [ Math . round ( 100 * ratio ) ] ;
}
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
function createRepresentationButtons ( player , menuButton = undefined ) {
if ( menuButton === undefined ) {
menuButton = new MenuButton ( player ) ;
menuButton . updateLabel ( "auto" ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
let hls = player . tech ( { IWillNotUseThisInPlugins : true } ) . hls ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( hls === undefined ) {
setTimeout ( ( ) => createRepresentationButtons ( player , menuButton ) , 500 ) ;
return menuButton ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
let representations = hls . representations ( ) ;
representations . sort ( ( a , b ) => b . height - a . height ) ;
menuButton . menu . items = [ ] ;
menuButton . menu . addAndRecordItem = function ( item ) {
this . addItem ( item ) ;
this . items . push ( item ) ;
}
menuButton . menu . addAndRecordItem ( new ResolutionItem ( player , { label : "auto" , menuButton } ) ) ;
for ( let representation of representations ) {
menuButton . menu . addAndRecordItem ( new ResolutionItem ( player , {
label : representation . height + "p" ,
representation ,
menuButton
} ) ) ;
}
return menuButton ;
}
function createSpeedButtons ( player ) {
let menuButton = new MenuButton ( player ) ;
let speeds = [ 0.25 , 0.5 , 0.75 , 1 , 1.25 , 1.5 , 1.75 , 2 ] ;
menuButton . updateLabel ( 'x1' ) ;
menuButton . menu . items = [ ] ;
menuButton . menu . addAndRecordItem = function ( item ) {
this . addItem ( item ) ;
this . items . push ( item ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
for ( let speed of speeds ) {
menuButton . menu . addAndRecordItem ( new SpeedItem ( player , {
label : "x" + speed ,
speed ,
} ) ) ;
}
return menuButton ;
}
vd . parseTime = function ( t ) {
let parsed = 1 * t ;
if ( ! isNaN ( parsed ) ) {
return parsed ;
}
// Compute the split
let split = t . split ( "h" ) ;
let hours ;
let minutes ;
let seconds ;
switch ( split . length ) {
case 1 :
hours = 0 ;
split = split [ 0 ] . split ( "m" ) ;
break ;
case 2 :
hours = 1 * split [ 0 ] ;
if ( isNaN ( hours ) ) {
return NaN ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
split = split [ 1 ] . split ( "m" ) ;
break ;
default :
return NaN ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
switch ( split . length ) {
case 1 :
minutes = 0 ;
split = split [ 0 ] . split ( "s" ) ;
break ;
case 2 :
minutes = 1 * split [ 0 ] ;
if ( isNaN ( minutes ) ) {
return NaN ;
}
split = split [ 1 ] . split ( "s" ) ;
break ;
default :
return NaN ;
}
2020-11-05 16:17:05 +01:00
2020-11-05 17:18:16 +01:00
seconds = 1 * split [ 0 ] ;
if ( ( split . length !== 1 && ( ! ( split . length == 2 && split [ 1 ] === "" ) ) ) || isNaN ( seconds ) ) {
return NaN ;
2020-11-05 16:17:05 +01:00
}
2020-11-05 17:18:16 +01:00
return 3600 * hours + 60 * minutes + seconds ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
vd . setup = function ( video , args ) {
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
let src ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( typeof video === 'string' || video instanceof String ) {
video = document . getElementById ( video ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( video === undefined ) {
throw new Error ( "video element or ID invalid" ) ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
if ( typeof args === "string" || args instanceof String ) {
src = args ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( typeof args === "object" ) {
src = args . v ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( src === undefined ) {
throw new Error ( "video src is undefined" ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
let player = videojs ( video ) ;
player . src ( {
src ,
type : 'application/dash+xml'
} ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( args . focus === true ) {
player . focus ( ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
player . _oldRequestFullscreen = player . requestFullscreen ;
player . requestFullscreen = function ( ) {
var player = document . getElementById ( this . id ( ) ) ;
if ( player === null ) {
return ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
player = typeof player . player === "function" ? player . player ( ) : player . player ;
player . _oldRequestFullscreen ( ... arguments ) ;
setTimeout ( ( ) => {
if ( screen . orientation ) {
screen . orientation . lock ( "landscape" )
}
} , 1000 ) ;
} ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
player . _oldExitFullscreen = player . exitFullscreen ;
player . exitFullscreen = function ( ) {
var player = document . getElementById ( this . id ( ) ) ;
if ( player === null ) {
return ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
player = typeof player . player === "function" ? player . player ( ) : player . player ;
player . _oldExitFullscreen ( ... arguments ) ;
setTimeout ( ( ) => {
if ( screen . orientation ) {
screen . orientation . unlock ( ) ;
}
} , 1000 ) ;
} ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( args . t !== undefined ) {
let time = vd . parseTime ( args . t ) ;
if ( ! isNaN ( time ) ) {
player . currentTime ( time ) ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
}
2020-10-03 18:44:16 +02:00
2020-10-06 09:54:34 +02:00
2020-11-05 17:18:16 +01:00
if ( player . getAttribute ( 'disable-shortcuts' ) == undefined ) {
player . el ( ) . addEventListener ( 'keydown' , ( e ) => {
if ( e . ctrlKey || e . shiftKey || e . altKey ) {
2020-10-05 00:02:20 +02:00
return ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
let p = document . getElementById ( player . id ( ) ) ;
if ( p === null ) {
2020-10-05 00:02:20 +02:00
return ;
}
2020-11-05 17:18:16 +01:00
p = typeof p . player === "function" ? p . player ( ) : p . player ;
switch ( e . keyCode ) {
case 37 : e . preventDefault ( ) ; p . currentTime ( p . currentTime ( ) - 5 ) ; break ;
case 39 : e . preventDefault ( ) ; p . currentTime ( p . currentTime ( ) + 5 ) ; break ;
case 32 : e . preventDefault ( ) ; if ( p . paused ( ) ) p . play ( ) ; else p . pause ( ) ; break ;
case 40 : e . preventDefault ( ) ; p . volume ( p . volume ( ) - 0.1 ) ; break ;
case 38 : e . preventDefault ( ) ; p . volume ( p . volume ( ) + 0.1 ) ; break ;
}
} , true ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
document . body . addEventListener ( 'keydown' , ( e ) => {
if ( e . ctrlKey || e . shiftKey || e . altKey ) {
return ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
let p = document . getElementById ( player . id ( ) ) ;
if ( p === null ) {
return ;
}
p = typeof p . player === "function" ? p . player ( ) : p . player ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
switch ( e . keyCode ) {
case 74 : e . preventDefault ( ) ; p . currentTime ( p . currentTime ( ) - 10 ) ; break ; // J -> -10s
case 76 : e . preventDefault ( ) ; p . currentTime ( p . currentTime ( ) + 10 ) ; break ; // L -> +10s
case 75 : e . preventDefault ( ) ; if ( p . paused ( ) ) p . play ( ) ; else p . pause ( ) ; break ; // K -> play/pause
case 77 : e . preventDefault ( ) ; p . muted ( ! p . muted ( ) ) ; break ; // M -> mute
2020-10-03 18:44:16 +02:00
// F -> toggle fullscreen
2020-11-05 17:18:16 +01:00
case 70 :
e . preventDefault ( ) ;
2020-10-08 17:25:17 +02:00
2020-11-05 17:18:16 +01:00
if ( p . isFullscreen ( ) ) {
p . exitFullscreen ( ) ;
} else {
p . requestFullscreen ( ) ;
}
break ;
2020-10-03 18:44:16 +02:00
// Seek shortcuts
2020-11-05 17:18:16 +01:00
case 48 : case 96 : e . preventDefault ( ) ; p . currentTime ( 0 ) ; break ;
case 49 : case 97 : e . preventDefault ( ) ; p . currentTime ( p . duration ( ) / 10 ) ; break ;
case 50 : case 98 : e . preventDefault ( ) ; p . currentTime ( 2 * p . duration ( ) / 10 ) ; break ;
case 51 : case 99 : e . preventDefault ( ) ; p . currentTime ( 3 * p . duration ( ) / 10 ) ; break ;
case 52 : case 100 : e . preventDefault ( ) ; p . currentTime ( 4 * p . duration ( ) / 10 ) ; break ;
case 53 : case 101 : e . preventDefault ( ) ; p . currentTime ( 5 * p . duration ( ) / 10 ) ; break ;
case 54 : case 102 : e . preventDefault ( ) ; p . currentTime ( 6 * p . duration ( ) / 10 ) ; break ;
case 55 : case 103 : e . preventDefault ( ) ; p . currentTime ( 7 * p . duration ( ) / 10 ) ; break ;
case 56 : case 104 : e . preventDefault ( ) ; p . currentTime ( 8 * p . duration ( ) / 10 ) ; break ;
case 57 : case 105 : e . preventDefault ( ) ; p . currentTime ( 9 * p . duration ( ) / 10 ) ; break ;
}
} , true ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
let root = src . split ( '/' ) . slice ( 0 , - 1 ) . join ( '/' ) ;
if ( root !== "" ) {
root += "/" ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( player . getAttribute ( 'disable-thumbnails' ) == undefined ) {
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
let thumbnails = [ ] ;
const MAX _INDEX = 100 ;
for ( let i = 0 ; i <= MAX _INDEX ; i ++ ) {
thumbnails . push ( root + "miniature-" + ( "" + i ) . padStart ( 3 , "0" ) + ".png" ) ;
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
let thumbnail = new Thumbnail ( player , {
thumbnails ,
width : 192 * 0.75 ,
height : 108 * 0.75 ,
} ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
player . controlBar . progressControl . addChild ( thumbnail ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
player . controlBar . progressControl . el ( ) . addEventListener ( 'mouseenter' , e => {
thumbnail . el ( ) . width = thumbnail . width ;
thumbnail . update ( e . offsetX / e . target . offsetWidth ) ;
} ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
player . controlBar . progressControl . el ( ) . addEventListener ( 'mouseleave' , e => {
thumbnail . el ( ) . width = 0 ;
} ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
player . controlBar . progressControl . on ( 'mousemove' , ( event ) => {
const seekBar = player . controlBar . progressControl . seekBar ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
const seekBarEl = seekBar . el ( ) ;
const seekBarRect = getBoundingClientRect ( seekBarEl ) ;
let seekBarPoint = getPointerPosition ( seekBarEl , event ) . x ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
seekBarPoint = Math . max ( 0 , Math . min ( 1 , seekBarPoint ) ) ;
thumbnail . update ( seekBarPoint ) ;
thumbnail . el ( ) . style . left = ( seekBarPoint * seekBarRect . width - thumbnail . width / 2 ) + "px" ;
} ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
let controlBar = player . getChild ( 'controlBar' ) ;
let fullscreenButton = controlBar . children ( ) [ controlBar . children ( ) . length - 1 ] ;
controlBar . removeChild ( fullscreenButton ) ;
2020-11-05 16:17:05 +01:00
2020-11-05 17:18:16 +01:00
let menuButton = createRepresentationButtons ( player ) ;
let speedButton = createSpeedButtons ( player ) ;
controlBar . addChild ( speedButton , { } ) ;
controlBar . addChild ( menuButton , { } ) ;
controlBar . addChild ( fullscreenButton , { } ) ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
window . player = player ;
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
if ( video . getAttribute ( 'autoplay' ) != undefined ) {
player . play ( ) ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
return player ;
}
for ( let element of document . getElementsByTagName ( 'video' ) ) {
let src = element . getAttribute ( 'data-dash-src' ) ;
if ( src != undefined ) {
vd . setup ( element , src ) ;
2020-10-03 18:44:16 +02:00
}
2020-11-05 17:18:16 +01:00
}
2020-10-03 18:44:16 +02:00
2020-11-05 17:18:16 +01:00
return vd ;
2020-10-03 18:44:16 +02:00
} ) ( ) ;