2018-10-23 01:05:09 +03:00
define ( [ "appSettings" , "browser" , "events" ] , function ( appSettings , browser , events ) {
"use strict" ;
function getSavedVolume ( ) {
return appSettings . get ( "volume" ) || 1
}
function saveVolume ( value ) {
value && appSettings . set ( "volume" , value )
}
function getCrossOriginValue ( mediaSource ) {
return mediaSource . IsRemote ? null : "anonymous"
}
function canPlayNativeHls ( ) {
var media = document . createElement ( "video" ) ;
return ! ( ! media . canPlayType ( "application/x-mpegURL" ) . replace ( /no/ , "" ) && ! media . canPlayType ( "application/vnd.apple.mpegURL" ) . replace ( /no/ , "" ) )
}
function enableHlsShakaPlayer ( item , mediaSource , mediaType ) {
if ( window . MediaSource && MediaSource . isTypeSupported ) {
if ( canPlayNativeHls ( ) ) {
if ( browser . edge && "Video" === mediaType ) return ! 0 ;
mediaSource . RunTimeTicks
}
return ! 0
}
return ! 1
}
function enableHlsJsPlayer ( runTimeTicks , mediaType ) {
if ( null == window . MediaSource ) return ! 1 ;
if ( browser . iOS ) return ! 1 ;
if ( browser . tizen || browser . web0s ) return ! 1 ;
if ( canPlayNativeHls ( ) ) {
if ( browser . android && "Audio" === mediaType ) return ! 0 ;
if ( browser . edge , runTimeTicks ) return ! 1
}
return ! 0
}
function handleHlsJsMediaError ( instance , reject ) {
var hlsPlayer = instance . _hlsPlayer ;
if ( hlsPlayer ) {
var now = Date . now ( ) ;
window . performance && window . performance . now && ( now = performance . now ( ) ) , ! recoverDecodingErrorDate || now - recoverDecodingErrorDate > 3e3 ? ( recoverDecodingErrorDate = now , console . log ( "try to recover media Error ..." ) , hlsPlayer . recoverMediaError ( ) ) : ! recoverSwapAudioCodecDate || now - recoverSwapAudioCodecDate > 3e3 ? ( recoverSwapAudioCodecDate = now , console . log ( "try to swap Audio Codec and recover media Error ..." ) , hlsPlayer . swapAudioCodec ( ) , hlsPlayer . recoverMediaError ( ) ) : ( console . error ( "cannot recover, last media error recovery failed ..." ) , reject ? reject ( ) : onErrorInternal ( instance , "mediadecodeerror" ) )
}
}
function onErrorInternal ( instance , type ) {
instance . destroyCustomTrack && instance . destroyCustomTrack ( instance . _mediaElement ) , events . trigger ( instance , "error" , [ {
type : type
} ] )
}
function isValidDuration ( duration ) {
return ! ( ! duration || isNaN ( duration ) || duration === Number . POSITIVE _INFINITY || duration === Number . NEGATIVE _INFINITY )
}
function setCurrentTimeIfNeeded ( element , seconds , allowance ) {
Math . abs ( ( element . currentTime || 0 ) - seconds ) >= allowance && ( element . currentTime = seconds )
}
function seekOnPlaybackStart ( instance , element , ticks ) {
var seconds = ( ticks || 0 ) / 1e7 ;
if ( seconds ) {
( instance . currentSrc ( ) || "" ) . toLowerCase ( ) ;
setCurrentTimeIfNeeded ( element , seconds , 5 ) , setTimeout ( function ( ) {
setCurrentTimeIfNeeded ( element , seconds , 10 )
} , 2500 )
}
}
function applySrc ( elem , src , options ) {
return window . Windows && options . mediaSource && options . mediaSource . IsLocal ? Windows . Storage . StorageFile . getFileFromPathAsync ( options . url ) . then ( function ( file ) {
var playlist = new Windows . Media . Playback . MediaPlaybackList ,
source1 = Windows . Media . Core . MediaSource . createFromStorageFile ( file ) ,
startTime = ( options . playerStartPositionTicks || 0 ) / 1e4 ;
return playlist . items . append ( new Windows . Media . Playback . MediaPlaybackItem ( source1 , startTime ) ) , elem . src = URL . createObjectURL ( playlist , {
oneTimeOnly : ! 0
} ) , Promise . resolve ( )
} ) : ( elem . src = src , Promise . resolve ( ) )
}
function onSuccessfulPlay ( elem , onErrorFn ) {
elem . addEventListener ( "error" , onErrorFn )
}
function playWithPromise ( elem , onErrorFn ) {
try {
var promise = elem . play ( ) ;
return promise && promise . then ? promise . catch ( function ( e ) {
var errorName = ( e . name || "" ) . toLowerCase ( ) ;
return "notallowederror" === errorName || "aborterror" === errorName ? ( onSuccessfulPlay ( elem , onErrorFn ) , Promise . resolve ( ) ) : Promise . reject ( )
} ) : ( onSuccessfulPlay ( elem , onErrorFn ) , Promise . resolve ( ) )
} catch ( err ) {
return console . log ( "error calling video.play: " + err ) , Promise . reject ( )
}
}
function destroyCastPlayer ( instance ) {
var player = instance . _castPlayer ;
if ( player ) {
try {
player . unload ( )
} catch ( err ) {
console . log ( err )
}
instance . _castPlayer = null
}
}
function destroyShakaPlayer ( instance ) {
var player = instance . _shakaPlayer ;
if ( player ) {
try {
player . destroy ( )
} catch ( err ) {
console . log ( err )
}
instance . _shakaPlayer = null
}
}
function destroyHlsPlayer ( instance ) {
var player = instance . _hlsPlayer ;
if ( player ) {
try {
player . destroy ( )
} catch ( err ) {
console . log ( err )
}
instance . _hlsPlayer = null
}
}
function destroyFlvPlayer ( instance ) {
var player = instance . _flvPlayer ;
if ( player ) {
try {
player . unload ( ) , player . detachMediaElement ( ) , player . destroy ( )
} catch ( err ) {
console . log ( err )
}
instance . _flvPlayer = null
}
}
function bindEventsToHlsPlayer ( instance , hls , elem , onErrorFn , resolve , reject ) {
hls . on ( Hls . Events . MANIFEST _PARSED , function ( ) {
playWithPromise ( elem , onErrorFn ) . then ( resolve , function ( ) {
reject && ( reject ( ) , reject = null )
} )
} ) , hls . on ( Hls . Events . ERROR , function ( event , data ) {
switch ( console . log ( "HLS Error: Type: " + data . type + " Details: " + ( data . details || "" ) + " Fatal: " + ( data . fatal || ! 1 ) ) , data . type ) {
case Hls . ErrorTypes . NETWORK _ERROR :
if ( data . response && data . response . code && data . response . code >= 400 ) return console . log ( "hls.js response error code: " + data . response . code ) , hls . destroy ( ) , void ( reject ? ( reject ( "servererror" ) , reject = null ) : onErrorInternal ( instance , "servererror" ) )
}
if ( data . fatal ) switch ( data . type ) {
case Hls . ErrorTypes . NETWORK _ERROR :
data . response && 0 === data . response . code ? ( console . log ( "hls.js response error code: " + data . response . code ) , hls . destroy ( ) , reject ? ( reject ( "network" ) , reject = null ) : onErrorInternal ( instance , "network" ) ) : ( console . log ( "fatal network error encountered, try to recover" ) , hls . startLoad ( ) ) ;
break ;
case Hls . ErrorTypes . MEDIA _ERROR :
console . log ( "fatal media error encountered, try to recover" ) ;
var currentReject = reject ;
reject = null , handleHlsJsMediaError ( instance , currentReject ) ;
break ;
default :
console . log ( "Cannot recover from hls error - destroy and trigger error" ) , hls . destroy ( ) , reject ? ( reject ( ) , reject = null ) : onErrorInternal ( instance , "mediadecodeerror" )
}
} )
}
function onEndedInternal ( instance , elem , onErrorFn ) {
elem . removeEventListener ( "error" , onErrorFn ) , elem . src = "" , elem . innerHTML = "" , elem . removeAttribute ( "src" ) , destroyHlsPlayer ( instance ) , destroyFlvPlayer ( instance ) , destroyShakaPlayer ( instance ) , destroyCastPlayer ( instance ) ;
var stopInfo = {
src : instance . _currentSrc
} ;
events . trigger ( instance , "stopped" , [ stopInfo ] ) , instance . _currentTime = null , instance . _currentSrc = null , instance . _currentPlayOptions = null
}
function getBufferedRanges ( instance , elem ) {
var offset , ranges = [ ] ,
seekable = elem . buffered || [ ] ,
currentPlayOptions = instance . _currentPlayOptions ;
currentPlayOptions && ( offset = currentPlayOptions . transcodingOffsetTicks ) , offset = offset || 0 ;
for ( var i = 0 , length = seekable . length ; i < length ; i ++ ) {
var start = seekable . start ( i ) ,
end = seekable . end ( i ) ;
isValidDuration ( start ) || ( start = 0 ) , isValidDuration ( end ) ? ranges . push ( {
start : 1e7 * start + offset ,
end : 1e7 * end + offset
} ) : end = 0
}
return ranges
}
var recoverDecodingErrorDate , recoverSwapAudioCodecDate ;
return {
getSavedVolume : getSavedVolume ,
saveVolume : saveVolume ,
enableHlsJsPlayer : enableHlsJsPlayer ,
enableHlsShakaPlayer : enableHlsShakaPlayer ,
handleHlsJsMediaError : handleHlsJsMediaError ,
isValidDuration : isValidDuration ,
onErrorInternal : onErrorInternal ,
seekOnPlaybackStart : seekOnPlaybackStart ,
applySrc : applySrc ,
playWithPromise : playWithPromise ,
destroyHlsPlayer : destroyHlsPlayer ,
destroyFlvPlayer : destroyFlvPlayer ,
destroyCastPlayer : destroyCastPlayer ,
bindEventsToHlsPlayer : bindEventsToHlsPlayer ,
onEndedInternal : onEndedInternal ,
getCrossOriginValue : getCrossOriginValue ,
getBufferedRanges : getBufferedRanges
}
} ) ;