diff --git a/src/components/LivePlayer.vue b/src/components/LivePlayer.vue index aab2d3a..52b5caa 100644 --- a/src/components/LivePlayer.vue +++ b/src/components/LivePlayer.vue @@ -70,6 +70,7 @@ let startupRetryTimer = null let startupRetryCount = 0 let startupStartedAt = 0 let activeUrl = '' +let mediaRecoverAttempted = false const playable = computed(() => props.playUrl && !props.playUrl.startsWith('fake://')) const isLiveShell = computed(() => props.active && !playable.value) @@ -128,6 +129,7 @@ function clearMediaListeners() { function destroyPlayer() { clearMediaListeners() + mediaRecoverAttempted = false needsUserPlay.value = false if (hls) { hls.destroy() @@ -259,6 +261,7 @@ async function attachPlayer(url, { seq: existingSeq } = {}) { startupRetryCount = 0 startupStartedAt = Date.now() waitingForStream.value = false + mediaRecoverAttempted = false } activeUrl = url || '' @@ -371,13 +374,17 @@ async function attachPlayer(url, { seq: existingSeq } = {}) { } if (data.type === Hls.ErrorTypes.MEDIA_ERROR) { - try { - console.warn('[live-player] hls media fatal, recover once', data) - hls.recoverMediaError() - return - } catch (recoverErr) { - console.warn('[live-player] hls recover failed', recoverErr) + if (!mediaRecoverAttempted) { + mediaRecoverAttempted = true + try { + console.warn('[live-player] hls media fatal, recover once', data) + hls.recoverMediaError() + return + } catch (recoverErr) { + console.warn('[live-player] hls recover failed', recoverErr) + } } + // already attempted or recover threw → fall through to emitFatal } console.warn('[live-player] hls fatal', data)