Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-align audio playlist with main when there is no overlap between audio playlist updates #6857

Merged
merged 5 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 32 additions & 18 deletions src/controller/audio-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { ElementaryStreamTypes, isMediaFragment } from '../loader/fragment';
import { Level } from '../types/level';
import { PlaylistContextType, PlaylistLevelType } from '../types/loader';
import { ChunkMetadata } from '../types/transmuxer';
import { alignMediaPlaylistByPDT } from '../utils/discontinuities';
import {
alignDiscontinuities,
alignMediaPlaylistByPDT,
} from '../utils/discontinuities';
import { mediaAttributesIdentical } from '../utils/media-option-attributes';
import type { FragmentTracker } from './fragment-tracker';
import type Hls from '../hls';
Expand Down Expand Up @@ -257,7 +260,7 @@ class AudioStreamController
this.nextLoadPosition = this.findSyncFrag(videoAnchor).start;
this.clearWaitingFragment();
}
} else if (this.state !== State.STOPPED) {
} else {
this.state = State.IDLE;
}
}
Expand Down Expand Up @@ -508,22 +511,30 @@ class AudioStreamController

private onLevelLoaded(event: Events.LEVEL_LOADED, data: LevelLoadedData) {
this.mainDetails = data.details;
if (this.cachedTrackLoadedData !== null) {
this.hls.trigger(Events.AUDIO_TRACK_LOADED, this.cachedTrackLoadedData);
const cachedTrackLoadedData = this.cachedTrackLoadedData;
if (cachedTrackLoadedData) {
this.cachedTrackLoadedData = null;
this.hls.trigger(Events.AUDIO_TRACK_LOADED, cachedTrackLoadedData);
}
}

private onAudioTrackLoaded(
event: Events.AUDIO_TRACK_LOADED,
data: TrackLoadedData,
) {
if (this.mainDetails == null) {
const { levels } = this;
const { details: newDetails, id: trackId } = data;
if (
this.mainDetails == null ||
this.mainDetails.expired ||
newDetails.endCC > this.mainDetails.endCC
) {
this.cachedTrackLoadedData = data;
if (this.state !== State.STOPPED) {
this.state = State.WAITING_TRACK;
}
return;
}
const { levels } = this;
const { details: newDetails, id: trackId } = data;
if (!levels) {
this.warn(`Audio tracks were reset while loading level ${trackId}`);
return;
Expand All @@ -546,22 +557,23 @@ class AudioStreamController
if (newDetails.deltaUpdateFailed || !mainDetails) {
return;
}
if (
!track.details &&
newDetails.hasProgramDateTime &&
mainDetails.hasProgramDateTime
) {
// Make sure our audio rendition is aligned with the "main" rendition, using
// pdt as our reference times.
alignMediaPlaylistByPDT(newDetails, mainDetails);
sliding = newDetails.fragmentStart;
} else {

if (track.details) {
sliding = this.alignPlaylists(
newDetails,
track.details,
this.levelLastLoaded?.details,
);
}
if (!newDetails.alignedSliding) {
// Align audio rendition with the "main" playlist on discontinuity change
// or program-date-time (PDT)
alignDiscontinuities(newDetails, mainDetails);
if (!newDetails.alignedSliding) {
alignMediaPlaylistByPDT(newDetails, mainDetails);
}
sliding = newDetails.fragmentStart;
}
}
track.details = newDetails;
this.levelLastLoaded = track;
Expand Down Expand Up @@ -665,7 +677,9 @@ class AudioStreamController
complete: false,
});
cache.push(new Uint8Array(payload));
this.state = State.WAITING_INIT_PTS;
if (this.state !== State.STOPPED) {
this.state = State.WAITING_INIT_PTS;
}
}
}

Expand Down
7 changes: 2 additions & 5 deletions src/controller/base-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1593,15 +1593,12 @@ export default class BaseStreamController
const firstLevelLoad = !previousDetails;
const aligned = details.alignedSliding && Number.isFinite(slidingStart);
if (firstLevelLoad || (!aligned && !slidingStart)) {
const { fragPrevious } = this;
alignStream(fragPrevious, switchDetails, details);
alignStream(switchDetails, details);
const alignedSlidingStart = details.fragmentStart;
this.log(
`Live playlist sliding: ${alignedSlidingStart.toFixed(2)} start-sn: ${
previousDetails ? previousDetails.startSN : 'na'
}->${details.startSN} prev-sn: ${
fragPrevious ? fragPrevious.sn : 'na'
} fragments: ${length}`,
}->${details.startSN} fragments: ${length}`,
);
return alignedSlidingStart;
}
Expand Down
4 changes: 2 additions & 2 deletions src/loader/m3u8-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ export default class M3U8Parser {
}

case 'DISCONTINUITY-SEQUENCE':
discontinuityCounter = parseInt(value1);
level.startCC = discontinuityCounter = parseInt(value1);
break;
case 'KEY': {
const levelKey = parseKey(value1, baseurl, level);
Expand Down Expand Up @@ -671,7 +671,7 @@ export default class M3U8Parser {
if (!level.live) {
lastFragment.endList = true;
}
if (firstFragment) {
if (firstFragment && !level.startCC) {
level.startCC = firstFragment.cc;
}
/**
Expand Down
2 changes: 0 additions & 2 deletions src/utils/discontinuities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,10 @@ export function adjustSlidingStart(sliding: number, details: LevelDetails) {
* The PTS of a fragment lets Hls.js know where it fits into a stream - by knowing every PTS, we know which fragment to
* download at any given time. PTS is normally computed when the fragment is demuxed, so taking this step saves us time
* and an extra download.
* @param lastFrag
* @param lastLevel
* @param details
*/
export function alignStream(
lastFrag: Fragment | null,
switchDetails: LevelDetails | undefined,
details: LevelDetails,
) {
Expand Down
4 changes: 3 additions & 1 deletion src/utils/level-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,9 @@ export function mergeDetails(
newDetails.fragments.shift();
}
newDetails.startSN = newDetails.fragments[0].sn;
newDetails.startCC = newDetails.fragments[0].cc;
if (!newDetails.startCC) {
newDetails.startCC = newDetails.fragments[0].cc;
}
} else {
if (newDetails.canSkipDateRanges) {
newDetails.dateRanges = mergeDateRanges(
Expand Down
Loading
Loading