diff --git a/src/composables/useMonitorLive.js b/src/composables/useMonitorLive.js index bfd9d37..2cdc8b6 100644 --- a/src/composables/useMonitorLive.js +++ b/src/composables/useMonitorLive.js @@ -141,7 +141,8 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { } // 成功返回 true;失败抛错,由调用方决定是否 onPlayError(避免互相递归) - async function refreshPlayURL() { + // fromRetry: 播放错误触发的刷新不重置重试计数,避免无限重建 + async function refreshPlayURL({ fromRetry = false } = {}) { if (!live.dockId || !live.session?.id) return false const sessionId = live.session.id const play = await getLivePlayURL(live.dockId, sessionId) @@ -149,7 +150,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { live.playUrl = play.playUrl || '' const nowSec = Math.floor(Date.now() / 1000) live.playUrlExpiresAt = Number(play.expiresAt) || nowSec + PLAY_EXPIRE_FALLBACK_SEC - live.playRetryCount = 0 + if (!fromRetry) live.playRetryCount = 0 schedulePlayRefresh() return true } @@ -172,9 +173,11 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { const delay = Math.max(5000, (Number(expiresAt) * 1000 - Date.now()) / 2) live.heartbeatTimer = window.setTimeout(async () => { if (!live.dockId || !live.session?.id) return + const dockId = live.dockId + const sessionId = live.session.id try { - const result = await heartbeatLive(live.dockId, live.session.id) - if (!live.session) return + const result = await heartbeatLive(dockId, sessionId) + if (!live.session || live.session.id !== sessionId || live.dockId !== dockId) return live.session = result.session scheduleLiveHeartbeat(result.leaseExpiresAt) if (result.session.phase === 'streaming' && !live.playUrl) { @@ -185,6 +188,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { } } } catch (e) { + if (!live.session || live.session.id !== sessionId || live.dockId !== dockId) return ui.toast(e.message || '直播观看已结束') await closeLive(false) } @@ -200,7 +204,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { } live.playRetryCount += 1 try { - await refreshPlayURL() + await refreshPlayURL({ fromRetry: true }) } catch (e) { if (live.playRetryCount >= PLAY_RETRY_MAX) { ui.toast(e?.message || err?.message || '播放失败') @@ -232,6 +236,8 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { ['确认停止推流', '影响当前所有观看者'] ) if (!ok) return + // confirm 期间可能已关闭/切换会话,避免 stop 错 dock 或 wipe 新会话 + if (!live.session || live.dockId !== dockId || live.session.id !== session.id) return try { await stopLive(dockId) resetLocal()