hls.js 1.6.0-rc.2 → 1.6.0-rc.2.0.canary.11083
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hls.d.mts +1 -0
- package/dist/hls.d.ts +1 -0
- package/dist/hls.js +85 -42
- package/dist/hls.js.d.ts +1 -0
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +32 -25
- package/dist/hls.light.js.map +1 -1
- package/dist/hls.light.min.js +1 -1
- package/dist/hls.light.min.js.map +1 -1
- package/dist/hls.light.mjs +34 -27
- package/dist/hls.light.mjs.map +1 -1
- package/dist/hls.min.js +1 -1
- package/dist/hls.min.js.map +1 -1
- package/dist/hls.mjs +86 -43
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/dist/hls.worker.js.map +1 -1
- package/package.json +1 -1
- package/src/controller/abr-controller.ts +10 -5
- package/src/controller/base-stream-controller.ts +8 -1
- package/src/controller/interstitials-controller.ts +61 -17
- package/src/controller/interstitials-schedule.ts +1 -1
- package/src/exports-named.ts +2 -0
- package/src/utils/mp4-tools.ts +13 -15
package/dist/hls.mjs
CHANGED
@@ -402,7 +402,7 @@ function enableLogs(debugConfig, context, id) {
|
|
402
402
|
// Some browsers don't allow to use bind on console object anyway
|
403
403
|
// fallback to default if needed
|
404
404
|
try {
|
405
|
-
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-rc.2"}`);
|
405
|
+
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.0-rc.2.0.canary.11083"}`);
|
406
406
|
} catch (e) {
|
407
407
|
/* log fn threw an exception. All logger methods are no-ops. */
|
408
408
|
return createLogger();
|
@@ -1308,29 +1308,27 @@ function parseInitSegment(initSegment) {
|
|
1308
1308
|
soun: ElementaryStreamTypes.AUDIO,
|
1309
1309
|
vide: ElementaryStreamTypes.VIDEO
|
1310
1310
|
}[hdlrType];
|
1311
|
+
// Parse codec details
|
1312
|
+
const stsdBox = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0];
|
1313
|
+
const stsd = parseStsd(stsdBox);
|
1311
1314
|
if (type) {
|
1312
|
-
//
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
timescale,
|
1330
|
-
type: hdlrType,
|
1331
|
-
stsd
|
1332
|
-
};
|
1333
|
-
}
|
1315
|
+
// Add 'audio', 'video', and 'audiovideo' track records that will map to SourceBuffers
|
1316
|
+
result[trackId] = {
|
1317
|
+
timescale,
|
1318
|
+
type,
|
1319
|
+
stsd
|
1320
|
+
};
|
1321
|
+
result[type] = _objectSpread2({
|
1322
|
+
timescale,
|
1323
|
+
id: trackId
|
1324
|
+
}, stsd);
|
1325
|
+
} else {
|
1326
|
+
// Add 'meta' and other track records required by `offsetStartDTS`
|
1327
|
+
result[trackId] = {
|
1328
|
+
timescale,
|
1329
|
+
type: hdlrType,
|
1330
|
+
stsd
|
1331
|
+
};
|
1334
1332
|
}
|
1335
1333
|
}
|
1336
1334
|
}
|
@@ -3274,6 +3272,7 @@ class AbrController extends Logger {
|
|
3274
3272
|
this.fragCurrent = null;
|
3275
3273
|
this.partCurrent = null;
|
3276
3274
|
this.bitrateTestDelay = 0;
|
3275
|
+
this.rebufferNotice = -1;
|
3277
3276
|
this.bwEstimator = void 0;
|
3278
3277
|
/*
|
3279
3278
|
This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
|
@@ -3739,6 +3738,7 @@ class AbrController extends Logger {
|
|
3739
3738
|
if (bufferStarvationDelay) {
|
3740
3739
|
const _bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, 0, bwFactor, bwUpFactor);
|
3741
3740
|
if (_bestLevel >= 0) {
|
3741
|
+
this.rebufferNotice = -1;
|
3742
3742
|
return _bestLevel;
|
3743
3743
|
}
|
3744
3744
|
}
|
@@ -3761,7 +3761,10 @@ class AbrController extends Logger {
|
|
3761
3761
|
}
|
3762
3762
|
}
|
3763
3763
|
const bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor);
|
3764
|
-
this.
|
3764
|
+
if (this.rebufferNotice !== bestLevel) {
|
3765
|
+
this.rebufferNotice = bestLevel;
|
3766
|
+
this.info(`${bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty'}, optimal quality level ${bestLevel}`);
|
3767
|
+
}
|
3765
3768
|
if (bestLevel > -1) {
|
3766
3769
|
return bestLevel;
|
3767
3770
|
}
|
@@ -9158,7 +9161,11 @@ class BaseStreamController extends TaskLoop {
|
|
9158
9161
|
const end = this.loadingParts ? levelDetails.partEnd : levelDetails.fragmentEnd;
|
9159
9162
|
frag = this.getFragmentAtPosition(pos, end, levelDetails);
|
9160
9163
|
}
|
9161
|
-
|
9164
|
+
let programFrag = this.filterReplacedPrimary(frag, levelDetails);
|
9165
|
+
if (!programFrag && frag) {
|
9166
|
+
const curSNIdx = frag.sn - levelDetails.startSN;
|
9167
|
+
programFrag = this.filterReplacedPrimary(fragments[curSNIdx + 1] || null, levelDetails);
|
9168
|
+
}
|
9162
9169
|
return this.mapToInitFragWhenRequired(programFrag);
|
9163
9170
|
}
|
9164
9171
|
isLoopLoading(frag, targetBufferTime) {
|
@@ -10110,7 +10117,7 @@ function requireEventemitter3 () {
|
|
10110
10117
|
var eventemitter3Exports = requireEventemitter3();
|
10111
10118
|
var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventemitter3Exports);
|
10112
10119
|
|
10113
|
-
const version = "1.6.0-rc.2";
|
10120
|
+
const version = "1.6.0-rc.2.0.canary.11083";
|
10114
10121
|
|
10115
10122
|
// ensure the worker ends up in the bundle
|
10116
10123
|
// If the worker should not be included this gets aliased to empty.js
|
@@ -23890,7 +23897,7 @@ class InterstitialsSchedule extends Logger {
|
|
23890
23897
|
return !playlists.some(playlistType => {
|
23891
23898
|
const details = mediaSelection[playlistType].details;
|
23892
23899
|
const playlistEnd = details.edge;
|
23893
|
-
if (resumeTime
|
23900
|
+
if (resumeTime >= playlistEnd) {
|
23894
23901
|
// Live playback - resumption segments are not yet available
|
23895
23902
|
this.log(`"${interstitial.identifier}" resumption ${resumeTime} past ${playlistType} playlist end ${playlistEnd}`);
|
23896
23903
|
// Assume alignment is possible (or reset can take place)
|
@@ -25285,14 +25292,18 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25285
25292
|
}
|
25286
25293
|
|
25287
25294
|
// Schedule buffer control
|
25288
|
-
checkBuffer() {
|
25295
|
+
checkBuffer(starved) {
|
25289
25296
|
const items = this.schedule.items;
|
25290
25297
|
if (!items) {
|
25291
25298
|
return;
|
25292
25299
|
}
|
25293
25300
|
// Find when combined forward buffer change reaches next schedule segment
|
25294
25301
|
const bufferInfo = BufferHelper.bufferInfo(this.primaryMedia, this.timelinePos, 0);
|
25295
|
-
|
25302
|
+
if (starved) {
|
25303
|
+
this.bufferedPos = this.timelinePos;
|
25304
|
+
}
|
25305
|
+
starved || (starved = bufferInfo.len < 1);
|
25306
|
+
this.updateBufferedPos(bufferInfo.end, items, starved);
|
25296
25307
|
}
|
25297
25308
|
updateBufferedPos(bufferEnd, items, bufferIsEmpty) {
|
25298
25309
|
const schedule = this.schedule;
|
@@ -25329,8 +25340,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25329
25340
|
this.preloadAssets(nextItemToBuffer.event, 0);
|
25330
25341
|
}
|
25331
25342
|
}
|
25332
|
-
} else if (bufferIsEmpty && playingItem && !this.itemsMatch(playingItem, bufferingItem)
|
25333
|
-
|
25343
|
+
} else if (bufferIsEmpty && playingItem && !this.itemsMatch(playingItem, bufferingItem)) {
|
25344
|
+
if (bufferEndIndex === playingIndex) {
|
25345
|
+
this.bufferedToItem(playingItem);
|
25346
|
+
} else if (bufferEndIndex === playingIndex + 1) {
|
25347
|
+
this.bufferedToItem(items[bufferEndIndex]);
|
25348
|
+
}
|
25334
25349
|
}
|
25335
25350
|
}
|
25336
25351
|
assetsBuffered(item, media) {
|
@@ -25440,7 +25455,11 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25440
25455
|
if (neverLoaded) {
|
25441
25456
|
const timelineStart = interstitial.timelineStart;
|
25442
25457
|
if (interstitial.appendInPlace) {
|
25443
|
-
|
25458
|
+
var _playingItem$nextEven;
|
25459
|
+
const playingItem = this.playingItem;
|
25460
|
+
if (!this.isInterstitial(playingItem) && (playingItem == null ? void 0 : (_playingItem$nextEven = playingItem.nextEvent) == null ? void 0 : _playingItem$nextEven.identifier) === interstitial.identifier) {
|
25461
|
+
this.flushFrontBuffer(timelineStart + 0.25);
|
25462
|
+
}
|
25444
25463
|
}
|
25445
25464
|
let hlsStartOffset;
|
25446
25465
|
let liveStartPosition = 0;
|
@@ -25483,6 +25502,7 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25483
25502
|
if (!requiredTracks) {
|
25484
25503
|
return;
|
25485
25504
|
}
|
25505
|
+
this.log(`Removing front buffer starting at ${startOffset}`);
|
25486
25506
|
const sourceBufferNames = Object.keys(requiredTracks);
|
25487
25507
|
sourceBufferNames.forEach(type => {
|
25488
25508
|
this.hls.trigger(Events.BUFFER_FLUSHING, {
|
@@ -25559,11 +25579,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25559
25579
|
}
|
25560
25580
|
}
|
25561
25581
|
}
|
25582
|
+
const assetId = assetItem.identifier;
|
25562
25583
|
const playerConfig = _objectSpread2(_objectSpread2({}, userConfig), {}, {
|
25563
25584
|
autoStartLoad: true,
|
25564
25585
|
startFragPrefetch: true,
|
25565
25586
|
primarySessionId: primary.sessionId,
|
25566
|
-
assetPlayerId:
|
25587
|
+
assetPlayerId: assetId,
|
25567
25588
|
abrEwmaDefaultEstimate: primary.bandwidthEstimate,
|
25568
25589
|
interstitialsController: undefined,
|
25569
25590
|
startPosition,
|
@@ -25585,10 +25606,12 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25585
25606
|
contentId: hash(assetItem.uri)
|
25586
25607
|
});
|
25587
25608
|
}
|
25609
|
+
if (this.getAssetPlayer(assetId)) {
|
25610
|
+
this.warn(`Duplicate date range identifier ${interstitial} and asset ${assetId}`);
|
25611
|
+
}
|
25588
25612
|
const player = new HlsAssetPlayer(this.HlsPlayerClass, playerConfig, interstitial, assetItem);
|
25589
25613
|
this.playerQueue.push(player);
|
25590
25614
|
interstitial.assetList[assetListIndex] = assetItem;
|
25591
|
-
const assetId = assetItem.identifier;
|
25592
25615
|
// Listen for LevelDetails and PTS change to update duration
|
25593
25616
|
const updateAssetPlayerDetails = details => {
|
25594
25617
|
if (details.live) {
|
@@ -25630,15 +25653,13 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25630
25653
|
}
|
25631
25654
|
};
|
25632
25655
|
player.on(Events.BUFFER_CODECS, onBufferCodecs);
|
25633
|
-
const bufferedToEnd =
|
25656
|
+
const bufferedToEnd = () => {
|
25634
25657
|
var _this$schedule$items2;
|
25635
25658
|
const inQueuPlayer = this.getAssetPlayer(assetId);
|
25636
25659
|
this.log(`buffered to end of asset ${inQueuPlayer}`);
|
25637
25660
|
if (!inQueuPlayer) {
|
25638
25661
|
return;
|
25639
25662
|
}
|
25640
|
-
inQueuPlayer.off(Events.BUFFERED_TO_END, bufferedToEnd);
|
25641
|
-
|
25642
25663
|
// Preload at end of asset
|
25643
25664
|
const scheduleIndex = this.schedule.findEventIndex(interstitial.identifier);
|
25644
25665
|
const assetListIndex = interstitial.findAssetIndex(assetItem);
|
@@ -25646,7 +25667,7 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25646
25667
|
const item = (_this$schedule$items2 = this.schedule.items) == null ? void 0 : _this$schedule$items2[scheduleIndex];
|
25647
25668
|
if (this.isInterstitial(item)) {
|
25648
25669
|
if (assetListIndex !== -1 && !interstitial.isAssetPastPlayoutLimit(nextAssetIndex) && !interstitial.assetList[nextAssetIndex].error) {
|
25649
|
-
this.bufferedToItem(item,
|
25670
|
+
this.bufferedToItem(item, nextAssetIndex);
|
25650
25671
|
} else {
|
25651
25672
|
var _this$schedule$items3;
|
25652
25673
|
const nextItem = (_this$schedule$items3 = this.schedule.items) == null ? void 0 : _this$schedule$items3[scheduleIndex + 1];
|
@@ -25671,6 +25692,22 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25671
25692
|
player.once(Events.MEDIA_ENDED, endedWithAssetIndex(assetListIndex));
|
25672
25693
|
player.once(Events.PLAYOUT_LIMIT_REACHED, endedWithAssetIndex(Infinity));
|
25673
25694
|
player.on(Events.ERROR, (event, data) => {
|
25695
|
+
const inQueuPlayer = this.getAssetPlayer(assetId);
|
25696
|
+
if (data.details === ErrorDetails.BUFFER_STALLED_ERROR) {
|
25697
|
+
if (inQueuPlayer != null && inQueuPlayer.media) {
|
25698
|
+
const assetCurrentTime = inQueuPlayer.currentTime;
|
25699
|
+
const distanceFromEnd = inQueuPlayer.duration - assetCurrentTime;
|
25700
|
+
if (assetCurrentTime && interstitial.appendInPlace && distanceFromEnd / inQueuPlayer.media.playbackRate < 0.5) {
|
25701
|
+
this.log(`Advancing buffer past end of asset ${assetId} ${interstitial} at ${inQueuPlayer.media.currentTime}`);
|
25702
|
+
bufferedToEnd();
|
25703
|
+
} else {
|
25704
|
+
this.warn(`Stalled at ${assetCurrentTime} of ${assetCurrentTime + distanceFromEnd} in asset ${assetId} ${interstitial}`);
|
25705
|
+
this.onTimeupdate();
|
25706
|
+
this.checkBuffer(true);
|
25707
|
+
}
|
25708
|
+
}
|
25709
|
+
return;
|
25710
|
+
}
|
25674
25711
|
this.handleAssetItemError(data, interstitial, this.schedule.findEventIndex(interstitial.identifier), assetListIndex, `Asset player error ${data.error} ${interstitial}`);
|
25675
25712
|
});
|
25676
25713
|
player.on(Events.DESTROYING, () => {
|
@@ -25745,10 +25782,9 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25745
25782
|
player
|
25746
25783
|
});
|
25747
25784
|
}
|
25748
|
-
|
25749
|
-
|
25750
|
-
|
25751
|
-
}
|
25785
|
+
|
25786
|
+
// detach media and attach to interstitial player if it does not have another element attached
|
25787
|
+
this.bufferAssetPlayer(player, media);
|
25752
25788
|
}
|
25753
25789
|
bufferAssetPlayer(player, media) {
|
25754
25790
|
var _this$schedule$items4, _this$detachedData5;
|
@@ -25931,6 +25967,13 @@ Schedule: ${scheduleItems.map(seg => segmentToString(seg))}`);
|
|
25931
25967
|
if (interstitial) {
|
25932
25968
|
this.primaryFallback(interstitial);
|
25933
25969
|
}
|
25970
|
+
break;
|
25971
|
+
}
|
25972
|
+
case ErrorDetails.BUFFER_STALLED_ERROR:
|
25973
|
+
{
|
25974
|
+
this.onTimeupdate();
|
25975
|
+
this.checkBuffer(true);
|
25976
|
+
break;
|
25934
25977
|
}
|
25935
25978
|
}
|
25936
25979
|
}
|
@@ -35100,5 +35143,5 @@ class Hls {
|
|
35100
35143
|
}
|
35101
35144
|
Hls.defaultConfig = void 0;
|
35102
35145
|
|
35103
|
-
export { AbrController, AttrList, AudioStreamController, AudioTrackController, BasePlaylistController, BaseSegment, BaseStreamController, BufferController, CMCDController, CapLevelController, ChunkMetadata, ContentSteeringController, Cues, DateRange, EMEController, ErrorActionFlags, ErrorController, ErrorDetails, ErrorTypes, Events, FPSController, FetchLoader, Fragment, Hls, HlsSkip, HlsUrlParameters, KeySystemFormats, KeySystems, Level, LevelDetails, LevelKey, LoadStats, MetadataSchema, NetworkErrorAction, Part, PlaylistLevelType, SubtitleStreamController, SubtitleTrackController, TimelineController, XhrLoader, Hls as default, fetchSupported, getMediaSource, isMSESupported, isSupported, requestMediaKeySystemAccess };
|
35146
|
+
export { AbrController, AttrList, AudioStreamController, AudioTrackController, BasePlaylistController, BaseSegment, BaseStreamController, BufferController, CMCDController, CapLevelController, ChunkMetadata, ContentSteeringController, Cues, DateRange, EMEController, ErrorActionFlags, ErrorController, ErrorDetails, ErrorTypes, Events, FPSController, FetchLoader, Fragment, Hls, HlsSkip, HlsUrlParameters, KeySystemFormats, KeySystems, Level, LevelDetails, LevelKey, LoadStats, M3U8Parser, MetadataSchema, NetworkErrorAction, Part, PlaylistLevelType, SubtitleStreamController, SubtitleTrackController, TimelineController, XhrLoader, Hls as default, fetchSupported, getMediaSource, isMSESupported, isSupported, requestMediaKeySystemAccess };
|
35104
35147
|
//# sourceMappingURL=hls.mjs.map
|