From 3ab014a38b2ed121e0fc45ed40bf8061618d792d Mon Sep 17 00:00:00 2001 From: Rob Walch Date: Tue, 10 Dec 2024 15:22:35 -0800 Subject: [PATCH] Fix transfer media failing when MediaSource readyState is "ended" --- src/controller/buffer-controller.ts | 35 +++++++++++++++++------------ 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/controller/buffer-controller.ts b/src/controller/buffer-controller.ts index 96eec7dd109..02b2d5c0a1c 100755 --- a/src/controller/buffer-controller.ts +++ b/src/controller/buffer-controller.ts @@ -340,11 +340,8 @@ export default class BufferController extends Logger implements ComponentAPI { : null; const trackCount = trackNames ? trackNames.length : 0; const mediaSourceOpenCallback = () => { - if (this.media) { - const readyState = this.mediaSource?.readyState; - if (readyState === 'open' || readyState === 'ended') { - this._onMediaSourceOpen(); - } + if (this.media && this.mediaSourceOpenOrEnded) { + this._onMediaSourceOpen(); } }; if (transferredTracks && trackNames && trackCount) { @@ -429,6 +426,11 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i } } + private get mediaSourceOpenOrEnded(): boolean { + const readyState = this.mediaSource?.readyState; + return readyState === 'open' || readyState === 'ended'; + } + private _onEndStreaming = (event) => { if (!this.hls) { return; @@ -466,18 +468,23 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i }); this.resetQueue(); } else { - if (mediaSource.readyState === 'open') { + if (this.mediaSourceOpenOrEnded) { + const open = mediaSource.readyState === 'open'; try { const sourceBuffers = mediaSource.sourceBuffers; for (let i = sourceBuffers.length; i--; ) { - sourceBuffers[i].abort(); + if (open) { + sourceBuffers[i].abort(); + } mediaSource.removeSourceBuffer(sourceBuffers[i]); } - // endOfStream could trigger exception if any sourcebuffer is in updating state - // we don't really care about checking sourcebuffer state here, - // as we are anyway detaching the MediaSource - // let's just avoid this exception to propagate - mediaSource.endOfStream(); + if (open) { + // endOfStream could trigger exception if any sourcebuffer is in updating state + // we don't really care about checking sourcebuffer state here, + // as we are anyway detaching the MediaSource + // let's just avoid this exception to propagate + mediaSource.endOfStream(); + } } catch (err) { this.warn( `onMediaDetaching: ${err.message} while calling endOfStream`, @@ -651,7 +658,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i if (this.sourceBufferCount) { return; } - if (this.mediaSource !== null && this.mediaSource.readyState === 'open') { + if (this.mediaSourceOpenOrEnded) { this.checkPendingTracks(); } } @@ -892,7 +899,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i event.details = ErrorDetails.BUFFER_FULL_ERROR; } else if ( (error as DOMException).code === DOMException.INVALID_STATE_ERR && - this.mediaSource?.readyState === 'open' && + this.mediaSourceOpenOrEnded && !this.media?.error ) { // Allow retry for "Failed to execute 'appendBuffer' on 'SourceBuffer': This SourceBuffer is still processing" errors