@@ -139,7 +139,7 @@ function StreamController() {
139139 function registerEvents ( ) {
140140 eventBus . on ( Events . PLAYBACK_TIME_UPDATED , onPlaybackTimeUpdated , this ) ;
141141 eventBus . on ( Events . PLAYBACK_SEEKING , onPlaybackSeeking , this ) ;
142- eventBus . on ( Events . GAP_CAUSED_PLAYBACK_SEEK , onGapCausedPlaybackSeek , this ) ;
142+ eventBus . on ( Events . GAP_CAUSED_SEEK_TO_PERIOD_END , onGapCausedPlaybackSeek , this ) ;
143143 eventBus . on ( Events . PLAYBACK_ERROR , onPlaybackError , this ) ;
144144 eventBus . on ( Events . PLAYBACK_STARTED , onPlaybackStarted , this ) ;
145145 eventBus . on ( Events . PLAYBACK_PAUSED , onPlaybackPaused , this ) ;
@@ -154,7 +154,7 @@ function StreamController() {
154154 function unRegisterEvents ( ) {
155155 eventBus . off ( Events . PLAYBACK_TIME_UPDATED , onPlaybackTimeUpdated , this ) ;
156156 eventBus . off ( Events . PLAYBACK_SEEKING , onPlaybackSeeking , this ) ;
157- eventBus . off ( Events . GAP_CAUSED_PLAYBACK_SEEK , onGapCausedPlaybackSeek , this ) ;
157+ eventBus . off ( Events . GAP_CAUSED_SEEK_TO_PERIOD_END , onGapCausedPlaybackSeek , this ) ;
158158 eventBus . off ( Events . PLAYBACK_ERROR , onPlaybackError , this ) ;
159159 eventBus . off ( Events . PLAYBACK_STARTED , onPlaybackStarted , this ) ;
160160 eventBus . off ( Events . PLAYBACK_PAUSED , onPlaybackPaused , this ) ;
@@ -331,14 +331,22 @@ function StreamController() {
331331 }
332332 }
333333
334+ function canSourceBuffersBeReused ( nextStream , previousStream ) {
335+ try {
336+ return ( previousStream . isProtectionCompatible ( nextStream , previousStream ) &&
337+ ( supportsChangeType || previousStream . isMediaCodecCompatible ( nextStream , previousStream ) ) && ! hasCriticalTexttracks ( nextStream ) ) ;
338+ } catch ( e ) {
339+ return false ;
340+ }
341+ }
342+
334343 function onStreamCanLoadNext ( nextStream , previousStream = null ) {
335344
336345 if ( mediaSource && ! nextStream . getPreloaded ( ) ) {
337346 // Seamless period switch allowed only if:
338347 // - none of the periods uses contentProtection.
339348 // - AND changeType method implemented by browser or periods use the same codec.
340- let seamlessPeriodSwitch = previousStream . isProtectionCompatible ( nextStream , previousStream ) &&
341- ( supportsChangeType || previousStream . isMediaCodecCompatible ( nextStream , previousStream ) ) && ! hasCriticalTexttracks ( nextStream ) ;
349+ let seamlessPeriodSwitch = canSourceBuffersBeReused ( nextStream , previousStream ) ;
342350
343351 if ( seamlessPeriodSwitch ) {
344352 nextStream . setPreloadingScheduled ( true ) ;
@@ -505,7 +513,6 @@ function StreamController() {
505513 function switchStream ( stream , previousStream , seekTime ) {
506514
507515 if ( isStreamSwitchingInProgress || ! stream || ( previousStream === stream && stream . isActive ( ) ) ) return ;
508- logger . info ( 'Switch stream to ' + stream . getId ( ) + ' at t=' + seekTime ) ;
509516 isStreamSwitchingInProgress = true ;
510517
511518 eventBus . trigger ( Events . PERIOD_SWITCH_STARTED , {
@@ -515,23 +522,23 @@ function StreamController() {
515522
516523 let seamlessPeriodSwitch = false ;
517524 if ( previousStream ) {
518- seamlessPeriodSwitch = ( activeStream . isProtectionCompatible ( stream , previousStream ) &&
519- ( supportsChangeType || activeStream . isMediaCodecCompatible ( stream , previousStream ) ) && ( isNaN ( seekTime ) || stream . getPreloaded ( ) ) && ! hasCriticalTexttracks ( stream ) ) ;
525+ seamlessPeriodSwitch = canSourceBuffersBeReused ( stream , previousStream ) ;
520526 previousStream . deactivate ( seamlessPeriodSwitch ) ;
521527 }
522528
523529 // Determine seek time when switching to new period
524530 // - seek at given seek time
525- // - or seek at period start if seamless period switching
531+ // - or seek at period start if upcoming period is not prebuffered
526532 seekTime = ! isNaN ( seekTime ) ? seekTime : ( ! seamlessPeriodSwitch && previousStream ? stream . getStreamInfo ( ) . start : NaN ) ;
533+ logger . info ( `Switch to stream ${ stream . getId ( ) } . Seektime is ${ seekTime } , current playback time is ${ playbackController . getTime ( ) } ` ) ;
534+ logger . info ( `Seamless period switch is set to ${ seamlessPeriodSwitch } ` ) ;
527535
528536 activeStream = stream ;
529537 preloadingStreams = preloadingStreams . filter ( ( s ) => {
530538 return s . getId ( ) !== activeStream . getId ( ) ;
531539 } ) ;
532540 playbackController . initialize ( getActiveStreamInfo ( ) , ! ! previousStream , seekTime ) ;
533541 if ( videoModel . getElement ( ) ) {
534- //TODO detect if we should close jump to activateStream.
535542 openMediaSource ( seekTime , ( previousStream === null ) , false , seamlessPeriodSwitch ) ;
536543 } else {
537544 activateStream ( seekTime , seamlessPeriodSwitch ) ;
@@ -551,7 +558,7 @@ function StreamController() {
551558
552559 function onMediaSourceOpen ( ) {
553560 // Manage situations in which a call to reset happens while MediaSource is being opened
554- if ( ! mediaSource || mediaSource . readyState != 'open' ) return ;
561+ if ( ! mediaSource || mediaSource . readyState !== 'open' ) return ;
555562
556563 logger . debug ( 'MediaSource is open!' ) ;
557564 window . URL . revokeObjectURL ( sourceUrl ) ;
@@ -603,21 +610,18 @@ function StreamController() {
603610 if ( buffers ) {
604611 const keys = Object . keys ( buffers ) ;
605612 if ( keys . length > 0 && buffers [ keys [ 0 ] ] . changeType ) {
606- logger . debug ( 'SourceBuffer changeType method supported. Use it to switch codecs in periods transitions' ) ;
607613 supportsChangeType = true ;
608614 }
609615 }
610616
611617 if ( ! initialPlayback ) {
612618 if ( ! isNaN ( seekTime ) ) {
613- playbackController . seek ( seekTime ) ; //we only need to call seek here, bufferingTime was set from seeking event
614- } else {
615- // let startTime = playbackController.getStreamStartTime(true);
616- // if (!keepBuffers) {
617- // getActiveStreamProcessors().forEach(p => {
618- // p.setBufferingTime(startTime);
619- // });
620- // }
619+ // If the streamswitch has been triggered by a seek command there is no need to seek again. Still we need to trigger the seeking event in order for the controllers to adjust the new time
620+ if ( seekTime === playbackController . getTime ( ) ) {
621+ eventBus . trigger ( Events . SEEK_TARGET , { time : seekTime , streamId : activeStream . getId ( ) } ) ;
622+ } else {
623+ playbackController . seek ( seekTime ) ;
624+ }
621625 }
622626 }
623627
@@ -734,7 +738,8 @@ function StreamController() {
734738 logger . debug ( 'Dynamic stream: Trying to find the correct starting period' ) ;
735739 initialStream = getInitialStream ( ) ;
736740 }
737- switchStream ( initialStream !== null ? initialStream : streams [ 0 ] , null , NaN ) ;
741+ const startStream = initialStream !== null ? initialStream : streams [ 0 ] ;
742+ switchStream ( startStream , null , NaN ) ;
738743 startPlaybackEndedTimerInterval ( ) ;
739744 startCheckIfPrebufferingCanStartInterval ( ) ;
740745 }
0 commit comments