Skip to content

Commit d2c81f0

Browse files
authored
Force schedule update on asset or interstitial error (#7451)
* Force schedule update on asset or interstitial error (in case playout duration is not changed by error but schedule update is needed) * Handle seeking back in interstitial with faulty assets
1 parent 053c42b commit d2c81f0

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

src/controller/interstitial-player.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ export class HlsAssetPlayer {
8787
// issue should surface as an INTERSTITIAL_ASSET_ERROR loading the asset.
8888
}
8989
hls.loadSource(uri);
90+
} else if (hls.levels.length && !(hls as any).started) {
91+
hls.startLoad(-1, true);
9092
}
9193
}
9294

@@ -100,7 +102,7 @@ export class HlsAssetPlayer {
100102
if (!media) {
101103
return false;
102104
}
103-
const duration = this._bufferedEosTime || this.duration;
105+
const duration = Math.min(this._bufferedEosTime || Infinity, this.duration);
104106
const start = this.timelineOffset;
105107
const bufferInfo = BufferHelper.bufferInfo(media, start, 0);
106108
const bufferedEnd = this.getAssetTime(bufferInfo.end);
@@ -160,6 +162,13 @@ export class HlsAssetPlayer {
160162
if (!duration) {
161163
return 0;
162164
}
165+
const playoutLimit = this.interstitial.playoutLimit;
166+
if (playoutLimit) {
167+
const assetPlayout = playoutLimit - this.startOffset;
168+
if (assetPlayout > 0 && assetPlayout < duration) {
169+
return assetPlayout;
170+
}
171+
}
163172
return duration;
164173
}
165174

src/controller/interstitials-controller.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ export default class InterstitialsController
905905
currentTime - diff,
906906
);
907907
if (resetCount) {
908-
this.updateSchedule();
908+
this.updateSchedule(true);
909909
}
910910
}
911911
this.checkBuffer();
@@ -961,6 +961,10 @@ export default class InterstitialsController
961961
(backwardSeek && currentTime < start) ||
962962
currentTime >= start + duration
963963
) {
964+
if (playingItem.event?.appendInPlace) {
965+
this.clearInterstitial(playingItem.event, playingItem);
966+
this.flushFrontBuffer(currentTime);
967+
}
964968
this.setScheduleToAssetAtTime(currentTime, playingAsset);
965969
}
966970
};
@@ -1119,8 +1123,10 @@ export default class InterstitialsController
11191123
if (!scheduleItems || this.playbackDisabled) {
11201124
return;
11211125
}
1122-
this.log(`setSchedulePosition ${index}, ${assetListIndex}`);
11231126
const scheduledItem = index >= 0 ? scheduleItems[index] : null;
1127+
this.log(
1128+
`setSchedulePosition ${index}, ${assetListIndex} (${scheduledItem ? segmentToString(scheduledItem) : scheduledItem})`,
1129+
);
11241130
// Cleanup current item / asset
11251131
const currentItem = this.waitingItem || this.playingItem;
11261132
const playingLastItem = this.playingLastItem;
@@ -1837,12 +1843,12 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
18371843
return item && this.schedule ? this.schedule.findItemIndex(item, time) : -1;
18381844
}
18391845

1840-
private updateSchedule() {
1846+
private updateSchedule(forceUpdate: boolean = false) {
18411847
const mediaSelection = this.mediaSelection;
18421848
if (!mediaSelection) {
18431849
return;
18441850
}
1845-
this.schedule?.updateSchedule(mediaSelection, []);
1851+
this.schedule?.updateSchedule(mediaSelection, [], forceUpdate);
18461852
}
18471853

18481854
// Schedule buffer control
@@ -2699,8 +2705,8 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
26992705
for (let i = assetListIndex; i < interstitial.assetList.length; i++) {
27002706
this.resetAssetPlayer(interstitial.assetList[i].identifier);
27012707
}
2702-
this.updateSchedule();
27032708
}
2709+
this.updateSchedule(true);
27042710
if (interstitial.error) {
27052711
this.primaryFallback(interstitial);
27062712
} else if (playingAsset && playingAsset.identifier === assetId) {
@@ -2719,7 +2725,6 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
27192725
const flushStart = interstitial.timelineStart;
27202726
const playingItem = this.effectivePlayingItem;
27212727
// Update schedule now that interstitial/assets are flagged with `error` for fallback
2722-
this.updateSchedule();
27232728
if (playingItem) {
27242729
this.log(
27252730
`Fallback to primary from event "${interstitial.identifier}" start: ${
@@ -2802,6 +2807,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
28022807
interstitial.error = new Error(
28032808
`Interstitial no longer within playback range ${this.timelinePos} ${interstitial}`,
28042809
);
2810+
this.updateSchedule(true);
28052811
this.primaryFallback(interstitial);
28062812
return;
28072813
}
@@ -2837,6 +2843,7 @@ Schedule: ${scheduleItems.map((seg) => segmentToString(seg))} pos: ${this.timeli
28372843
case ErrorDetails.ASSET_LIST_LOAD_TIMEOUT: {
28382844
const interstitial = data.interstitial;
28392845
if (interstitial) {
2846+
this.updateSchedule(true);
28402847
this.primaryFallback(interstitial);
28412848
}
28422849
break;

src/controller/interstitials-schedule.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,12 +303,14 @@ export class InterstitialsSchedule extends Logger {
303303
public updateSchedule(
304304
mediaSelection: MediaSelection,
305305
removedInterstitials: InterstitialEvent[] = [],
306+
forceUpdate: boolean = false,
306307
) {
307308
const events = this.events || [];
308309
if (events.length || removedInterstitials.length || this.length < 2) {
309310
const currentItems = this.items;
310311
const updatedItems = this.parseSchedule(events, mediaSelection);
311312
const updated =
313+
forceUpdate ||
312314
removedInterstitials.length ||
313315
currentItems?.length !== updatedItems.length ||
314316
updatedItems.some((item, i) => {

0 commit comments

Comments
 (0)