diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js
index 3766624d68..5b9fb3d471 100644
--- a/src/plugins/htmlVideoPlayer/plugin.js
+++ b/src/plugins/htmlVideoPlayer/plugin.js
@@ -533,7 +533,7 @@ function tryRemoveElement(elem) {
/**
* @private
*/
- getTextTrack() {
+ getTextTracks() {
const videoElement = this.#mediaElement;
if (videoElement) {
return Array.from(videoElement.textTracks)
@@ -546,9 +546,6 @@ function tryRemoveElement(elem) {
}
}
- /**
- * @private
- */
setSubtitleOffset(offset) {
const offsetValue = parseFloat(offset);
@@ -557,12 +554,13 @@ function tryRemoveElement(elem) {
this.updateCurrentTrackOffset(offsetValue);
this.#currentSubtitlesOctopus.timeOffset = (this._currentPlayOptions.transcodingOffsetTicks || 0) / 10000000 + offsetValue;
} else {
- const trackElement = this.getTextTrack();
+ const trackElements = this.getTextTracks();
// if .vtt currently rendering
- if (trackElement) {
- this.setTextTrackSubtitleOffset(trackElement, offsetValue);
- } else if (this.#currentTrackEvents) {
- this.setTrackEventsSubtitleOffset(this.#currentTrackEvents, offsetValue);
+ if (trackElements.length > 0) {
+ trackElements.forEach((trackElement, index) => this.setTextTrackSubtitleOffset(trackElement, offsetValue, index));
+ } else if (this.#currentTrackEvents || this.#currentSecondaryTrackEvents) {
+ this.#currentTrackEvents && this.setTrackEventsSubtitleOffset(this.#currentTrackEvents, offsetValue, this._PRIMARY_TEXT_TRACK_INDEX);
+ this.#currentSecondaryTrackEvents && this.setTrackEventsSubtitleOffset(this.#currentSecondaryTrackEvents, offsetValue, this._SECONDARY_TEXT_TRACK_INDEX);
} else {
console.debug('No available track, cannot apply offset: ', offsetValue);
}
@@ -572,10 +570,21 @@ function tryRemoveElement(elem) {
/**
* @private
*/
- updateCurrentTrackOffset(offsetValue) {
+ updateCurrentTrackOffset(offsetValue, currentTrackIndex = 0) {
+ const skipRelativeOffset = currentTrackIndex !== this._PRIMARY_TEXT_TRACK_INDEX;
let relativeOffset = offsetValue;
const newTrackOffset = offsetValue;
- if (this.#currentTrackOffset) {
+ if (this.#currentTrackOffset && !skipRelativeOffset) {
+ /**
+ * Only calculate the offset for the first track.
+ * The offset gets set after this method is first called.
+ * Subsequent method calls (when playing multiple tracks)
+ * will have the calculated relative offset cancel out
+ * and will be `0`
+ * @example
+ * first_call: (relativeOffset = -2) -= (this.#currentTrackOffset = -1) -> 1
+ * second_call: (relativeOffset = -2) -= (this.#currentTrackOffset = -2) -> 0
+ */
relativeOffset -= this.#currentTrackOffset;
}
this.#currentTrackOffset = newTrackOffset;
@@ -585,10 +594,41 @@ function tryRemoveElement(elem) {
/**
* @private
+ * These browsers will not clear the existing active cue when setting an offset
+ * for native TextTracks.
+ * Any previous text tracks that are on the screen when the offset changes will
+ * remain next to the new tracks until they reach the new offset's instance of the track.
*/
- setTextTrackSubtitleOffset(currentTrack, offsetValue) {
+ requiresHidingActiveCuesOnOffsetChange() {
+ if (browser.firefox) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * @private
+ */
+ hideTextTrackActiveCues(currentTrack) {
+ if (currentTrack.activeCues) {
+ Array.from(currentTrack.activeCues).forEach((cue) => {
+ cue.text = '';
+ });
+ }
+ }
+
+ /**
+ * @private
+ */
+ setTextTrackSubtitleOffset(currentTrack, offsetValue, currentTrackIndex) {
if (currentTrack.cues) {
- offsetValue = this.updateCurrentTrackOffset(offsetValue);
+ offsetValue = this.updateCurrentTrackOffset(offsetValue, currentTrackIndex);
+ if (offsetValue === 0) {
+ return;
+ }
+ if (this.requiresHidingActiveCuesOnOffsetChange()) {
+ this.hideTextTrackActiveCues(currentTrack);
+ }
Array.from(currentTrack.cues)
.forEach(function (cue) {
cue.startTime -= offsetValue;
@@ -600,9 +640,12 @@ function tryRemoveElement(elem) {
/**
* @private
*/
- setTrackEventsSubtitleOffset(trackEvents, offsetValue) {
+ setTrackEventsSubtitleOffset(trackEvents, offsetValue, currentTrackIndex) {
if (Array.isArray(trackEvents)) {
- offsetValue = this.updateCurrentTrackOffset(offsetValue) * 1e7; // ticks
+ offsetValue = this.updateCurrentTrackOffset(offsetValue, currentTrackIndex) * 1e7; // ticks
+ if (offsetValue === 0) {
+ return;
+ }
trackEvents.forEach(function (trackEvent) {
trackEvent.StartPositionTicks -= offsetValue;
trackEvent.EndPositionTicks -= offsetValue;