From f2fd96aced6cfd9f14d55d997b4228dd56ea6ba2 Mon Sep 17 00:00:00 2001 From: Ivan Schurawel Date: Sun, 12 Feb 2023 17:16:20 -0500 Subject: [PATCH 1/7] fix: clear stuck subtitle track cues --- src/plugins/htmlVideoPlayer/plugin.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index f2a2b8d30b..8902b9cf25 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -620,6 +620,28 @@ function tryRemoveElement(elem) { return relativeOffset; } + /** + * @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. + */ + requiresHidingActiveCuesOnOffsetChange() { + return !!browser.firefox; + } + + /** + * @private + */ + hideTextTrackActiveCues(currentTrack) { + if (currentTrack.activeCues) { + Array.from(currentTrack.activeCues).forEach((cue) => { + cue.text = ''; + }); + } + } + /** * @private */ @@ -629,6 +651,9 @@ function tryRemoveElement(elem) { if (offsetValue === 0) { return; } + if (this.requiresHidingActiveCuesOnOffsetChange()) { + this.hideTextTrackActiveCues(currentTrack); + } Array.from(currentTrack.cues) .forEach(function (cue) { cue.startTime -= offsetValue; From f20ee0b2ea0c486b97dcc1c197ed76b813013e29 Mon Sep 17 00:00:00 2001 From: Ivan Schurawel Date: Tue, 14 Feb 2023 18:43:19 -0500 Subject: [PATCH 2/7] fix: disable track mode to force clear active cues --- src/plugins/htmlVideoPlayer/plugin.js | 48 ++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 8902b9cf25..695829ca2b 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -245,6 +245,12 @@ function tryRemoveElement(elem) { * @type {any | null | undefined} */ #currentSecondaryTrackEvents; + /** + * Used to temporarily store the text track when + * force-clearing the `activeCue` for certain browsers + * @type {TextTrack | null | undefined} + */ + #currentTextTrack; /** * @type {string[] | undefined} */ @@ -624,8 +630,8 @@ 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. + * Any previous text tracks that are on the screen when the offset changes will remain next + * to the new tracks until they reach the end time of the new offset's instance of the track. */ requiresHidingActiveCuesOnOffsetChange() { return !!browser.firefox; @@ -634,11 +640,30 @@ function tryRemoveElement(elem) { /** * @private */ - hideTextTrackActiveCues(currentTrack) { + hideTextTrackWithActiveCues(currentTrack) { if (currentTrack.activeCues) { - Array.from(currentTrack.activeCues).forEach((cue) => { - cue.text = ''; - }); + currentTrack.mode = 'hidden'; + } + } + + /** + * Forces the active cue to clear by disabling then re-enabling the track. + * The track mode is reverted inside of a 0ms timeout to free up the track + * and allow it to disable and clear the active cue. + * The track needs to be temporarily stored in order for us to access it + * inside the timeout. The stored value is reset after it is used. + * @private + */ + forceClearTextTrackActiveCues(currentTrack) { + if (currentTrack.activeCues) { + this.#currentTextTrack = currentTrack; + currentTrack.mode = 'disabled'; + setTimeout(() => { + if (this.#currentTextTrack) { + this.#currentTextTrack.mode = 'showing'; + this.#currentTextTrack = null; + } + }, 0); } } @@ -651,14 +676,21 @@ function tryRemoveElement(elem) { if (offsetValue === 0) { return; } - if (this.requiresHidingActiveCuesOnOffsetChange()) { - this.hideTextTrackActiveCues(currentTrack); + + const shouldClearActiveCues = this.requiresClearingActiveCuesOnOffsetChange(); + if (shouldClearActiveCues) { + this.hideTextTrackWithActiveCues(currentTrack); } + Array.from(currentTrack.cues) .forEach(function (cue) { cue.startTime -= offsetValue; cue.endTime -= offsetValue; }); + + if (shouldClearActiveCues) { + this.forceClearTextTrackActiveCues(currentTrack); + } } } From 2caa2851b9b9a08cafa607cd5d5582a27c3cc5e6 Mon Sep 17 00:00:00 2001 From: Ivan Schurawel <30599893+is343@users.noreply.github.com> Date: Fri, 17 Feb 2023 09:43:04 -0500 Subject: [PATCH 3/7] fix: use correct name Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com> --- src/plugins/htmlVideoPlayer/plugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 695829ca2b..aaf22f759b 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -677,7 +677,7 @@ function tryRemoveElement(elem) { return; } - const shouldClearActiveCues = this.requiresClearingActiveCuesOnOffsetChange(); + const shouldClearActiveCues = this.requiresHidingActiveCuesOnOffsetChange(); if (shouldClearActiveCues) { this.hideTextTrackWithActiveCues(currentTrack); } From 032d03d20135d0cdb357ad6f2dda1603af5ede1e Mon Sep 17 00:00:00 2001 From: Ivan Schurawel Date: Sun, 19 Feb 2023 10:56:10 -0500 Subject: [PATCH 4/7] fix: don't set temp variable --- src/plugins/htmlVideoPlayer/plugin.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index aaf22f759b..7936067145 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -245,12 +245,6 @@ function tryRemoveElement(elem) { * @type {any | null | undefined} */ #currentSecondaryTrackEvents; - /** - * Used to temporarily store the text track when - * force-clearing the `activeCue` for certain browsers - * @type {TextTrack | null | undefined} - */ - #currentTextTrack; /** * @type {string[] | undefined} */ @@ -650,19 +644,13 @@ function tryRemoveElement(elem) { * Forces the active cue to clear by disabling then re-enabling the track. * The track mode is reverted inside of a 0ms timeout to free up the track * and allow it to disable and clear the active cue. - * The track needs to be temporarily stored in order for us to access it - * inside the timeout. The stored value is reset after it is used. * @private */ forceClearTextTrackActiveCues(currentTrack) { if (currentTrack.activeCues) { - this.#currentTextTrack = currentTrack; currentTrack.mode = 'disabled'; setTimeout(() => { - if (this.#currentTextTrack) { - this.#currentTextTrack.mode = 'showing'; - this.#currentTextTrack = null; - } + currentTrack.mode = 'showing'; }, 0); } } From acdbf59b50e7a6d2b0114d490048aee337cfaa1b Mon Sep 17 00:00:00 2001 From: Ivan Schurawel Date: Sun, 19 Feb 2023 17:29:34 -0500 Subject: [PATCH 5/7] chore: add debounce to setSubtitleOffset --- src/plugins/htmlVideoPlayer/plugin.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 7936067145..cef47fe119 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -32,6 +32,7 @@ import { getIncludeCorsCredentials } from '../../scripts/settings/webSettings'; import { setBackdropTransparency, TRANSPARENCY_LEVEL } from '../../components/backdrop/backdrop'; import Events from '../../utils/events.ts'; import { includesAny } from '../../utils/container.ts'; +import debounce from 'lodash-es/debounce'; /** * Returns resolved URL. @@ -571,7 +572,12 @@ function tryRemoveElement(elem) { } } - setSubtitleOffset(offset) { + setSubtitleOffset = debounce(this._setSubtitleOffset, 500); + + /** + * @private + */ + _setSubtitleOffset(offset) { const offsetValue = parseFloat(offset); // if .ass currently rendering From 4c71de481547f61fbb46e5065b895b6ce5a6895b Mon Sep 17 00:00:00 2001 From: Ivan Schurawel Date: Mon, 20 Feb 2023 15:26:17 -0500 Subject: [PATCH 6/7] chore: use smaller debounce time --- src/plugins/htmlVideoPlayer/plugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index cef47fe119..4e120e5f78 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -572,7 +572,7 @@ function tryRemoveElement(elem) { } } - setSubtitleOffset = debounce(this._setSubtitleOffset, 500); + setSubtitleOffset = debounce(this._setSubtitleOffset, 100); /** * @private From c0fc93dedcbdf87c49cef6f4d72817bb5cd57172 Mon Sep 17 00:00:00 2001 From: Ivan Schurawel Date: Tue, 21 Feb 2023 09:12:39 -0500 Subject: [PATCH 7/7] fix: cancel debounce on player unmount --- src/plugins/htmlVideoPlayer/plugin.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 4e120e5f78..8b5afd90d5 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -822,6 +822,8 @@ function tryRemoveElement(elem) { } destroy() { + this.setSubtitleOffset.cancel(); + destroyHlsPlayer(this); destroyFlvPlayer(this);