Skip to content

Commit 04d53f3

Browse files
Merge pull request #105 from bbc/port-pr-4359-subs-flickering
Port Subtitle Changes from v4.7.4 (Dash-Industry-Forum#4359)
2 parents 4bb6804 + f735d34 commit 04d53f3

File tree

1 file changed

+49
-22
lines changed

1 file changed

+49
-22
lines changed

src/streaming/text/TextTracks.js

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)