diff --git a/api-extractor/report/hls.js.api.md b/api-extractor/report/hls.js.api.md index 2cc281ae8b5..2ef051373b8 100644 --- a/api-extractor/report/hls.js.api.md +++ b/api-extractor/report/hls.js.api.md @@ -81,6 +81,8 @@ export interface AudioTrackSwitchedData { // // @public (undocumented) export interface AudioTrackSwitchingData { + // (undocumented) + groupId: string; // (undocumented) id: number; // (undocumented) @@ -2007,6 +2009,8 @@ export interface SubtitleTracksUpdatedData { // // @public (undocumented) export interface SubtitleTrackSwitchData { + // (undocumented) + groupId?: string; // (undocumented) id: number; // (undocumented) diff --git a/src/controller/audio-stream-controller.ts b/src/controller/audio-stream-controller.ts index 1170f508ebd..2668a54aba6 100644 --- a/src/controller/audio-stream-controller.ts +++ b/src/controller/audio-stream-controller.ts @@ -7,7 +7,6 @@ import { FragmentState } from './fragment-tracker'; import { Level } from '../types/level'; import { PlaylistLevelType } from '../types/loader'; import { Fragment, ElementaryStreamTypes, Part } from '../loader/fragment'; -import FragmentLoader from '../loader/fragment-loader'; import ChunkCache from '../demux/chunk-cache'; import TransmuxerInterface from '../demux/transmuxer-interface'; import type { TransmuxerResult } from '../types/transmuxer'; @@ -364,6 +363,7 @@ class AudioStreamController event: Events.AUDIO_TRACKS_UPDATED, { audioTracks }: AudioTracksUpdatedData ) { + this.resetTransmuxer(); this.levels = audioTracks.map((mediaPlaylist) => new Level(mediaPlaylist)); } @@ -374,7 +374,7 @@ class AudioStreamController // if any URL found on new audio track, it is an alternate audio track const altAudio = !!data.url; this.trackId = data.id; - const { fragCurrent, transmuxer } = this; + const { fragCurrent } = this; if (fragCurrent?.loader) { fragCurrent.loader.abort(); @@ -383,10 +383,7 @@ class AudioStreamController this.clearWaitingFragment(); // destroy useless transmuxer when switching audio to main if (!altAudio) { - if (transmuxer) { - transmuxer.destroy(); - this.transmuxer = null; - } + this.resetTransmuxer(); } else { // switching to audio track, start timer if not already started this.setInterval(TICK_INTERVAL); diff --git a/src/controller/audio-track-controller.ts b/src/controller/audio-track-controller.ts index 3396b99afad..c06f0d60827 100644 --- a/src/controller/audio-track-controller.ts +++ b/src/controller/audio-track-controller.ts @@ -188,11 +188,17 @@ class AudioTrackController extends BasePlaylistController { const lastTrack = tracks[this.trackId]; this.log(`Now switching to audio-track index ${newId}`); - const { id, name, type, url } = track; + const { id, groupId = '', name, type, url } = track; this.trackId = newId; this.trackName = name; this.selectDefaultTrack = false; - this.hls.trigger(Events.AUDIO_TRACK_SWITCHING, { id, name, type, url }); + this.hls.trigger(Events.AUDIO_TRACK_SWITCHING, { + id, + groupId, + name, + type, + url, + }); const hlsUrlParameters = this.switchParams(track.url, lastTrack?.details); this.loadPlaylist(hlsUrlParameters); } diff --git a/src/controller/base-stream-controller.ts b/src/controller/base-stream-controller.ts index fea77cd1acd..faaf3710dea 100644 --- a/src/controller/base-stream-controller.ts +++ b/src/controller/base-stream-controller.ts @@ -121,10 +121,7 @@ export default class BaseStreamController if (frag) { this.fragmentTracker.removeFragment(frag); } - if (this.transmuxer) { - this.transmuxer.destroy(); - this.transmuxer = null; - } + this.resetTransmuxer(); this.fragCurrent = null; this.fragPrevious = null; this.clearInterval(); @@ -1228,10 +1225,7 @@ export default class BaseStreamController this.warn( `Could not parse fragment ${frag.sn} ${type} duration reliably (${parsedDuration}) resetting transmuxer to fallback to playlist timing` ); - if (this.transmuxer) { - this.transmuxer.destroy(); - this.transmuxer = null; - } + this.resetTransmuxer(); return result || false; } const drift = partial @@ -1269,6 +1263,13 @@ export default class BaseStreamController } } + protected resetTransmuxer() { + if (this.transmuxer) { + this.transmuxer.destroy(); + this.transmuxer = null; + } + } + set state(nextState) { const previousState = this._state; if (previousState !== nextState) { diff --git a/src/controller/stream-controller.ts b/src/controller/stream-controller.ts index 97e5257cbba..5dba9b6e396 100644 --- a/src/controller/stream-controller.ts +++ b/src/controller/stream-controller.ts @@ -715,13 +715,6 @@ export default class StreamController ); } - private resetTransmuxer() { - if (this.transmuxer) { - this.transmuxer.destroy(); - this.transmuxer = null; - } - } - private onAudioTrackSwitching( event: Events.AUDIO_TRACK_SWITCHING, data: AudioTrackSwitchingData diff --git a/src/controller/subtitle-stream-controller.ts b/src/controller/subtitle-stream-controller.ts index 9072ad69cdb..19549e81cff 100644 --- a/src/controller/subtitle-stream-controller.ts +++ b/src/controller/subtitle-stream-controller.ts @@ -5,7 +5,6 @@ import { findFragmentByPDT, findFragmentByPTS } from './fragment-finders'; import type { FragmentTracker } from './fragment-tracker'; import { FragmentState } from './fragment-tracker'; import BaseStreamController, { State } from './base-stream-controller'; -import FragmentLoader from '../loader/fragment-loader'; import { PlaylistLevelType } from '../types/loader'; import { Level } from '../types/level'; import type { NetworkComponentAPI } from '../types/component-api'; diff --git a/src/controller/subtitle-track-controller.ts b/src/controller/subtitle-track-controller.ts index 13250f3210c..473f2520c06 100644 --- a/src/controller/subtitle-track-controller.ts +++ b/src/controller/subtitle-track-controller.ts @@ -354,8 +354,14 @@ class SubtitleTrackController extends BasePlaylistController { this.log(`Switching to subtitle track ${newId}`); this.trackId = newId; if (track) { - const { id, name, type, url } = track; - this.hls.trigger(Events.SUBTITLE_TRACK_SWITCH, { id, name, type, url }); + const { id, groupId = '', name, type, url } = track; + this.hls.trigger(Events.SUBTITLE_TRACK_SWITCH, { + id, + groupId, + name, + type, + url, + }); const hlsUrlParameters = this.switchParams(track.url, lastTrack?.details); this.loadPlaylist(hlsUrlParameters); } else { diff --git a/src/types/events.ts b/src/types/events.ts index 02cb7a12428..fc21d76b892 100644 --- a/src/types/events.ts +++ b/src/types/events.ts @@ -155,6 +155,7 @@ export interface LevelPTSUpdatedData { export interface AudioTrackSwitchingData { id: number; name: string; + groupId: string; type: MediaPlaylistType | 'main'; url: string; } @@ -176,6 +177,7 @@ export interface SubtitleTracksUpdatedData { export interface SubtitleTrackSwitchData { id: number; name?: string; + groupId?: string; type?: MediaPlaylistType | 'main'; url?: string; } diff --git a/tests/unit/controller/subtitle-track-controller.js b/tests/unit/controller/subtitle-track-controller.js index 4a098831ca3..67d794cbf70 100644 --- a/tests/unit/controller/subtitle-track-controller.js +++ b/tests/unit/controller/subtitle-track-controller.js @@ -129,6 +129,7 @@ describe('SubtitleTrackController', function () { 'hlsSubtitleTrackSwitch', { id: 1, + groupId: 'default-text-group', name: 'English', type: 'SUBTITLES', url: 'bar', @@ -164,6 +165,7 @@ describe('SubtitleTrackController', function () { 'hlsSubtitleTrackSwitch', { id: 0, + groupId: 'default-text-group', name: 'English', type: 'SUBTITLES', url: 'baz',