From da67d316052a78de4d7f284c75f3b8e4b9542d21 Mon Sep 17 00:00:00 2001 From: Rob Walch Date: Tue, 3 Dec 2024 15:07:11 -0800 Subject: [PATCH] Fix loading of audio media options with the same URI as the current level (#6887) Resolves #6859 Resolves #6783 (Fixed with #6785 but regressed with #6845) --- src/controller/audio-track-controller.ts | 8 ++++---- src/controller/interstitials-controller.ts | 4 ++++ src/controller/stream-controller.ts | 8 ++++---- src/utils/rendition-helper.ts | 5 +++++ 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/controller/audio-track-controller.ts b/src/controller/audio-track-controller.ts index 6804bcf962e..433fed22b60 100644 --- a/src/controller/audio-track-controller.ts +++ b/src/controller/audio-track-controller.ts @@ -8,6 +8,7 @@ import { findClosestLevelWithAudioGroup, findMatchingOption, matchesOption, + useAlternateAudio, } from '../utils/rendition-helper'; import type Hls from '../hls'; import type { @@ -401,11 +402,10 @@ class AudioTrackController extends BasePlaylistController { if (!this.shouldLoadPlaylist(audioTrack)) { return; } - if (audioTrack.url === this.hls.levels[this.hls.loadLevel]?.uri) { - // Do not load audio rendition with URI matching main variant URI - return; + // Do not load audio rendition with URI matching main variant URI + if (useAlternateAudio(audioTrack.url, this.hls)) { + this.scheduleLoading(audioTrack, hlsUrlParameters); } - this.scheduleLoading(audioTrack, hlsUrlParameters); } protected loadingPlaylist( diff --git a/src/controller/interstitials-controller.ts b/src/controller/interstitials-controller.ts index 69a919d044f..0c23799e989 100644 --- a/src/controller/interstitials-controller.ts +++ b/src/controller/interstitials-controller.ts @@ -1273,6 +1273,10 @@ MediaSource ${JSON.stringify(attachMediaSourceData)} from ${logFromSource}`, } private onLevelUpdated(event: Events.LEVEL_UPDATED, data: LevelUpdatedData) { + if (data.level === -1) { + // level was removed + return; + } const main = this.hls.levels[data.level]; const currentSelection = { ...(this.mediaSelection || this.altSelection), diff --git a/src/controller/stream-controller.ts b/src/controller/stream-controller.ts index e02055a2b74..1c2c6727f82 100644 --- a/src/controller/stream-controller.ts +++ b/src/controller/stream-controller.ts @@ -11,6 +11,7 @@ import { PlaylistContextType, PlaylistLevelType } from '../types/loader'; import { ChunkMetadata } from '../types/transmuxer'; import { BufferHelper } from '../utils/buffer-helper'; import { pickMostCompleteCodecName } from '../utils/codecs'; +import { useAlternateAudio } from '../utils/rendition-helper'; import type { FragmentTracker } from './fragment-tracker'; import type Hls from '../hls'; import type { Fragment, MediaFragment } from '../loader/fragment'; @@ -851,9 +852,10 @@ export default class StreamController event: Events.AUDIO_TRACK_SWITCHING, data: AudioTrackSwitchingData, ) { + const hls = this.hls; // if any URL found on new audio track, it is an alternate audio track const fromAltAudio = this.altAudio === AlternateAudio.SWITCHED; - const altAudio = !!data.url; + const altAudio = useAlternateAudio(data.url, hls); // if we switch on main audio, ensure that main fragment scheduling is synced with media.buffered // don't do anything if we switch to alt audio: audio stream controller is handling it. // we will just have to change buffer scheduling on audioTrackSwitched @@ -878,7 +880,6 @@ export default class StreamController // Reset audio transmuxer so when switching back to main audio we're not still appending where we left off this.resetTransmuxer(); } - const hls = this.hls; // If switching from alt to main audio, flush all audio and trigger track switched if (fromAltAudio) { hls.trigger(Events.BUFFER_FLUSHING, { @@ -898,8 +899,7 @@ export default class StreamController event: Events.AUDIO_TRACK_SWITCHED, data: AudioTrackSwitchedData, ) { - const trackId = data.id; - const altAudio = !!this.hls.audioTracks[trackId].url; + const altAudio = useAlternateAudio(data.url, this.hls); if (altAudio) { const videoBuffer = this.videoBuffer; // if we switched on alternate audio, ensure that main fragment scheduling is synced with video sourcebuffer buffered diff --git a/src/utils/rendition-helper.ts b/src/utils/rendition-helper.ts index ee65e2df8bb..ea3ec2ecebe 100644 --- a/src/utils/rendition-helper.ts +++ b/src/utils/rendition-helper.ts @@ -1,6 +1,7 @@ import { codecsSetSelectionPreferenceValue } from './codecs'; import { getVideoSelectionOptions } from './hdr'; import { logger } from './logger'; +import type Hls from '../hls'; import type { Level, VideoRange } from '../types/level'; import type { AudioSelectionOption, @@ -500,3 +501,7 @@ function searchDownAndUpList( } return -1; } + +export function useAlternateAudio(audioTrackUrl: string, hls: Hls): boolean { + return !!audioTrackUrl && audioTrackUrl !== hls.levels[hls.loadLevel]?.uri; +}