@@ -79,7 +79,8 @@ function TextTracks(config) {
79
79
displayCCOnTop ,
80
80
previousISDState ,
81
81
topZIndex ,
82
- resizeObserver ;
82
+ resizeObserver ,
83
+ hasRequestAnimationFrame ;
83
84
84
85
function setup ( ) {
85
86
logger = Debug ( context ) . getInstance ( ) . getLogger ( instance ) ;
@@ -104,6 +105,7 @@ function TextTracks(config) {
104
105
displayCCOnTop = false ;
105
106
topZIndex = 2147483647 ;
106
107
previousISDState = null ;
108
+ hasRequestAnimationFrame = ( 'requestAnimationFrame' in window ) ;
107
109
108
110
if ( document . fullscreenElement !== undefined ) {
109
111
fullscreenAttribute = 'fullscreenElement' ; // Standard and Edge
@@ -409,20 +411,19 @@ function TextTracks(config) {
409
411
410
412
function _renderCaption ( cue ) {
411
413
if ( captionContainer ) {
414
+ clearCaptionContainer . call ( this ) ;
415
+
412
416
const finalCue = document . createElement ( 'div' ) ;
413
417
captionContainer . appendChild ( finalCue ) ;
418
+
414
419
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 ,
422
425
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*/ } ,
426
427
previousISDState ,
427
428
settings . get ( ) . streaming . text . imsc . enableRollUp ,
428
429
settings . get ( ) . streaming . text . imsc . options
@@ -432,23 +433,26 @@ function TextTracks(config) {
432
433
}
433
434
}
434
435
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 ) {
440
439
return false ;
441
440
}
442
- const prevCue = track . cues [ track . cues . length - 1 ] ;
443
441
// Check previous cue endTime with current cue startTime
444
442
// (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 ) {
446
449
return false ;
447
450
}
448
- // Compare cues content
451
+
449
452
if ( ! _cuesContentAreEqual ( prevCue , cue , CUE_PROPS_TO_COMPARE ) ) {
450
453
return false ;
451
- }
454
+ }
455
+
452
456
prevCue . endTime = Math . max ( prevCue . endTime , cue . endTime ) ;
453
457
return true ;
454
458
}
@@ -509,7 +513,24 @@ function TextTracks(config) {
509
513
}
510
514
track . manualCueList . push ( cue ) ;
511
515
} 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 {
513
534
track . addCue ( cue ) ;
514
535
}
515
536
}
@@ -560,7 +581,12 @@ function TextTracks(config) {
560
581
cue . onenter = function ( ) {
561
582
if ( track . mode === Constants . TEXT_SHOWING ) {
562
583
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
+ }
564
590
logger . debug ( 'Cue enter id:' + this . cueID ) ;
565
591
} else {
566
592
captionContainer . appendChild ( this . cueHTMLElement ) ;
@@ -573,6 +599,7 @@ function TextTracks(config) {
573
599
}
574
600
} ;
575
601
602
+ // For imsc subs, this could be reassigned to not do anything if there is a cue that immediately follows this one
576
603
cue . onexit = function ( ) {
577
604
if ( captionContainer ) {
578
605
const divs = captionContainer . childNodes ;
0 commit comments