diff --git a/src/composables/useMonitorLive.js b/src/composables/useMonitorLive.js index 4fe4df4..e7fc74b 100644 --- a/src/composables/useMonitorLive.js +++ b/src/composables/useMonitorLive.js @@ -16,6 +16,7 @@ const STOP_TIMEOUT_MS = 60_000 const PLAY_RETRY_MAX = 3 const PLAY_EXPIRE_FALLBACK_SEC = 270 const PLAY_REFRESH_LEAD_MS = 30_000 +const PLAY_URL_FRESH_MS = PLAY_REFRESH_LEAD_MS const LEASE_INVALID_CODE = 57006 function isFatalPlayMediaError(err) { @@ -73,6 +74,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { }) let playURLRequest = null + let playURLRequestSessionId = '' let disposed = false let openGen = 0 let rejoinBusy = false @@ -108,6 +110,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { live.heartbeatTimer = null live.playRefreshTimer = null playURLRequest = null + playURLRequestSessionId = '' live.playUrl = '' live.playUrlExpiresAt = 0 live.playRetryCount = 0 @@ -116,6 +119,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { function resetLocal() { clearTimers() playURLRequest = null + playURLRequestSessionId = '' live.session = null live.dockId = '' live.opening = false @@ -257,10 +261,20 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { // 成功返回 true;失败抛错,由调用方决定是否 onPlayError(避免互相递归) // fromRetry: 播放错误触发的刷新不重置重试计数,避免无限重建 - async function refreshPlayURLOnce({ fromRetry = false } = {}) { + async function refreshPlayURLOnce({ fromRetry = false, force = false } = {}) { if (disposed || live.stopping || !live.dockId || !live.session?.id) return false const dockId = live.dockId const sessionId = live.session.id + const forceFetch = force || fromRetry + + if ( + !forceFetch && + live.playUrl && + live.playUrlExpiresAt * 1000 - Date.now() > PLAY_URL_FRESH_MS + ) { + return true + } + const play = await getLivePlayURL(dockId, sessionId) if (disposed || live.stopping || !live.session || live.session.id !== sessionId) return false live.playUrl = play.playUrl || '' @@ -272,9 +286,28 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { } function refreshPlayURL(options = {}) { - if (playURLRequest) return playURLRequest + const sessionId = live.session?.id + if (!sessionId) return Promise.resolve(false) + + const forceFetch = Boolean(options.force || options.fromRetry) + if ( + !forceFetch && + live.playUrl && + live.playUrlExpiresAt * 1000 - Date.now() > PLAY_URL_FRESH_MS + ) { + return Promise.resolve(true) + } + + if (playURLRequest && playURLRequestSessionId === sessionId) { + return playURLRequest + } + + playURLRequestSessionId = sessionId playURLRequest = refreshPlayURLOnce(options).finally(() => { - playURLRequest = null + if (playURLRequestSessionId === sessionId) { + playURLRequest = null + playURLRequestSessionId = '' + } }) return playURLRequest } @@ -286,7 +319,7 @@ export function useMonitorLive({ getDockId, ui, getLivePlayer }) { const delay = Math.max(5000, live.playUrlExpiresAt * 1000 - Date.now() - PLAY_REFRESH_LEAD_MS) live.playRefreshTimer = window.setTimeout(async () => { try { - await refreshPlayURL() + await refreshPlayURL({ force: true }) } catch (e) { if (disposed || live.stopping) return if (isLeaseInvalidError(e)) {