Skip to content

Commit

Permalink
Fallback to primary when Interstitial DateRange is removed while playing
Browse files Browse the repository at this point in the history
Resolves #6765
Resolves regression in dev starting live interstitials from media playlist (no multivariant playlist loaded startup sequence changed)
  • Loading branch information
robwalch committed Dec 6, 2024
1 parent 93dfd4f commit 88be787
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 35 deletions.
2 changes: 0 additions & 2 deletions api-extractor/report/hls.js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3646,8 +3646,6 @@ export interface ManifestLoadedData {
// (undocumented)
contentSteering: ContentSteeringOptions | null;
// (undocumented)
isMediaPlaylist?: boolean;
// (undocumented)
levels: LevelParsed[];
// (undocumented)
networkDetails: any;
Expand Down
43 changes: 27 additions & 16 deletions src/controller/interstitials-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1151,9 +1151,6 @@ MediaSource ${JSON.stringify(attachMediaSourceData)} from ${logFromSource}`,
this.waitingItem = null;

this.bufferedToItem(scheduledItem);
if (!fromItem) {
return;
}

this.log(`resuming ${segmentToString(scheduledItem)}`);

Expand All @@ -1169,6 +1166,10 @@ MediaSource ${JSON.stringify(attachMediaSourceData)} from ${logFromSource}`,
this.attachPrimary(timelinePos, scheduledItem);
}

if (!fromItem) {
return;
}

const scheduleItems = this.schedule.items;
if (!scheduleItems) {
return;
Expand Down Expand Up @@ -1434,14 +1435,6 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))}`,
if (removedIds.length) {
this.log(`Removed events ${removedIds}`);
}
if (
this.isInterstitial(playingItem) &&
removedIds.includes(playingItem.event.identifier)
) {
this.warn(
`Interstitial "${playingItem.event.identifier}" removed while playing`,
);
}

this.playerQueue.forEach((player) => {
if (player.interstitial.appendInPlace) {
Expand Down Expand Up @@ -1474,15 +1467,15 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))}`,
} else if (!this.updateItem(bufferingItem)) {
// Interstitial removed from schedule (Live -> VOD or other scenario where Start Date is outside the range of VOD Playlist)
this.bufferingItem = null;
this.clearInterstitial(bufferingItem.event);
this.clearInterstitial(bufferingItem.event, null);
}
}
// Clear waitingItem if it has been removed from the schedule
this.waitingItem = this.updateItem(this.waitingItem);

removedInterstitials.forEach((interstitial) => {
interstitial.assetList.forEach((asset) => {
this.clearAssetPlayer(asset.identifier);
this.clearAssetPlayer(asset.identifier, null);
});
});

Expand All @@ -1494,6 +1487,17 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))}`,
removedIds,
});

if (
this.isInterstitial(playingItem) &&
removedIds.includes(playingItem.event.identifier)
) {
this.warn(
`Interstitial "${playingItem.event.identifier}" removed while playing`,
);
this.primaryFallback(playingItem.event);
return;
}

// Check is buffered to new Interstitial event boundary
// (Live update publishes Interstitial with new segment)
this.checkBuffer();
Expand Down Expand Up @@ -2065,7 +2069,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))}`,

private clearInterstitial(
interstitial: InterstitialEvent,
toSegment?: InterstitialScheduleItem | null,
toSegment: InterstitialScheduleItem | null,
) {
interstitial.assetList.forEach((asset) => {
this.clearAssetPlayer(asset.identifier, toSegment);
Expand All @@ -2075,7 +2079,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))}`,

private clearAssetPlayer(
assetId: InterstitialAssetId,
toSegment?: InterstitialScheduleItem | null,
toSegment: InterstitialScheduleItem | null,
) {
if (toSegment === null) {
return;
Expand Down Expand Up @@ -2228,7 +2232,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))}`,
const error = new Error(errorMessage);
if (assetItem) {
if (this.playingAsset !== assetItem) {
this.clearAssetPlayer(assetItem.identifier);
this.clearAssetPlayer(assetItem.identifier, null);
}
assetItem.error = error;
}
Expand All @@ -2251,6 +2255,13 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))}`,
// Update schedule now that interstitial/assets are flagged with `error` for fallback
this.updateSchedule();
if (playingItem) {
this.log(
`Fallback to primary from event "${interstitial.identifier}" start: ${
flushStart
} pos: ${this.timelinePos} playing: ${
playingItem ? segmentToString(playingItem) : '<none>'
} error: ${interstitial.error}`,
);
if (interstitial.appendInPlace) {
interstitial.appendInPlace = false;
this.attachPrimary(flushStart, null);
Expand Down
20 changes: 4 additions & 16 deletions src/loader/playlist-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ErrorDetails, ErrorTypes } from '../errors';
import { Events } from '../events';
import { PlaylistContextType, PlaylistLevelType } from '../types/loader';
import { AttrList } from '../utils/attr-list';
import { computeReloadInterval } from '../utils/level-helper';
import type { LevelDetails } from './level-details';
import type { LoaderConfig, RetryConfig } from '../config';
import type Hls from '../hls';
Expand All @@ -19,7 +20,6 @@ import type {
ErrorData,
LevelLoadingData,
LevelsUpdatedData,
ManifestLoadedData,
ManifestLoadingData,
TrackLoadingData,
} from '../types/events';
Expand Down Expand Up @@ -70,6 +70,7 @@ class PlaylistLoader implements NetworkComponentAPI {
[key: string]: Loader<LoaderContext>;
} = Object.create(null);
private variableList: VariableMap | null = null;
public onManifestLoaded = this.checkAutostartLoad;

constructor(hls: Hls) {
this.hls = hls;
Expand Down Expand Up @@ -498,12 +499,6 @@ class PlaylistLoader implements NetworkComponentAPI {
});
}

onManifestLoaded(event: Events.MANIFEST_LOADED, data: ManifestLoadedData) {
if (!data.isMediaPlaylist) {
this.checkAutostartLoad();
}
}

private handleTrackOrLevelPlaylist(
response: LoaderResponse,
stats: LoaderStats,
Expand Down Expand Up @@ -542,6 +537,8 @@ class PlaylistLoader implements NetworkComponentAPI {
name: '',
url,
};
levelDetails.requestScheduled =
stats.loading.start + computeReloadInterval(levelDetails, 0);

hls.trigger(Events.MANIFEST_LOADED, {
levels: [singleLevel],
Expand All @@ -554,7 +551,6 @@ class PlaylistLoader implements NetworkComponentAPI {
contentSteering: null,
startTimeOffset: null,
variableList: null,
isMediaPlaylist: true,
});
}

Expand All @@ -572,14 +568,6 @@ class PlaylistLoader implements NetworkComponentAPI {
networkDetails,
loader,
);

if (
type === PlaylistContextType.MANIFEST &&
(!levelDetails.playlistParsingError ||
(!levelDetails.fragments.length && levelDetails.live))
) {
this.checkAutostartLoad();
}
}

private handleManifestParsingError(
Expand Down
1 change: 0 additions & 1 deletion src/types/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ export interface ManifestLoadedData {
subtitles?: MediaPlaylist[];
url: string;
variableList: VariableMap | null;
isMediaPlaylist?: boolean;
}

export interface ManifestParsedData {
Expand Down

0 comments on commit 88be787

Please sign in to comment.