@@ -380,7 +380,7 @@ function StreamProcessor(config) {
380380 return ;
381381 }
382382 // Init segment not in cache, send new request
383- const request = dashHandler ? dashHandler . getInitRequest ( getMediaInfo ( ) , rep ) : null ;
383+ const request = dashHandler ? dashHandler . getInitRequest ( mediaInfo , rep ) : null ;
384384 if ( request ) {
385385 fragmentModel . executeRequest ( request ) ;
386386 } else if ( rescheduleIfNoRequest ) {
@@ -397,58 +397,75 @@ function StreamProcessor(config) {
397397 * @private
398398 */
399399 function _onMediaFragmentNeeded ( e , rescheduleIfNoRequest = true ) {
400-
401- if ( manifestUpdateInProgress ) {
400+ // Don't schedule next fragments while updating manifest or pruning to avoid buffer inconsistencies
401+ if ( manifestUpdateInProgress || bufferController . getIsPruningInProgress ( ) ) {
402402 _noValidRequest ( ) ;
403403 return ;
404404 }
405405
406- let request = null ;
407-
408- // Don't schedule next fragments while pruning to avoid buffer inconsistencies
409- if ( ! bufferController . getIsPruningInProgress ( ) ) {
410- request = _getFragmentRequest ( ) ;
411- if ( request ) {
412- shouldUseExplicitTimeForRequest = false ;
413- if ( ! isNaN ( request . startTime + request . duration ) ) {
414- bufferingTime = request . startTime + request . duration ;
415- }
416- request . delayLoadingTime = new Date ( ) . getTime ( ) + scheduleController . getTimeToLoadDelay ( ) ;
417- scheduleController . setTimeToLoadDelay ( 0 ) ;
418- }
406+ let request = _getFragmentRequest ( ) ;
407+ if ( request ) {
408+ shouldUseExplicitTimeForRequest = false ;
409+ _mediaRequestGenerated ( request ) ;
410+ } else {
411+ _noMediaRequestGenerated ( rescheduleIfNoRequest ) ;
419412 }
413+ }
420414
421- if ( request ) {
422- if ( ! _shouldIgnoreRequest ( request ) ) {
423- logger . debug ( `Next fragment request url for stream id ${ streamInfo . id } and media type ${ type } is ${ request . url } ` ) ;
424- fragmentModel . executeRequest ( request ) ;
425- } else {
426- logger . warn ( `Fragment request url ${ request . url } for stream id ${ streamInfo . id } and media type ${ type } is on the ignore list and will be skipped` ) ;
427- _noValidRequest ( ) ;
428- }
415+ /**
416+ * If we generated a valid media request we can execute the request. In some cases the segment might be blacklisted.
417+ * @param { object } request
418+ * @private
419+ */
420+ function _mediaRequestGenerated ( request ) {
421+ if ( ! isNaN ( request . startTime + request . duration ) ) {
422+ bufferingTime = request . startTime + request . duration ;
429423 }
430- else {
431- // Check if the media is finished. If so, no need to schedule another request
432- const representation = representationController . getCurrentRepresentation ( ) ;
433- const isLastSegmentRequested = dashHandler . isLastSegmentRequested ( representation , bufferingTime ) ;
434-
435- if ( isLastSegmentRequested ) {
436- const segmentIndex = dashHandler . getCurrentIndex ( ) ;
437- logger . debug ( `Segment requesting for stream ${ streamInfo . id } has finished` ) ;
438- eventBus . trigger ( Events . STREAM_REQUESTING_COMPLETED , { segmentIndex } , {
439- streamId : streamInfo . id ,
440- mediaType : type
441- } ) ;
442- bufferController . segmentRequestingCompleted ( segmentIndex ) ;
443- scheduleController . clearScheduleTimer ( ) ;
424+ request . delayLoadingTime = new Date ( ) . getTime ( ) + scheduleController . getTimeToLoadDelay ( ) ;
425+ scheduleController . setTimeToLoadDelay ( 0 ) ;
426+ if ( ! _shouldIgnoreRequest ( request ) ) {
427+ logger . debug ( `Next fragment request url for stream id ${ streamInfo . id } and media type ${ type } is ${ request . url } ` ) ;
428+ fragmentModel . executeRequest ( request ) ;
429+ } else {
430+ logger . warn ( `Fragment request url ${ request . url } for stream id ${ streamInfo . id } and media type ${ type } is on the ignore list and will be skipped` ) ;
431+ _noValidRequest ( ) ;
432+ }
433+ }
434+
435+ /**
436+ * We could not generate a valid request. Check if the media is finished, we are stuck in a gap or simply need to wait for the next segment to be available.
437+ * @param {boolean } rescheduleIfNoRequest
438+ * @private
439+ */
440+ function _noMediaRequestGenerated ( rescheduleIfNoRequest ) {
441+ const representation = representationController . getCurrentRepresentation ( ) ;
442+
443+ // If this statement is true we are stuck. A static manifest does not change and we did not find a valid request for the target time
444+ // There is no point in trying again. We need to adjust the time in order to find a valid request. This can happen if the user/app seeked into a gap.
445+ if ( settings . get ( ) . streaming . buffer . seekGapFix . enabled && ! isDynamic && shouldUseExplicitTimeForRequest && playbackController . isSeeking ( ) ) {
446+ const adjustedTime = dashHandler . getValidSeekTimeCloseToTargetTime ( bufferingTime , mediaInfo , representation , settings . get ( ) . streaming . buffer . seekGapFix . threshold ) ;
447+ if ( ! isNaN ( adjustedTime ) ) {
448+ playbackController . seek ( adjustedTime , false , false ) ;
444449 return ;
445450 }
451+ }
446452
447- // Reschedule
448- if ( rescheduleIfNoRequest ) {
449- // Use case - Playing at the bleeding live edge and frag is not available yet. Cycle back around.
450- _noValidRequest ( ) ;
451- }
453+ // Check if the media is finished. If so, no need to schedule another request
454+ const isLastSegmentRequested = dashHandler . isLastSegmentRequested ( representation , bufferingTime ) ;
455+ if ( isLastSegmentRequested ) {
456+ const segmentIndex = dashHandler . getCurrentIndex ( ) ;
457+ logger . debug ( `Segment requesting for stream ${ streamInfo . id } has finished` ) ;
458+ eventBus . trigger ( Events . STREAM_REQUESTING_COMPLETED , { segmentIndex } , {
459+ streamId : streamInfo . id ,
460+ mediaType : type
461+ } ) ;
462+ bufferController . segmentRequestingCompleted ( segmentIndex ) ;
463+ scheduleController . clearScheduleTimer ( ) ;
464+ return ;
465+ }
466+
467+ if ( rescheduleIfNoRequest ) {
468+ _noValidRequest ( ) ;
452469 }
453470 }
454471
@@ -486,9 +503,9 @@ function StreamProcessor(config) {
486503 const representation = representationController && representationInfo ? representationController . getRepresentationForQuality ( representationInfo . quality ) : null ;
487504
488505 if ( useTime ) {
489- request = dashHandler . getSegmentRequestForTime ( getMediaInfo ( ) , representation , bufferingTime ) ;
506+ request = dashHandler . getSegmentRequestForTime ( mediaInfo , representation , bufferingTime ) ;
490507 } else {
491- request = dashHandler . getNextSegmentRequest ( getMediaInfo ( ) , representation ) ;
508+ request = dashHandler . getNextSegmentRequest ( mediaInfo , representation ) ;
492509 }
493510 }
494511
@@ -918,7 +935,7 @@ function StreamProcessor(config) {
918935 representationController . getRepresentationForQuality ( representationInfo . quality ) : null ;
919936
920937 let request = dashHandler . getNextSegmentRequestIdempotent (
921- getMediaInfo ( ) ,
938+ mediaInfo ,
922939 representation
923940 ) ;
924941
0 commit comments