hls.js 1.6.14 → 1.6.15
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 +3 -0
- package/dist/hls.d.ts +3 -0
- package/dist/hls.js +59 -27
- package/dist/hls.js.d.ts +3 -0
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +36 -15
- 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 +37 -16
- 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 +60 -28
- 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/base-stream-controller.ts +9 -4
- package/src/controller/eme-controller.ts +8 -0
- package/src/controller/fragment-tracker.ts +11 -7
- package/src/controller/interstitials-controller.ts +22 -12
- package/src/controller/stream-controller.ts +2 -1
- package/src/loader/key-loader.ts +10 -2
- package/src/loader/level-key.ts +9 -0
- package/src/remux/mp4-remuxer.ts +1 -1
package/dist/hls.d.mts
CHANGED
|
@@ -1496,6 +1496,7 @@ export declare class FragmentTracker implements ComponentAPI {
|
|
|
1496
1496
|
* Partially loaded fragments will be registered as a partial fragment
|
|
1497
1497
|
*/
|
|
1498
1498
|
detectPartialFragments(data: FragBufferedData): void;
|
|
1499
|
+
private bufferedEnd;
|
|
1499
1500
|
private removeParts;
|
|
1500
1501
|
fragBuffered(frag: MediaFragment, force?: true): void;
|
|
1501
1502
|
private getBufferedTimes;
|
|
@@ -2490,6 +2491,7 @@ export declare class InterstitialsController extends Logger implements NetworkCo
|
|
|
2490
2491
|
private createAsset;
|
|
2491
2492
|
private createAssetPlayer;
|
|
2492
2493
|
private clearInterstitial;
|
|
2494
|
+
private clearAssetPlayers;
|
|
2493
2495
|
private resetAssetPlayer;
|
|
2494
2496
|
private clearAssetPlayer;
|
|
2495
2497
|
private emptyPlayerQueue;
|
|
@@ -2760,6 +2762,7 @@ export declare class LevelKey implements DecryptData {
|
|
|
2760
2762
|
pssh: Uint8Array<ArrayBuffer> | null;
|
|
2761
2763
|
static clearKeyUriToKeyIdMap(): void;
|
|
2762
2764
|
static setKeyIdForUri(uri: string, keyId: Uint8Array<ArrayBuffer>): void;
|
|
2765
|
+
static addKeyIdForUri(uri: string): Uint8Array<ArrayBuffer>;
|
|
2763
2766
|
constructor(method: string, uri: string, format: string, formatversions?: number[], iv?: Uint8Array<ArrayBuffer> | null, keyId?: string);
|
|
2764
2767
|
matches(key: LevelKey): boolean;
|
|
2765
2768
|
isSupported(): boolean;
|
package/dist/hls.d.ts
CHANGED
|
@@ -1496,6 +1496,7 @@ export declare class FragmentTracker implements ComponentAPI {
|
|
|
1496
1496
|
* Partially loaded fragments will be registered as a partial fragment
|
|
1497
1497
|
*/
|
|
1498
1498
|
detectPartialFragments(data: FragBufferedData): void;
|
|
1499
|
+
private bufferedEnd;
|
|
1499
1500
|
private removeParts;
|
|
1500
1501
|
fragBuffered(frag: MediaFragment, force?: true): void;
|
|
1501
1502
|
private getBufferedTimes;
|
|
@@ -2490,6 +2491,7 @@ export declare class InterstitialsController extends Logger implements NetworkCo
|
|
|
2490
2491
|
private createAsset;
|
|
2491
2492
|
private createAssetPlayer;
|
|
2492
2493
|
private clearInterstitial;
|
|
2494
|
+
private clearAssetPlayers;
|
|
2493
2495
|
private resetAssetPlayer;
|
|
2494
2496
|
private clearAssetPlayer;
|
|
2495
2497
|
private emptyPlayerQueue;
|
|
@@ -2760,6 +2762,7 @@ export declare class LevelKey implements DecryptData {
|
|
|
2760
2762
|
pssh: Uint8Array<ArrayBuffer> | null;
|
|
2761
2763
|
static clearKeyUriToKeyIdMap(): void;
|
|
2762
2764
|
static setKeyIdForUri(uri: string, keyId: Uint8Array<ArrayBuffer>): void;
|
|
2765
|
+
static addKeyIdForUri(uri: string): Uint8Array<ArrayBuffer>;
|
|
2763
2766
|
constructor(method: string, uri: string, format: string, formatversions?: number[], iv?: Uint8Array<ArrayBuffer> | null, keyId?: string);
|
|
2764
2767
|
matches(key: LevelKey): boolean;
|
|
2765
2768
|
isSupported(): boolean;
|
package/dist/hls.js
CHANGED
|
@@ -1165,7 +1165,7 @@
|
|
|
1165
1165
|
// Some browsers don't allow to use bind on console object anyway
|
|
1166
1166
|
// fallback to default if needed
|
|
1167
1167
|
try {
|
|
1168
|
-
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.
|
|
1168
|
+
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.15");
|
|
1169
1169
|
} catch (e) {
|
|
1170
1170
|
/* log fn threw an exception. All logger methods are no-ops. */
|
|
1171
1171
|
return createLogger();
|
|
@@ -5583,11 +5583,7 @@
|
|
|
5583
5583
|
});
|
|
5584
5584
|
fragmentEntity.loaded = null;
|
|
5585
5585
|
if (Object.keys(fragmentEntity.range).length) {
|
|
5586
|
-
fragmentEntity
|
|
5587
|
-
var endList = fragmentEntity.body.endList = frag.endList || fragmentEntity.body.endList;
|
|
5588
|
-
if (endList) {
|
|
5589
|
-
this.endListFragments[fragmentEntity.body.type] = fragmentEntity;
|
|
5590
|
-
}
|
|
5586
|
+
this.bufferedEnd(fragmentEntity, frag);
|
|
5591
5587
|
if (!isPartial(fragmentEntity)) {
|
|
5592
5588
|
// Remove older fragment parts from lookup after frag is tracked as buffered
|
|
5593
5589
|
this.removeParts(frag.sn - 1, frag.type);
|
|
@@ -5597,6 +5593,13 @@
|
|
|
5597
5593
|
this.removeFragment(fragmentEntity.body);
|
|
5598
5594
|
}
|
|
5599
5595
|
};
|
|
5596
|
+
_proto.bufferedEnd = function bufferedEnd(fragmentEntity, frag) {
|
|
5597
|
+
fragmentEntity.buffered = true;
|
|
5598
|
+
var endList = fragmentEntity.body.endList = frag.endList || fragmentEntity.body.endList;
|
|
5599
|
+
if (endList) {
|
|
5600
|
+
this.endListFragments[fragmentEntity.body.type] = fragmentEntity;
|
|
5601
|
+
}
|
|
5602
|
+
};
|
|
5600
5603
|
_proto.removeParts = function removeParts(snToKeep, levelType) {
|
|
5601
5604
|
var activeParts = this.activePartLists[levelType];
|
|
5602
5605
|
if (!activeParts) {
|
|
@@ -5623,7 +5626,7 @@
|
|
|
5623
5626
|
}
|
|
5624
5627
|
if (fragmentEntity) {
|
|
5625
5628
|
fragmentEntity.loaded = null;
|
|
5626
|
-
fragmentEntity
|
|
5629
|
+
this.bufferedEnd(fragmentEntity, frag);
|
|
5627
5630
|
}
|
|
5628
5631
|
};
|
|
5629
5632
|
_proto.getBufferedTimes = function getBufferedTimes(fragment, part, partial, timeRange) {
|
|
@@ -7810,6 +7813,14 @@
|
|
|
7810
7813
|
LevelKey.setKeyIdForUri = function setKeyIdForUri(uri, keyId) {
|
|
7811
7814
|
keyUriToKeyIdMap[uri] = keyId;
|
|
7812
7815
|
};
|
|
7816
|
+
LevelKey.addKeyIdForUri = function addKeyIdForUri(uri) {
|
|
7817
|
+
var val = Object.keys(keyUriToKeyIdMap).length % Number.MAX_SAFE_INTEGER;
|
|
7818
|
+
var keyId = new Uint8Array(16);
|
|
7819
|
+
var dv = new DataView(keyId.buffer, 12, 4); // Just set the last 4 bytes
|
|
7820
|
+
dv.setUint32(0, val);
|
|
7821
|
+
keyUriToKeyIdMap[uri] = keyId;
|
|
7822
|
+
return keyId;
|
|
7823
|
+
};
|
|
7813
7824
|
var _proto = LevelKey.prototype;
|
|
7814
7825
|
_proto.matches = function matches(key) {
|
|
7815
7826
|
return key.uri === this.uri && key.method === this.method && key.encrypted === this.encrypted && key.keyFormat === this.keyFormat && arrayValuesMatch(key.keyFormatVersions, this.keyFormatVersions) && optionalArrayValuesMatch(key.iv, this.iv) && optionalArrayValuesMatch(key.keyId, this.keyId);
|
|
@@ -9950,7 +9961,7 @@
|
|
|
9950
9961
|
this.state = State.FRAG_LOADING;
|
|
9951
9962
|
|
|
9952
9963
|
// Load key before streaming fragment data
|
|
9953
|
-
var dataOnProgress = this.config.progressive;
|
|
9964
|
+
var dataOnProgress = this.config.progressive && frag.type !== PlaylistLevelType.SUBTITLE;
|
|
9954
9965
|
var result;
|
|
9955
9966
|
if (dataOnProgress && keyLoadingPromise) {
|
|
9956
9967
|
result = keyLoadingPromise.then(function (keyLoadedData) {
|
|
@@ -10776,11 +10787,12 @@
|
|
|
10776
10787
|
}, false);
|
|
10777
10788
|
if (!parsed) {
|
|
10778
10789
|
var _this$transmuxer;
|
|
10779
|
-
|
|
10780
|
-
|
|
10790
|
+
var mediaNotFound = ((_this$transmuxer = this.transmuxer) == null ? void 0 : _this$transmuxer.error) === null;
|
|
10791
|
+
if (level.fragmentError === 0 || mediaNotFound && (level.fragmentError < 2 || frag.endList)) {
|
|
10792
|
+
// Mark and track the odd (or last) empty segment as a gap to avoid reloading
|
|
10781
10793
|
this.treatAsGap(frag, level);
|
|
10782
10794
|
}
|
|
10783
|
-
if (
|
|
10795
|
+
if (mediaNotFound) {
|
|
10784
10796
|
var error = new Error("Found no media in fragment " + frag.sn + " of " + this.playlistLabel() + " " + frag.level + " resetting transmuxer to fallback to playlist timing");
|
|
10785
10797
|
this.warn(error.message);
|
|
10786
10798
|
this.hls.trigger(Events.ERROR, {
|
|
@@ -16140,7 +16152,7 @@
|
|
|
16140
16152
|
// Clear the track samples. This also clears the samples array in the demuxer, since the reference is shared
|
|
16141
16153
|
track.samples = [];
|
|
16142
16154
|
var start = (firstPTS - initTime) / inputTimeScale;
|
|
16143
|
-
var end = nextAudioTs / inputTimeScale;
|
|
16155
|
+
var end = this.nextAudioTs / inputTimeScale;
|
|
16144
16156
|
var type = 'audio';
|
|
16145
16157
|
var audioData = {
|
|
16146
16158
|
data1: moof,
|
|
@@ -17046,7 +17058,7 @@
|
|
|
17046
17058
|
return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
|
|
17047
17059
|
}
|
|
17048
17060
|
|
|
17049
|
-
var version = "1.6.
|
|
17061
|
+
var version = "1.6.15";
|
|
17050
17062
|
|
|
17051
17063
|
// ensure the worker ends up in the bundle
|
|
17052
17064
|
// If the worker should not be included this gets aliased to empty.js
|
|
@@ -23626,6 +23638,11 @@
|
|
|
23626
23638
|
}
|
|
23627
23639
|
var keyIdArray = 'buffer' in keyId ? new Uint8Array(keyId.buffer, keyId.byteOffset, keyId.byteLength) : new Uint8Array(keyId);
|
|
23628
23640
|
if (mediaKeySessionContext.keySystem === KeySystems.PLAYREADY && keyIdArray.length === 16) {
|
|
23641
|
+
// On some devices, the key ID has already been converted for endianness.
|
|
23642
|
+
// In such cases, this key ID is the one we need to cache.
|
|
23643
|
+
var originKeyIdWithStatusChange = arrayToHex(keyIdArray);
|
|
23644
|
+
// Cache the original key IDs to ensure compatibility across all cases.
|
|
23645
|
+
keyStatuses[originKeyIdWithStatusChange] = status;
|
|
23629
23646
|
changeEndianness(keyIdArray);
|
|
23630
23647
|
}
|
|
23631
23648
|
var keyIdWithStatusChange = arrayToHex(keyIdArray);
|
|
@@ -25458,7 +25475,8 @@
|
|
|
25458
25475
|
if (backwardSeek && currentTime < start || currentTime >= start + duration) {
|
|
25459
25476
|
var _playingItem$event;
|
|
25460
25477
|
if ((_playingItem$event = playingItem.event) != null && _playingItem$event.appendInPlace) {
|
|
25461
|
-
|
|
25478
|
+
// Return SourceBuffer(s) to primary player and flush
|
|
25479
|
+
_this.clearAssetPlayers(playingItem.event, playingItem);
|
|
25462
25480
|
_this.flushFrontBuffer(currentTime);
|
|
25463
25481
|
}
|
|
25464
25482
|
_this.setScheduleToAssetAtTime(currentTime, playingAsset);
|
|
@@ -26852,12 +26870,15 @@
|
|
|
26852
26870
|
return player;
|
|
26853
26871
|
};
|
|
26854
26872
|
_proto.clearInterstitial = function clearInterstitial(interstitial, toSegment) {
|
|
26873
|
+
this.clearAssetPlayers(interstitial, toSegment);
|
|
26874
|
+
// Remove asset list and resolved duration
|
|
26875
|
+
interstitial.reset();
|
|
26876
|
+
};
|
|
26877
|
+
_proto.clearAssetPlayers = function clearAssetPlayers(interstitial, toSegment) {
|
|
26855
26878
|
var _this9 = this;
|
|
26856
26879
|
interstitial.assetList.forEach(function (asset) {
|
|
26857
26880
|
_this9.clearAssetPlayer(asset.identifier, toSegment);
|
|
26858
26881
|
});
|
|
26859
|
-
// Remove asset list and resolved duration
|
|
26860
|
-
interstitial.reset();
|
|
26861
26882
|
};
|
|
26862
26883
|
_proto.resetAssetPlayer = function resetAssetPlayer(assetId) {
|
|
26863
26884
|
// Reset asset player so that it's timeline can be adjusted without reloading the MVP
|
|
@@ -27047,10 +27068,10 @@
|
|
|
27047
27068
|
// Fallback to Primary by on current or future events by updating schedule to skip errored interstitials/assets
|
|
27048
27069
|
var flushStart = interstitial.timelineStart;
|
|
27049
27070
|
var playingItem = this.effectivePlayingItem;
|
|
27071
|
+
var timelinePos = this.timelinePos;
|
|
27050
27072
|
// Update schedule now that interstitial/assets are flagged with `error` for fallback
|
|
27051
27073
|
if (playingItem) {
|
|
27052
|
-
this.log("Fallback to primary from event \"" + interstitial.identifier + "\" start: " + flushStart + " pos: " +
|
|
27053
|
-
var timelinePos = this.timelinePos;
|
|
27074
|
+
this.log("Fallback to primary from event \"" + interstitial.identifier + "\" start: " + flushStart + " pos: " + timelinePos + " playing: " + segmentToString(playingItem) + " error: " + interstitial.error);
|
|
27054
27075
|
if (timelinePos === -1) {
|
|
27055
27076
|
timelinePos = this.hls.startPosition;
|
|
27056
27077
|
}
|
|
@@ -27062,14 +27083,15 @@
|
|
|
27062
27083
|
this.attachPrimary(flushStart, null);
|
|
27063
27084
|
this.flushFrontBuffer(flushStart);
|
|
27064
27085
|
}
|
|
27065
|
-
|
|
27066
|
-
return;
|
|
27067
|
-
}
|
|
27068
|
-
var scheduleIndex = this.schedule.findItemIndexAtTime(timelinePos);
|
|
27069
|
-
this.setSchedulePosition(scheduleIndex);
|
|
27070
|
-
} else {
|
|
27086
|
+
} else if (timelinePos === -1) {
|
|
27071
27087
|
this.checkStart();
|
|
27088
|
+
return;
|
|
27072
27089
|
}
|
|
27090
|
+
if (!this.schedule) {
|
|
27091
|
+
return;
|
|
27092
|
+
}
|
|
27093
|
+
var scheduleIndex = this.schedule.findItemIndexAtTime(timelinePos);
|
|
27094
|
+
this.setSchedulePosition(scheduleIndex);
|
|
27073
27095
|
}
|
|
27074
27096
|
|
|
27075
27097
|
// Asset List loading
|
|
@@ -27113,7 +27135,8 @@
|
|
|
27113
27135
|
// Abandon if new duration is reduced enough to land playback in primary start
|
|
27114
27136
|
var index = this.schedule.findItemIndexAtTime(this.timelinePos);
|
|
27115
27137
|
if (index !== scheduleIndex) {
|
|
27116
|
-
interstitial.error = new Error("Interstitial no longer within playback range " + this.timelinePos + " " + interstitial);
|
|
27138
|
+
interstitial.error = new Error("Interstitial " + (assets.length ? 'no longer within playback range' : 'asset-list is empty') + " " + this.timelinePos + " " + interstitial);
|
|
27139
|
+
this.log(interstitial.error.message);
|
|
27117
27140
|
this.updateSchedule(true);
|
|
27118
27141
|
this.primaryFallback(interstitial);
|
|
27119
27142
|
return;
|
|
@@ -34941,7 +34964,7 @@
|
|
|
34941
34964
|
var _this2 = this;
|
|
34942
34965
|
var hls = this.hls;
|
|
34943
34966
|
// if any URL found on new audio track, it is an alternate audio track
|
|
34944
|
-
var fromAltAudio = this.altAudio
|
|
34967
|
+
var fromAltAudio = this.altAudio !== 0;
|
|
34945
34968
|
var altAudio = useAlternateAudio(data.url, hls);
|
|
34946
34969
|
// if we switch on main audio, ensure that main fragment scheduling is synced with media.buffered
|
|
34947
34970
|
// don't do anything if we switch to alt audio: audio stream controller is handling it.
|
|
@@ -34967,6 +34990,7 @@
|
|
|
34967
34990
|
}
|
|
34968
34991
|
// If switching from alt to main audio, flush all audio and trigger track switched
|
|
34969
34992
|
if (fromAltAudio) {
|
|
34993
|
+
this.altAudio = 0;
|
|
34970
34994
|
this.fragmentTracker.removeAllFragments();
|
|
34971
34995
|
hls.once(Events.BUFFER_FLUSHED, function () {
|
|
34972
34996
|
if (!_this2.hls) {
|
|
@@ -35817,11 +35841,19 @@
|
|
|
35817
35841
|
return b !== 0;
|
|
35818
35842
|
})) {
|
|
35819
35843
|
this.log("Using keyId found in init segment " + arrayToHex(keyId));
|
|
35820
|
-
keyInfo.decryptdata.keyId = keyId;
|
|
35821
35844
|
LevelKey.setKeyIdForUri(keyInfo.decryptdata.uri, keyId);
|
|
35845
|
+
} else {
|
|
35846
|
+
keyId = LevelKey.addKeyIdForUri(keyInfo.decryptdata.uri);
|
|
35847
|
+
this.log("Generating keyId to patch media " + arrayToHex(keyId));
|
|
35822
35848
|
}
|
|
35849
|
+
keyInfo.decryptdata.keyId = keyId;
|
|
35823
35850
|
}
|
|
35824
35851
|
}
|
|
35852
|
+
if (!keyInfo.decryptdata.keyId && !isMediaFragment(frag)) {
|
|
35853
|
+
// Resolve so that unencrypted init segment is loaded
|
|
35854
|
+
// key id is extracted from tenc box when processing key for next segment above
|
|
35855
|
+
return Promise.resolve(keyLoadedData);
|
|
35856
|
+
}
|
|
35825
35857
|
var keySessionContextPromise = this.emeController.loadKey(keyLoadedData);
|
|
35826
35858
|
return (keyInfo.keyLoadPromise = keySessionContextPromise.then(function (keySessionContext) {
|
|
35827
35859
|
keyInfo.mediaKeySessionContext = keySessionContext;
|
package/dist/hls.js.d.ts
CHANGED
|
@@ -1496,6 +1496,7 @@ export declare class FragmentTracker implements ComponentAPI {
|
|
|
1496
1496
|
* Partially loaded fragments will be registered as a partial fragment
|
|
1497
1497
|
*/
|
|
1498
1498
|
detectPartialFragments(data: FragBufferedData): void;
|
|
1499
|
+
private bufferedEnd;
|
|
1499
1500
|
private removeParts;
|
|
1500
1501
|
fragBuffered(frag: MediaFragment, force?: true): void;
|
|
1501
1502
|
private getBufferedTimes;
|
|
@@ -2490,6 +2491,7 @@ export declare class InterstitialsController extends Logger implements NetworkCo
|
|
|
2490
2491
|
private createAsset;
|
|
2491
2492
|
private createAssetPlayer;
|
|
2492
2493
|
private clearInterstitial;
|
|
2494
|
+
private clearAssetPlayers;
|
|
2493
2495
|
private resetAssetPlayer;
|
|
2494
2496
|
private clearAssetPlayer;
|
|
2495
2497
|
private emptyPlayerQueue;
|
|
@@ -2760,6 +2762,7 @@ export declare class LevelKey implements DecryptData {
|
|
|
2760
2762
|
pssh: Uint8Array<ArrayBuffer> | null;
|
|
2761
2763
|
static clearKeyUriToKeyIdMap(): void;
|
|
2762
2764
|
static setKeyIdForUri(uri: string, keyId: Uint8Array<ArrayBuffer>): void;
|
|
2765
|
+
static addKeyIdForUri(uri: string): Uint8Array<ArrayBuffer>;
|
|
2763
2766
|
constructor(method: string, uri: string, format: string, formatversions?: number[], iv?: Uint8Array<ArrayBuffer> | null, keyId?: string);
|
|
2764
2767
|
matches(key: LevelKey): boolean;
|
|
2765
2768
|
isSupported(): boolean;
|