From 9d388761b90fb0d764ea9a78c0beb4d65b394dcd Mon Sep 17 00:00:00 2001 From: absidue <48293849+absidue@users.noreply.github.com> Date: Sun, 17 Nov 2024 15:04:17 +0100 Subject: [PATCH 1/3] Better player error handling --- .../ft-shaka-video-player.js | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index 074739caf03a1..4e61bcbb7ab57 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -2147,17 +2147,28 @@ export default defineComponent({ // #endregion keyboard shortcuts + let ignoreErrors = false + /** * @param {shaka.util.Error} error * @param {string} context * @param {object?} details */ function handleError(error, context, details) { + // These two errors are just wrappers around another error, so use the original error instead + // As they can be nested (e.g. multiple googlevideo redirects because the Invidious server was far away from the user) we should pick the inner most one + while (error.code === shaka.util.Error.Code.REQUEST_FILTER_ERROR || error.code === shaka.util.Error.Code.RESPONSE_FILTER_ERROR) { + error = error.data[0] + } + logShakaError(error, context, props.videoId, details) // text related errors aren't serious (captions and seek bar thumbnails), so we should just log them // TODO: consider only emitting when the severity is crititcal? - if (error.category !== shaka.util.Error.Category.TEXT) { + if (!ignoreErrors && error.category !== shaka.util.Error.Category.TEXT) { + // don't react to multiple consecutive errors, otherwise we don't give the format fallback from the previous error a chance to work + ignoreErrors = true + emit('error', error) stopPowerSaveBlocker() @@ -2532,6 +2543,14 @@ export default defineComponent({ * @param {'dash'|'audio'|'legacy'} oldFormat */ async (newFormat, oldFormat) => { + ignoreErrors = true + + try { + await player.unload() + } catch { } + + ignoreErrors = false + // format switch happened before the player loaded, probably because of an error // as there are no previous player settings to restore, we should treat it like this was the original format if (!hasLoaded.value) { @@ -2702,6 +2721,8 @@ export default defineComponent({ * To workaround that we destroy the player first and wait for it to finish before we unmount this component. */ async function destroyPlayer() { + ignoreErrors = true + if (ui) { // destroying the ui also destroys the player await ui.destroy() From 736eb45df949324e61079315db75203a0e01ecb0 Mon Sep 17 00:00:00 2001 From: absidue <48293849+absidue@users.noreply.github.com> Date: Tue, 19 Nov 2024 21:54:02 +0100 Subject: [PATCH 2/3] Fix format switching --- .../ft-shaka-video-player.js | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index 4e61bcbb7ab57..644d25addcea4 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -2545,15 +2545,15 @@ export default defineComponent({ async (newFormat, oldFormat) => { ignoreErrors = true - try { - await player.unload() - } catch { } - - ignoreErrors = false - // format switch happened before the player loaded, probably because of an error // as there are no previous player settings to restore, we should treat it like this was the original format if (!hasLoaded.value) { + try { + await player.unload() + } catch { } + + ignoreErrors = false + player.configure(getPlayerConfig(newFormat, defaultQuality.value === 'auto')) await performFirstLoad() @@ -2616,6 +2616,12 @@ export default defineComponent({ } } + try { + await player.unload() + } catch { } + + ignoreErrors = false + player.configure(getPlayerConfig(newFormat, useAutoQuality)) try { @@ -2653,6 +2659,12 @@ export default defineComponent({ } activeLegacyFormat.value = null } else { + try { + await player.unload() + } catch { } + + ignoreErrors = false + await setLegacyQuality(oldFormat, playbackPosition) } From 6c398cac990bbec4ef35c826fe2128e9e8481fa4 Mon Sep 17 00:00:00 2001 From: absidue <48293849+absidue@users.noreply.github.com> Date: Wed, 20 Nov 2024 21:54:41 +0100 Subject: [PATCH 3/3] Fix legacy quality handling --- .../ft-shaka-video-player.js | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js index 644d25addcea4..a361dd8eba051 100644 --- a/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js +++ b/src/renderer/components/ft-shaka-video-player/ft-shaka-video-player.js @@ -1252,24 +1252,21 @@ export default defineComponent({ } /** - * @param {'dash'|'audio'|null} previousFormat * @param {number|null} playbackPosition + * @param {number|undefined} previousQuality */ - async function setLegacyQuality(previousFormat = null, playbackPosition = null) { + async function setLegacyQuality(playbackPosition = null, previousQuality = undefined) { + if (typeof previousQuality === 'undefined') { + if (defaultQuality.value === 'auto') { + previousQuality = Infinity + } else { + previousQuality = defaultQuality.value + } + } + /** @type {object[]} */ const legacyFormats = props.legacyFormats - let previousQuality - if (previousFormat === 'dash') { - const previousTrack = player.getVariantTracks().find(track => track.active) - - previousQuality = previousTrack.height > previousTrack.width ? previousTrack.width : previousTrack.height - } else if (defaultQuality.value === 'auto') { - previousQuality = Infinity - } else { - previousQuality = defaultQuality.value - } - const isPortrait = legacyFormats[0].height > legacyFormats[0].width let matches = legacyFormats.filter(variant => { @@ -2425,7 +2422,7 @@ export default defineComponent({ handleError(error, 'loading dash/audio manifest and setting default quality in mounted') } } else { - await setLegacyQuality(null, props.startTime) + await setLegacyQuality(props.startTime) } } @@ -2659,13 +2656,21 @@ export default defineComponent({ } activeLegacyFormat.value = null } else { + let previousQuality + + if (oldFormat === 'dash') { + const previousTrack = player.getVariantTracks().find(track => track.active) + + previousQuality = previousTrack.height > previousTrack.width ? previousTrack.width : previousTrack.height + } + try { await player.unload() } catch { } ignoreErrors = false - await setLegacyQuality(oldFormat, playbackPosition) + await setLegacyQuality(playbackPosition, previousQuality) } if (wasPaused) {