@@ -79,7 +79,8 @@ function TextTracks(config) {
7979 displayCCOnTop ,
8080 previousISDState ,
8181 topZIndex ,
82- resizeObserver ;
82+ resizeObserver ,
83+ hasRequestAnimationFrame ;
8384
8485 function setup ( ) {
8586 logger = Debug ( context ) . getInstance ( ) . getLogger ( instance ) ;
@@ -104,6 +105,7 @@ function TextTracks(config) {
104105 displayCCOnTop = false ;
105106 topZIndex = 2147483647 ;
106107 previousISDState = null ;
108+ hasRequestAnimationFrame = ( 'requestAnimationFrame' in window ) ;
107109
108110 if ( document . fullscreenElement !== undefined ) {
109111 fullscreenAttribute = 'fullscreenElement' ; // Standard and Edge
@@ -409,20 +411,19 @@ function TextTracks(config) {
409411
410412 function _renderCaption ( cue ) {
411413 if ( captionContainer ) {
414+ clearCaptionContainer . call ( this ) ;
415+
412416 const finalCue = document . createElement ( 'div' ) ;
413417 captionContainer . appendChild ( finalCue ) ;
418+
414419 previousISDState = renderHTML (
415- cue . isd ,
416- finalCue ,
417- function ( src ) {
418- return _resolveImageSrc ( cue , src )
419- } ,
420- captionContainer . clientHeight ,
421- captionContainer . clientWidth ,
420+ cue . isd ,
421+ finalCue ,
422+ function ( src ) { return _resolveImageSrc ( cue , src ) } ,
423+ captionContainer . clientHeight ,
424+ captionContainer . clientWidth ,
422425 settings . get ( ) . streaming . text . imsc . displayForcedOnlyMode ,
423- function ( err ) {
424- logger . info ( 'renderCaption :' , err ) /*TODO: add ErrorHandler management*/
425- } ,
426+ function ( err ) { logger . info ( 'renderCaption :' , err ) /*TODO: add ErrorHandler management*/ } ,
426427 previousISDState ,
427428 settings . get ( ) . streaming . text . imsc . enableRollUp ,
428429 settings . get ( ) . streaming . text . imsc . options
@@ -432,23 +433,26 @@ function TextTracks(config) {
432433 }
433434 }
434435
435- function _extendLastCue ( cue , track ) {
436- if ( ! settings . get ( ) . streaming . text . extendSegmentedCues ) {
437- return false ;
438- }
439- if ( ! track . cues || track . cues . length === 0 ) {
436+ // Check that a new cue immediately follows the previous cue
437+ function _areCuesAdjacent ( cue , prevCue ) {
438+ if ( ! prevCue ) {
440439 return false ;
441440 }
442- const prevCue = track . cues [ track . cues . length - 1 ] ;
443441 // Check previous cue endTime with current cue startTime
444442 // (should we consider an epsilon margin? for example to get around rounding issues)
445- if ( prevCue . endTime < cue . startTime ) {
443+ return prevCue . endTime >= cue . startTime ;
444+ }
445+
446+ // Check if cue content is identical. If it is, extend the previous cue.
447+ function _extendLastCue ( cue , prevCue ) {
448+ if ( ! settings . get ( ) . streaming . text . extendSegmentedCues ) {
446449 return false ;
447450 }
448- // Compare cues content
451+
449452 if ( ! _cuesContentAreEqual ( prevCue , cue , CUE_PROPS_TO_COMPARE ) ) {
450453 return false ;
451- }
454+ }
455+
452456 prevCue . endTime = Math . max ( prevCue . endTime , cue . endTime ) ;
453457 return true ;
454458 }
@@ -509,7 +513,24 @@ function TextTracks(config) {
509513 }
510514 track . manualCueList . push ( cue ) ;
511515 } else {
512- if ( ! _extendLastCue ( cue , track ) ) {
516+ // Handle adjacent cues
517+ let prevCue ;
518+ if ( track . cues && track . cues . length !== 0 ) {
519+ prevCue = track . cues [ track . cues . length - 1 ] ;
520+ }
521+
522+ if ( _areCuesAdjacent ( cue , prevCue ) ) {
523+ if ( ! _extendLastCue ( cue , prevCue ) ) {
524+ /* If cues are adjacent but not identical (extended), let the render function of the next cue
525+ * clear up the captionsContainer so removal and appending are instantaneous.
526+ * Only do this for imsc subs (where isd is present).
527+ */
528+ if ( prevCue . isd ) {
529+ prevCue . onexit = function ( ) { } ;
530+ }
531+ track . addCue ( cue ) ;
532+ }
533+ } else {
513534 track . addCue ( cue ) ;
514535 }
515536 }
@@ -560,7 +581,12 @@ function TextTracks(config) {
560581 cue . onenter = function ( ) {
561582 if ( track . mode === Constants . TEXT_SHOWING ) {
562583 if ( this . isd ) {
563- _renderCaption ( this ) ;
584+ if ( hasRequestAnimationFrame ) {
585+ // Ensure everything in _renderCaption happens in the same frame
586+ requestAnimationFrame ( ( ) => _renderCaption ( this ) ) ;
587+ } else {
588+ _renderCaption ( this )
589+ }
564590 logger . debug ( 'Cue enter id:' + this . cueID ) ;
565591 } else {
566592 captionContainer . appendChild ( this . cueHTMLElement ) ;
@@ -573,6 +599,7 @@ function TextTracks(config) {
573599 }
574600 } ;
575601
602+ // For imsc subs, this could be reassigned to not do anything if there is a cue that immediately follows this one
576603 cue . onexit = function ( ) {
577604 if ( captionContainer ) {
578605 const divs = captionContainer . childNodes ;
0 commit comments