diff --git a/src/controller/audio-stream-controller.ts b/src/controller/audio-stream-controller.ts index 2668a54aba6..56e7e74c99b 100644 --- a/src/controller/audio-stream-controller.ts +++ b/src/controller/audio-stream-controller.ts @@ -648,12 +648,7 @@ class AudioStreamController 'Buffer full error also media.currentTime is not buffered, flush audio buffer' ); this.fragCurrent = null; - // flush everything - this.hls.trigger(Events.BUFFER_FLUSHING, { - startOffset: 0, - endOffset: Number.POSITIVE_INFINITY, - type: 'audio', - }); + super.flushMainBuffer(0, Number.POSITIVE_INFINITY, 'audio'); } } break; @@ -824,11 +819,7 @@ class AudioStreamController const { hls, media, trackId } = this; if (media) { this.log('Switching audio track : flushing all audio'); - hls.trigger(Events.BUFFER_FLUSHING, { - startOffset: 0, - endOffset: Number.POSITIVE_INFINITY, - type: 'audio', - }); + super.flushMainBuffer(0, Number.POSITIVE_INFINITY, 'audio'); } this.audioSwitch = false; hls.trigger(Events.AUDIO_TRACK_SWITCHED, { id: trackId }); diff --git a/src/controller/base-stream-controller.ts b/src/controller/base-stream-controller.ts index faaf3710dea..647d9c6a1b3 100644 --- a/src/controller/base-stream-controller.ts +++ b/src/controller/base-stream-controller.ts @@ -184,7 +184,7 @@ export default class BaseStreamController protected onMediaSeeking() { const { config, fragCurrent, media, mediaBuffer, state } = this; - const currentTime = media ? media.currentTime : null; + const currentTime: number = media ? media.currentTime : 0; const bufferInfo = BufferHelper.bufferInfo( mediaBuffer || media, currentTime, @@ -198,13 +198,7 @@ export default class BaseStreamController ); if (state === State.ENDED) { - // if seeking to unbuffered area, clean up fragPrevious - if (!bufferInfo.len) { - this.fragPrevious = null; - this.fragCurrent = null; - } - // switch to IDLE state to check for potential new fragment - this.state = State.IDLE; + this.resetLoadingState(); } else if (fragCurrent && !bufferInfo.len) { // check if we are seeking to a unbuffered area AND if frag loading is in progress const tolerance = config.maxFragLookUpTolerance; @@ -219,10 +213,7 @@ export default class BaseStreamController ); fragCurrent.loader.abort(); } - this.fragCurrent = null; - this.fragPrevious = null; - // switch to IDLE state to load new fragment - this.state = State.IDLE; + this.resetLoadingState(); } } @@ -1185,6 +1176,15 @@ export default class BaseStreamController // (so that we will check against video.buffered ranges in case of alt audio track) const bufferedTimeRanges = BufferHelper.getBuffered(media); this.fragmentTracker.detectEvictedFragments(type, bufferedTimeRanges); + if (this.state === State.ENDED) { + this.resetLoadingState(); + } + } + + protected resetLoadingState() { + this.fragCurrent = null; + this.fragPrevious = null; + this.state = State.IDLE; } protected resetLiveStartWhenNotLoaded(level: number): boolean { @@ -1197,7 +1197,7 @@ export default class BaseStreamController // We can't afford to retry after a delay in a live scenario. Update the start position and return to IDLE. this.startPosition = -1; this.setStartPosition(details, 0); - this.state = State.IDLE; + this.resetLoadingState(); return true; } this.nextLoadPosition = this.startPosition; @@ -1257,9 +1257,7 @@ export default class BaseStreamController this.state = State.PARSED; this.hls.trigger(Events.FRAG_PARSED, { frag, part }); } else { - this.fragCurrent = null; - this.fragPrevious = null; - this.state = State.IDLE; + this.resetLoadingState(); } } diff --git a/src/controller/stream-controller.ts b/src/controller/stream-controller.ts index 5dba9b6e396..3d6a46c6920 100644 --- a/src/controller/stream-controller.ts +++ b/src/controller/stream-controller.ts @@ -738,12 +738,10 @@ export default class StreamController this.log('Switching to main audio track, cancel main fragment load'); fragCurrent.loader.abort(); } - this.fragCurrent = null; - this.fragPrevious = null; // destroy transmuxer to force init segment generation (following audio switch) this.resetTransmuxer(); // switch to IDLE state to load new fragment - this.state = State.IDLE; + this.resetLoadingState(); } else if (this.audioOnly) { // Reset audio transmuxer so when switching back to main audio we're not still appending where we left off this.resetTransmuxer();