hls.js 1.5.2-0.canary.9934 → 1.5.3
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-demo.js +0 -5
- package/dist/hls-demo.js.map +1 -1
- package/dist/hls.js +757 -883
- package/dist/hls.js.d.ts +47 -56
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +477 -600
- 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 +335 -446
- 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 +572 -681
- 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 +11 -11
- package/src/config.ts +2 -3
- package/src/controller/abr-controller.ts +22 -22
- package/src/controller/audio-stream-controller.ts +14 -11
- package/src/controller/audio-track-controller.ts +1 -1
- package/src/controller/base-playlist-controller.ts +7 -7
- package/src/controller/base-stream-controller.ts +29 -47
- package/src/controller/buffer-controller.ts +11 -10
- package/src/controller/cap-level-controller.ts +2 -1
- package/src/controller/cmcd-controller.ts +3 -25
- package/src/controller/content-steering-controller.ts +6 -8
- package/src/controller/eme-controller.ts +22 -9
- package/src/controller/error-controller.ts +8 -6
- package/src/controller/fps-controller.ts +3 -2
- package/src/controller/gap-controller.ts +16 -43
- package/src/controller/latency-controller.ts +11 -9
- package/src/controller/level-controller.ts +17 -5
- package/src/controller/stream-controller.ts +31 -24
- package/src/controller/subtitle-stream-controller.ts +14 -13
- package/src/controller/subtitle-track-controller.ts +3 -5
- package/src/controller/timeline-controller.ts +30 -23
- package/src/crypt/aes-crypto.ts +2 -21
- package/src/crypt/decrypter.ts +18 -32
- package/src/crypt/fast-aes-key.ts +5 -24
- package/src/demux/audio/adts.ts +4 -9
- package/src/demux/sample-aes.ts +0 -2
- package/src/demux/transmuxer-interface.ts +12 -4
- package/src/demux/transmuxer-worker.ts +4 -4
- package/src/demux/transmuxer.ts +3 -16
- package/src/demux/tsdemuxer.ts +17 -12
- package/src/events.ts +0 -7
- package/src/hls.ts +20 -33
- package/src/loader/fragment-loader.ts +2 -9
- package/src/loader/key-loader.ts +0 -2
- package/src/loader/level-key.ts +9 -10
- package/src/remux/mp4-remuxer.ts +4 -20
- package/src/task-loop.ts +2 -5
- package/src/types/demuxer.ts +0 -1
- package/src/types/events.ts +0 -4
- package/src/utils/codecs.ts +4 -33
- package/src/utils/logger.ts +24 -53
- package/src/crypt/decrypter-aes-mode.ts +0 -4
- package/src/utils/encryption-methods-util.ts +0 -21
package/dist/hls.js
CHANGED
@@ -394,7 +394,6 @@
|
|
394
394
|
Events["MEDIA_ATTACHED"] = "hlsMediaAttached";
|
395
395
|
Events["MEDIA_DETACHING"] = "hlsMediaDetaching";
|
396
396
|
Events["MEDIA_DETACHED"] = "hlsMediaDetached";
|
397
|
-
Events["MEDIA_ENDED"] = "hlsMediaEnded";
|
398
397
|
Events["BUFFER_RESET"] = "hlsBufferReset";
|
399
398
|
Events["BUFFER_CODECS"] = "hlsBufferCodecs";
|
400
399
|
Events["BUFFER_CREATED"] = "hlsBufferCreated";
|
@@ -508,21 +507,6 @@
|
|
508
507
|
return ErrorDetails;
|
509
508
|
}({});
|
510
509
|
|
511
|
-
var Logger = function Logger(label, logger) {
|
512
|
-
this.trace = void 0;
|
513
|
-
this.debug = void 0;
|
514
|
-
this.log = void 0;
|
515
|
-
this.warn = void 0;
|
516
|
-
this.info = void 0;
|
517
|
-
this.error = void 0;
|
518
|
-
var lb = "[" + label + "]:";
|
519
|
-
this.trace = noop;
|
520
|
-
this.debug = logger.debug.bind(null, lb);
|
521
|
-
this.log = logger.log.bind(null, lb);
|
522
|
-
this.warn = logger.warn.bind(null, lb);
|
523
|
-
this.info = logger.info.bind(null, lb);
|
524
|
-
this.error = logger.error.bind(null, lb);
|
525
|
-
};
|
526
510
|
var noop = function noop() {};
|
527
511
|
var fakeLogger = {
|
528
512
|
trace: noop,
|
@@ -532,9 +516,7 @@
|
|
532
516
|
info: noop,
|
533
517
|
error: noop
|
534
518
|
};
|
535
|
-
|
536
|
-
return _extends({}, fakeLogger);
|
537
|
-
}
|
519
|
+
var exportedLogger = fakeLogger;
|
538
520
|
|
539
521
|
// let lastCallTime;
|
540
522
|
// function formatMsgWithTimeInfo(type, msg) {
|
@@ -545,36 +527,38 @@
|
|
545
527
|
// return msg;
|
546
528
|
// }
|
547
529
|
|
548
|
-
function consolePrintFn(type
|
530
|
+
function consolePrintFn(type) {
|
549
531
|
var func = self.console[type];
|
550
|
-
|
532
|
+
if (func) {
|
533
|
+
return func.bind(self.console, "[" + type + "] >");
|
534
|
+
}
|
535
|
+
return noop;
|
551
536
|
}
|
552
|
-
function
|
553
|
-
|
537
|
+
function exportLoggerFunctions(debugConfig) {
|
538
|
+
for (var _len = arguments.length, functions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
539
|
+
functions[_key - 1] = arguments[_key];
|
540
|
+
}
|
541
|
+
functions.forEach(function (type) {
|
542
|
+
exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);
|
543
|
+
});
|
554
544
|
}
|
555
|
-
|
556
|
-
function enableLogs(debugConfig, context, id) {
|
545
|
+
function enableLogs(debugConfig, id) {
|
557
546
|
// check that console is available
|
558
|
-
var newLogger = createLogger();
|
559
547
|
if (typeof console === 'object' && debugConfig === true || typeof debugConfig === 'object') {
|
560
|
-
|
548
|
+
exportLoggerFunctions(debugConfig,
|
561
549
|
// Remove out from list here to hard-disable a log-level
|
562
550
|
// 'trace',
|
563
|
-
'debug', 'log', 'info', 'warn', 'error'
|
564
|
-
keys.forEach(function (key) {
|
565
|
-
newLogger[key] = getLoggerFn(key, debugConfig, id);
|
566
|
-
});
|
551
|
+
'debug', 'log', 'info', 'warn', 'error');
|
567
552
|
// Some browsers don't allow to use bind on console object anyway
|
568
553
|
// fallback to default if needed
|
569
554
|
try {
|
570
|
-
|
555
|
+
exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.5.3");
|
571
556
|
} catch (e) {
|
572
|
-
|
573
|
-
return createLogger();
|
557
|
+
exportedLogger = fakeLogger;
|
574
558
|
}
|
559
|
+
} else {
|
560
|
+
exportedLogger = fakeLogger;
|
575
561
|
}
|
576
|
-
exportedLogger = newLogger;
|
577
|
-
return newLogger;
|
578
562
|
}
|
579
563
|
var logger = exportedLogger;
|
580
564
|
|
@@ -1269,26 +1253,6 @@
|
|
1269
1253
|
});
|
1270
1254
|
}
|
1271
1255
|
|
1272
|
-
var DecrypterAesMode = {
|
1273
|
-
cbc: 0,
|
1274
|
-
ctr: 1
|
1275
|
-
};
|
1276
|
-
|
1277
|
-
function isFullSegmentEncryption(method) {
|
1278
|
-
return method === 'AES-128' || method === 'AES-256' || method === 'AES-256-CTR';
|
1279
|
-
}
|
1280
|
-
function getAesModeFromFullSegmentMethod(method) {
|
1281
|
-
switch (method) {
|
1282
|
-
case 'AES-128':
|
1283
|
-
case 'AES-256':
|
1284
|
-
return DecrypterAesMode.cbc;
|
1285
|
-
case 'AES-256-CTR':
|
1286
|
-
return DecrypterAesMode.ctr;
|
1287
|
-
default:
|
1288
|
-
throw new Error("invalid full segment method " + method);
|
1289
|
-
}
|
1290
|
-
}
|
1291
|
-
|
1292
1256
|
/** returns `undefined` is `self` is missing, e.g. in node */
|
1293
1257
|
var optionalSelf = typeof self !== 'undefined' ? self : undefined;
|
1294
1258
|
|
@@ -2947,13 +2911,13 @@
|
|
2947
2911
|
this.keyFormatVersions = formatversions;
|
2948
2912
|
this.iv = iv;
|
2949
2913
|
this.encrypted = method ? method !== 'NONE' : false;
|
2950
|
-
this.isCommonEncryption = this.encrypted &&
|
2914
|
+
this.isCommonEncryption = this.encrypted && method !== 'AES-128';
|
2951
2915
|
}
|
2952
2916
|
var _proto = LevelKey.prototype;
|
2953
2917
|
_proto.isSupported = function isSupported() {
|
2954
2918
|
// If it's Segment encryption or No encryption, just select that key system
|
2955
2919
|
if (this.method) {
|
2956
|
-
if (
|
2920
|
+
if (this.method === 'AES-128' || this.method === 'NONE') {
|
2957
2921
|
return true;
|
2958
2922
|
}
|
2959
2923
|
if (this.keyFormat === 'identity') {
|
@@ -2975,13 +2939,14 @@
|
|
2975
2939
|
if (!this.encrypted || !this.uri) {
|
2976
2940
|
return null;
|
2977
2941
|
}
|
2978
|
-
if (
|
2942
|
+
if (this.method === 'AES-128' && this.uri && !this.iv) {
|
2979
2943
|
if (typeof sn !== 'number') {
|
2980
2944
|
// We are fetching decryption data for a initialization segment
|
2981
|
-
// If the segment was encrypted with AES-128
|
2945
|
+
// If the segment was encrypted with AES-128
|
2982
2946
|
// It must have an IV defined. We cannot substitute the Segment Number in.
|
2983
|
-
|
2984
|
-
|
2947
|
+
if (this.method === 'AES-128' && !this.iv) {
|
2948
|
+
logger.warn("missing IV for initialization segment with method=\"" + this.method + "\" - compliance issue");
|
2949
|
+
}
|
2985
2950
|
// Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
|
2986
2951
|
sn = 0;
|
2987
2952
|
}
|
@@ -3275,28 +3240,23 @@
|
|
3275
3240
|
if (CODEC_COMPATIBLE_NAMES[lowerCaseCodec]) {
|
3276
3241
|
return CODEC_COMPATIBLE_NAMES[lowerCaseCodec];
|
3277
3242
|
}
|
3243
|
+
|
3244
|
+
// Idealy fLaC and Opus would be first (spec-compliant) but
|
3245
|
+
// some browsers will report that fLaC is supported then fail.
|
3246
|
+
// see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
|
3278
3247
|
var codecsToCheck = {
|
3279
|
-
// Idealy fLaC and Opus would be first (spec-compliant) but
|
3280
|
-
// some browsers will report that fLaC is supported then fail.
|
3281
|
-
// see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
|
3282
3248
|
flac: ['flac', 'fLaC', 'FLAC'],
|
3283
|
-
opus: ['opus', 'Opus']
|
3284
|
-
// Replace audio codec info if browser does not support mp4a.40.34,
|
3285
|
-
// and demuxer can fallback to 'audio/mpeg' or 'audio/mp4;codecs="mp3"'
|
3286
|
-
'mp4a.40.34': ['mp3']
|
3249
|
+
opus: ['opus', 'Opus']
|
3287
3250
|
}[lowerCaseCodec];
|
3288
3251
|
for (var i = 0; i < codecsToCheck.length; i++) {
|
3289
|
-
var _getMediaSource;
|
3290
3252
|
if (isCodecMediaSourceSupported(codecsToCheck[i], 'audio', preferManagedMediaSource)) {
|
3291
3253
|
CODEC_COMPATIBLE_NAMES[lowerCaseCodec] = codecsToCheck[i];
|
3292
3254
|
return codecsToCheck[i];
|
3293
|
-
} else if (codecsToCheck[i] === 'mp3' && (_getMediaSource = getMediaSource(preferManagedMediaSource)) != null && _getMediaSource.isTypeSupported('audio/mpeg')) {
|
3294
|
-
return '';
|
3295
3255
|
}
|
3296
3256
|
}
|
3297
3257
|
return lowerCaseCodec;
|
3298
3258
|
}
|
3299
|
-
var AUDIO_CODEC_REGEXP = /flac|opus
|
3259
|
+
var AUDIO_CODEC_REGEXP = /flac|opus/i;
|
3300
3260
|
function getCodecCompatibleName(codec, preferManagedMediaSource) {
|
3301
3261
|
if (preferManagedMediaSource === void 0) {
|
3302
3262
|
preferManagedMediaSource = true;
|
@@ -3324,18 +3284,6 @@
|
|
3324
3284
|
}
|
3325
3285
|
return codec;
|
3326
3286
|
}
|
3327
|
-
function getM2TSSupportedAudioTypes(preferManagedMediaSource) {
|
3328
|
-
var MediaSource = getMediaSource(preferManagedMediaSource) || {
|
3329
|
-
isTypeSupported: function isTypeSupported() {
|
3330
|
-
return false;
|
3331
|
-
}
|
3332
|
-
};
|
3333
|
-
return {
|
3334
|
-
mpeg: MediaSource.isTypeSupported('audio/mpeg'),
|
3335
|
-
mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'),
|
3336
|
-
ac3: MediaSource.isTypeSupported('audio/mp4; codecs="ac-3"')
|
3337
|
-
};
|
3338
|
-
}
|
3339
3287
|
|
3340
3288
|
var MASTER_PLAYLIST_REGEX = /#EXT-X-STREAM-INF:([^\r\n]*)(?:[\r\n](?:#[^\r\n]*)?)*([^\r\n]+)|#EXT-X-(SESSION-DATA|SESSION-KEY|DEFINE|CONTENT-STEERING|START):([^\r\n]*)[\r\n]+/g;
|
3341
3289
|
var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g;
|
@@ -4999,43 +4947,8 @@
|
|
4999
4947
|
this.currentTime = 0;
|
5000
4948
|
this.stallCount = 0;
|
5001
4949
|
this._latency = null;
|
5002
|
-
this.
|
5003
|
-
|
5004
|
-
levelDetails = _this.levelDetails;
|
5005
|
-
if (!media || !levelDetails) {
|
5006
|
-
return;
|
5007
|
-
}
|
5008
|
-
_this.currentTime = media.currentTime;
|
5009
|
-
var latency = _this.computeLatency();
|
5010
|
-
if (latency === null) {
|
5011
|
-
return;
|
5012
|
-
}
|
5013
|
-
_this._latency = latency;
|
5014
|
-
|
5015
|
-
// Adapt playbackRate to meet target latency in low-latency mode
|
5016
|
-
var _this$config = _this.config,
|
5017
|
-
lowLatencyMode = _this$config.lowLatencyMode,
|
5018
|
-
maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
|
5019
|
-
if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1 || !levelDetails.live) {
|
5020
|
-
return;
|
5021
|
-
}
|
5022
|
-
var targetLatency = _this.targetLatency;
|
5023
|
-
if (targetLatency === null) {
|
5024
|
-
return;
|
5025
|
-
}
|
5026
|
-
var distanceFromTarget = latency - targetLatency;
|
5027
|
-
// Only adjust playbackRate when within one target duration of targetLatency
|
5028
|
-
// and more than one second from under-buffering.
|
5029
|
-
// Playback further than one target duration from target can be considered DVR playback.
|
5030
|
-
var liveMinLatencyDuration = Math.min(_this.maxLatency, targetLatency + levelDetails.targetduration);
|
5031
|
-
var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
|
5032
|
-
if (inLiveRange && distanceFromTarget > 0.05 && _this.forwardBufferLength > 1) {
|
5033
|
-
var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
|
5034
|
-
var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - _this.edgeStalled)) * 20) / 20;
|
5035
|
-
media.playbackRate = Math.min(max, Math.max(1, rate));
|
5036
|
-
} else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
|
5037
|
-
media.playbackRate = 1;
|
5038
|
-
}
|
4950
|
+
this.timeupdateHandler = function () {
|
4951
|
+
return _this.timeupdate();
|
5039
4952
|
};
|
5040
4953
|
this.hls = hls;
|
5041
4954
|
this.config = hls.config;
|
@@ -5047,7 +4960,7 @@
|
|
5047
4960
|
this.onMediaDetaching();
|
5048
4961
|
this.levelDetails = null;
|
5049
4962
|
// @ts-ignore
|
5050
|
-
this.hls = null;
|
4963
|
+
this.hls = this.timeupdateHandler = null;
|
5051
4964
|
};
|
5052
4965
|
_proto.registerListeners = function registerListeners() {
|
5053
4966
|
this.hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
@@ -5065,11 +4978,11 @@
|
|
5065
4978
|
};
|
5066
4979
|
_proto.onMediaAttached = function onMediaAttached(event, data) {
|
5067
4980
|
this.media = data.media;
|
5068
|
-
this.media.addEventListener('timeupdate', this.
|
4981
|
+
this.media.addEventListener('timeupdate', this.timeupdateHandler);
|
5069
4982
|
};
|
5070
4983
|
_proto.onMediaDetaching = function onMediaDetaching() {
|
5071
4984
|
if (this.media) {
|
5072
|
-
this.media.removeEventListener('timeupdate', this.
|
4985
|
+
this.media.removeEventListener('timeupdate', this.timeupdateHandler);
|
5073
4986
|
this.media = null;
|
5074
4987
|
}
|
5075
4988
|
};
|
@@ -5082,10 +4995,10 @@
|
|
5082
4995
|
var details = _ref.details;
|
5083
4996
|
this.levelDetails = details;
|
5084
4997
|
if (details.advanced) {
|
5085
|
-
this.
|
4998
|
+
this.timeupdate();
|
5086
4999
|
}
|
5087
5000
|
if (!details.live && this.media) {
|
5088
|
-
this.media.removeEventListener('timeupdate', this.
|
5001
|
+
this.media.removeEventListener('timeupdate', this.timeupdateHandler);
|
5089
5002
|
}
|
5090
5003
|
};
|
5091
5004
|
_proto.onError = function onError(event, data) {
|
@@ -5095,7 +5008,45 @@
|
|
5095
5008
|
}
|
5096
5009
|
this.stallCount++;
|
5097
5010
|
if ((_this$levelDetails = this.levelDetails) != null && _this$levelDetails.live) {
|
5098
|
-
|
5011
|
+
logger.warn('[playback-rate-controller]: Stall detected, adjusting target latency');
|
5012
|
+
}
|
5013
|
+
};
|
5014
|
+
_proto.timeupdate = function timeupdate() {
|
5015
|
+
var media = this.media,
|
5016
|
+
levelDetails = this.levelDetails;
|
5017
|
+
if (!media || !levelDetails) {
|
5018
|
+
return;
|
5019
|
+
}
|
5020
|
+
this.currentTime = media.currentTime;
|
5021
|
+
var latency = this.computeLatency();
|
5022
|
+
if (latency === null) {
|
5023
|
+
return;
|
5024
|
+
}
|
5025
|
+
this._latency = latency;
|
5026
|
+
|
5027
|
+
// Adapt playbackRate to meet target latency in low-latency mode
|
5028
|
+
var _this$config = this.config,
|
5029
|
+
lowLatencyMode = _this$config.lowLatencyMode,
|
5030
|
+
maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
|
5031
|
+
if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1 || !levelDetails.live) {
|
5032
|
+
return;
|
5033
|
+
}
|
5034
|
+
var targetLatency = this.targetLatency;
|
5035
|
+
if (targetLatency === null) {
|
5036
|
+
return;
|
5037
|
+
}
|
5038
|
+
var distanceFromTarget = latency - targetLatency;
|
5039
|
+
// Only adjust playbackRate when within one target duration of targetLatency
|
5040
|
+
// and more than one second from under-buffering.
|
5041
|
+
// Playback further than one target duration from target can be considered DVR playback.
|
5042
|
+
var liveMinLatencyDuration = Math.min(this.maxLatency, targetLatency + levelDetails.targetduration);
|
5043
|
+
var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
|
5044
|
+
if (inLiveRange && distanceFromTarget > 0.05 && this.forwardBufferLength > 1) {
|
5045
|
+
var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
|
5046
|
+
var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - this.edgeStalled)) * 20) / 20;
|
5047
|
+
media.playbackRate = Math.min(max, Math.max(1, rate));
|
5048
|
+
} else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
|
5049
|
+
media.playbackRate = 1;
|
5099
5050
|
}
|
5100
5051
|
};
|
5101
5052
|
_proto.estimateLiveEdge = function estimateLiveEdge() {
|
@@ -6003,17 +5954,19 @@
|
|
6003
5954
|
MoveAllAlternatesMatchingHDCP: 2,
|
6004
5955
|
SwitchToSDR: 4
|
6005
5956
|
}; // Reserved for future use
|
6006
|
-
var ErrorController = /*#__PURE__*/function (
|
6007
|
-
_inheritsLoose(ErrorController, _Logger);
|
5957
|
+
var ErrorController = /*#__PURE__*/function () {
|
6008
5958
|
function ErrorController(hls) {
|
6009
|
-
|
6010
|
-
|
6011
|
-
|
6012
|
-
|
6013
|
-
|
6014
|
-
|
6015
|
-
|
6016
|
-
|
5959
|
+
this.hls = void 0;
|
5960
|
+
this.playlistError = 0;
|
5961
|
+
this.penalizedRenditions = {};
|
5962
|
+
this.log = void 0;
|
5963
|
+
this.warn = void 0;
|
5964
|
+
this.error = void 0;
|
5965
|
+
this.hls = hls;
|
5966
|
+
this.log = logger.log.bind(logger, "[info]:");
|
5967
|
+
this.warn = logger.warn.bind(logger, "[warning]:");
|
5968
|
+
this.error = logger.error.bind(logger, "[error]:");
|
5969
|
+
this.registerListeners();
|
6017
5970
|
}
|
6018
5971
|
var _proto = ErrorController.prototype;
|
6019
5972
|
_proto.registerListeners = function registerListeners() {
|
@@ -6369,19 +6322,19 @@
|
|
6369
6322
|
}
|
6370
6323
|
};
|
6371
6324
|
return ErrorController;
|
6372
|
-
}(
|
6325
|
+
}();
|
6373
6326
|
|
6374
|
-
var BasePlaylistController = /*#__PURE__*/function (
|
6375
|
-
_inheritsLoose(BasePlaylistController, _Logger);
|
6327
|
+
var BasePlaylistController = /*#__PURE__*/function () {
|
6376
6328
|
function BasePlaylistController(hls, logPrefix) {
|
6377
|
-
|
6378
|
-
|
6379
|
-
|
6380
|
-
|
6381
|
-
|
6382
|
-
|
6383
|
-
|
6384
|
-
|
6329
|
+
this.hls = void 0;
|
6330
|
+
this.timer = -1;
|
6331
|
+
this.requestScheduled = -1;
|
6332
|
+
this.canLoad = false;
|
6333
|
+
this.log = void 0;
|
6334
|
+
this.warn = void 0;
|
6335
|
+
this.log = logger.log.bind(logger, logPrefix + ":");
|
6336
|
+
this.warn = logger.warn.bind(logger, logPrefix + ":");
|
6337
|
+
this.hls = hls;
|
6385
6338
|
}
|
6386
6339
|
var _proto = BasePlaylistController.prototype;
|
6387
6340
|
_proto.destroy = function destroy() {
|
@@ -6414,7 +6367,7 @@
|
|
6414
6367
|
try {
|
6415
6368
|
uri = new self.URL(attr.URI, previous.url).href;
|
6416
6369
|
} catch (error) {
|
6417
|
-
|
6370
|
+
logger.warn("Could not construct new URL for Rendition Report: " + error);
|
6418
6371
|
uri = attr.URI || '';
|
6419
6372
|
}
|
6420
6373
|
// Use exact match. Otherwise, the last partial match, if any, will be used
|
@@ -6453,7 +6406,7 @@
|
|
6453
6406
|
return this.timer === -1 && this.requestScheduled === -1 && this.shouldLoadPlaylist(playlist);
|
6454
6407
|
};
|
6455
6408
|
_proto.playlistLoaded = function playlistLoaded(index, data, previousDetails) {
|
6456
|
-
var
|
6409
|
+
var _this = this;
|
6457
6410
|
var details = data.details,
|
6458
6411
|
stats = data.stats;
|
6459
6412
|
|
@@ -6558,7 +6511,7 @@
|
|
6558
6511
|
// );
|
6559
6512
|
|
6560
6513
|
this.timer = self.setTimeout(function () {
|
6561
|
-
return
|
6514
|
+
return _this.loadPlaylist(deliveryDirectives);
|
6562
6515
|
}, estimatedTimeUntilUpdate);
|
6563
6516
|
} else {
|
6564
6517
|
this.clearTimer();
|
@@ -6574,7 +6527,7 @@
|
|
6574
6527
|
return new HlsUrlParameters(msn, part, skip);
|
6575
6528
|
};
|
6576
6529
|
_proto.checkRetry = function checkRetry(errorEvent) {
|
6577
|
-
var
|
6530
|
+
var _this2 = this;
|
6578
6531
|
var errorDetails = errorEvent.details;
|
6579
6532
|
var isTimeout = isTimeoutError(errorEvent);
|
6580
6533
|
var errorAction = errorEvent.errorAction;
|
@@ -6598,7 +6551,7 @@
|
|
6598
6551
|
var delay = getRetryDelay(retryConfig, retryCount);
|
6599
6552
|
// Schedule level/track reload
|
6600
6553
|
this.timer = self.setTimeout(function () {
|
6601
|
-
return
|
6554
|
+
return _this2.loadPlaylist();
|
6602
6555
|
}, delay);
|
6603
6556
|
this.warn("Retrying playlist loading " + (retryCount + 1) + "/" + retryConfig.maxNumRetry + " after \"" + errorDetails + "\" in " + delay + "ms");
|
6604
6557
|
}
|
@@ -6609,7 +6562,7 @@
|
|
6609
6562
|
return retry;
|
6610
6563
|
};
|
6611
6564
|
return BasePlaylistController;
|
6612
|
-
}(
|
6565
|
+
}();
|
6613
6566
|
|
6614
6567
|
/*
|
6615
6568
|
* compute an Exponential Weighted moving average
|
@@ -7211,33 +7164,30 @@
|
|
7211
7164
|
return -1;
|
7212
7165
|
}
|
7213
7166
|
|
7214
|
-
var AbrController = /*#__PURE__*/function (
|
7215
|
-
_inheritsLoose(AbrController, _Logger);
|
7167
|
+
var AbrController = /*#__PURE__*/function () {
|
7216
7168
|
function AbrController(_hls) {
|
7217
|
-
var _this;
|
7218
|
-
|
7219
|
-
|
7220
|
-
|
7221
|
-
|
7222
|
-
|
7223
|
-
|
7224
|
-
|
7225
|
-
|
7226
|
-
|
7227
|
-
|
7228
|
-
|
7229
|
-
|
7230
|
-
|
7231
|
-
_this.bwEstimator = void 0;
|
7169
|
+
var _this = this;
|
7170
|
+
this.hls = void 0;
|
7171
|
+
this.lastLevelLoadSec = 0;
|
7172
|
+
this.lastLoadedFragLevel = -1;
|
7173
|
+
this.firstSelection = -1;
|
7174
|
+
this._nextAutoLevel = -1;
|
7175
|
+
this.nextAutoLevelKey = '';
|
7176
|
+
this.audioTracksByGroup = null;
|
7177
|
+
this.codecTiers = null;
|
7178
|
+
this.timer = -1;
|
7179
|
+
this.fragCurrent = null;
|
7180
|
+
this.partCurrent = null;
|
7181
|
+
this.bitrateTestDelay = 0;
|
7182
|
+
this.bwEstimator = void 0;
|
7232
7183
|
/*
|
7233
7184
|
This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
|
7234
7185
|
quickly enough to prevent underbuffering
|
7235
7186
|
*/
|
7236
|
-
|
7237
|
-
var
|
7238
|
-
|
7239
|
-
|
7240
|
-
hls = _assertThisInitialize.hls;
|
7187
|
+
this._abandonRulesCheck = function () {
|
7188
|
+
var frag = _this.fragCurrent,
|
7189
|
+
part = _this.partCurrent,
|
7190
|
+
hls = _this.hls;
|
7241
7191
|
var autoLevelEnabled = hls.autoLevelEnabled,
|
7242
7192
|
media = hls.media;
|
7243
7193
|
if (!frag || !media) {
|
@@ -7326,22 +7276,21 @@
|
|
7326
7276
|
_this.resetEstimator(nextLoadLevelBitrate);
|
7327
7277
|
}
|
7328
7278
|
_this.clearTimer();
|
7329
|
-
|
7279
|
+
logger.warn("[abr] Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of level " + frag.level + " is loading too slowly;\n Time to underbuffer: " + bufferStarvationDelay.toFixed(3) + " s\n Estimated load time for current fragment: " + fragLoadedDelay.toFixed(3) + " s\n Estimated load time for down switch fragment: " + fragLevelNextLoadedDelay.toFixed(3) + " s\n TTFB estimate: " + (ttfb | 0) + " ms\n Current BW estimate: " + (isFiniteNumber(bwEstimate) ? bwEstimate | 0 : 'Unknown') + " bps\n New BW estimate: " + (_this.getBwEstimate() | 0) + " bps\n Switching to level " + nextLoadLevel + " @ " + (nextLoadLevelBitrate | 0) + " bps");
|
7330
7280
|
hls.trigger(Events.FRAG_LOAD_EMERGENCY_ABORTED, {
|
7331
7281
|
frag: frag,
|
7332
7282
|
part: part,
|
7333
7283
|
stats: stats
|
7334
7284
|
});
|
7335
7285
|
};
|
7336
|
-
|
7337
|
-
|
7338
|
-
|
7339
|
-
return _this;
|
7286
|
+
this.hls = _hls;
|
7287
|
+
this.bwEstimator = this.initEstimator();
|
7288
|
+
this.registerListeners();
|
7340
7289
|
}
|
7341
7290
|
var _proto = AbrController.prototype;
|
7342
7291
|
_proto.resetEstimator = function resetEstimator(abrEwmaDefaultEstimate) {
|
7343
7292
|
if (abrEwmaDefaultEstimate) {
|
7344
|
-
|
7293
|
+
logger.log("setting initial bwe to " + abrEwmaDefaultEstimate);
|
7345
7294
|
this.hls.config.abrEwmaDefaultEstimate = abrEwmaDefaultEstimate;
|
7346
7295
|
}
|
7347
7296
|
this.firstSelection = -1;
|
@@ -7593,13 +7542,13 @@
|
|
7593
7542
|
// cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
|
7594
7543
|
var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay;
|
7595
7544
|
maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
|
7596
|
-
|
7545
|
+
logger.info("[abr] bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms");
|
7597
7546
|
// don't use conservative factor on bitrate test
|
7598
7547
|
bwFactor = bwUpFactor = 1;
|
7599
7548
|
}
|
7600
7549
|
}
|
7601
7550
|
var bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor);
|
7602
|
-
|
7551
|
+
logger.info("[abr] " + (bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty') + ", optimal quality level " + bestLevel);
|
7603
7552
|
if (bestLevel > -1) {
|
7604
7553
|
return bestLevel;
|
7605
7554
|
}
|
@@ -7655,7 +7604,7 @@
|
|
7655
7604
|
currentVideoRange = preferHDR ? videoRanges[videoRanges.length - 1] : videoRanges[0];
|
7656
7605
|
currentFrameRate = minFramerate;
|
7657
7606
|
currentBw = Math.max(currentBw, minBitrate);
|
7658
|
-
|
7607
|
+
logger.log("[abr] picked start tier " + JSON.stringify(startTier));
|
7659
7608
|
} else {
|
7660
7609
|
currentCodecSet = level == null ? void 0 : level.codecSet;
|
7661
7610
|
currentVideoRange = level == null ? void 0 : level.videoRange;
|
@@ -7664,7 +7613,7 @@
|
|
7664
7613
|
var ttfbEstimateSec = this.bwEstimator.getEstimateTTFB() / 1000;
|
7665
7614
|
var levelsSkipped = [];
|
7666
7615
|
var _loop = function _loop() {
|
7667
|
-
var _levelInfo$supportedR
|
7616
|
+
var _levelInfo$supportedR;
|
7668
7617
|
var levelInfo = levels[i];
|
7669
7618
|
var upSwitch = i > selectionBaseLevel;
|
7670
7619
|
if (!levelInfo) {
|
@@ -7679,11 +7628,11 @@
|
|
7679
7628
|
var levels = _this2.hls.levels;
|
7680
7629
|
var index = levels.indexOf(levelInfo);
|
7681
7630
|
if (decodingInfo.error) {
|
7682
|
-
|
7631
|
+
logger.warn("[abr] MediaCapabilities decodingInfo error: \"" + decodingInfo.error + "\" for level " + index + " " + JSON.stringify(decodingInfo));
|
7683
7632
|
} else if (!decodingInfo.supported) {
|
7684
|
-
|
7633
|
+
logger.warn("[abr] Unsupported MediaCapabilities decodingInfo result for level " + index + " " + JSON.stringify(decodingInfo));
|
7685
7634
|
if (index > -1 && levels.length > 1) {
|
7686
|
-
|
7635
|
+
logger.log("[abr] Removing unsupported level " + index);
|
7687
7636
|
_this2.hls.removeLevel(index);
|
7688
7637
|
}
|
7689
7638
|
}
|
@@ -7695,7 +7644,7 @@
|
|
7695
7644
|
|
7696
7645
|
// skip candidates which change codec-family or video-range,
|
7697
7646
|
// and which decrease or increase frame-rate for up and down-switch respectfully
|
7698
|
-
if (currentCodecSet && levelInfo.codecSet !== currentCodecSet || currentVideoRange && levelInfo.videoRange !== currentVideoRange || upSwitch && currentFrameRate > levelInfo.frameRate || !upSwitch && currentFrameRate > 0 && currentFrameRate < levelInfo.frameRate ||
|
7647
|
+
if (currentCodecSet && levelInfo.codecSet !== currentCodecSet || currentVideoRange && levelInfo.videoRange !== currentVideoRange || upSwitch && currentFrameRate > levelInfo.frameRate || !upSwitch && currentFrameRate > 0 && currentFrameRate < levelInfo.frameRate || levelInfo.supportedResult && !((_levelInfo$supportedR = levelInfo.supportedResult.decodingInfoResults) != null && _levelInfo$supportedR[0].smooth)) {
|
7699
7648
|
levelsSkipped.push(i);
|
7700
7649
|
return 0; // continue
|
7701
7650
|
}
|
@@ -7730,9 +7679,9 @@
|
|
7730
7679
|
var forcedAutoLevel = _this2.forcedAutoLevel;
|
7731
7680
|
if (i !== loadLevel && (forcedAutoLevel === -1 || forcedAutoLevel !== loadLevel)) {
|
7732
7681
|
if (levelsSkipped.length) {
|
7733
|
-
|
7682
|
+
logger.trace("[abr] Skipped level(s) " + levelsSkipped.join(',') + " of " + maxAutoLevel + " max with CODECS and VIDEO-RANGE:\"" + levels[levelsSkipped[0]].codecs + "\" " + levels[levelsSkipped[0]].videoRange + "; not compatible with \"" + level.codecs + "\" " + currentVideoRange);
|
7734
7683
|
}
|
7735
|
-
|
7684
|
+
logger.info("[abr] switch candidate:" + selectionBaseLevel + "->" + i + " adjustedbw(" + Math.round(adjustedbw) + ")-bitrate=" + Math.round(adjustedbw - bitrate) + " ttfb:" + ttfbEstimateSec.toFixed(1) + " avgDuration:" + avgDuration.toFixed(1) + " maxFetchDuration:" + maxFetchDuration.toFixed(1) + " fetchDuration:" + fetchDuration.toFixed(1) + " firstSelection:" + firstSelection + " codecSet:" + currentCodecSet + " videoRange:" + currentVideoRange + " hls.loadLevel:" + loadLevel);
|
7736
7685
|
}
|
7737
7686
|
if (firstSelection) {
|
7738
7687
|
_this2.firstSelection = i;
|
@@ -7766,7 +7715,7 @@
|
|
7766
7715
|
}
|
7767
7716
|
var firstLevel = this.hls.firstLevel;
|
7768
7717
|
var clamped = Math.min(Math.max(firstLevel, minAutoLevel), maxAutoLevel);
|
7769
|
-
|
7718
|
+
logger.warn("[abr] Could not find best starting auto level. Defaulting to first in playlist " + firstLevel + " clamped to " + clamped);
|
7770
7719
|
return clamped;
|
7771
7720
|
}
|
7772
7721
|
}, {
|
@@ -7816,7 +7765,7 @@
|
|
7816
7765
|
}
|
7817
7766
|
}]);
|
7818
7767
|
return AbrController;
|
7819
|
-
}(
|
7768
|
+
}();
|
7820
7769
|
|
7821
7770
|
/**
|
7822
7771
|
* @ignore
|
@@ -7847,17 +7796,13 @@
|
|
7847
7796
|
* we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further
|
7848
7797
|
* task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo).
|
7849
7798
|
*/
|
7850
|
-
var TaskLoop = /*#__PURE__*/function (
|
7851
|
-
|
7852
|
-
|
7853
|
-
|
7854
|
-
|
7855
|
-
|
7856
|
-
|
7857
|
-
_this._tickInterval = null;
|
7858
|
-
_this._tickCallCount = 0;
|
7859
|
-
_this._boundTick = _this.tick.bind(_assertThisInitialized(_this));
|
7860
|
-
return _this;
|
7799
|
+
var TaskLoop = /*#__PURE__*/function () {
|
7800
|
+
function TaskLoop() {
|
7801
|
+
this._boundTick = void 0;
|
7802
|
+
this._tickTimer = null;
|
7803
|
+
this._tickInterval = null;
|
7804
|
+
this._tickCallCount = 0;
|
7805
|
+
this._boundTick = this.tick.bind(this);
|
7861
7806
|
}
|
7862
7807
|
var _proto = TaskLoop.prototype;
|
7863
7808
|
_proto.destroy = function destroy() {
|
@@ -7943,7 +7888,7 @@
|
|
7943
7888
|
*/;
|
7944
7889
|
_proto.doTick = function doTick() {};
|
7945
7890
|
return TaskLoop;
|
7946
|
-
}(
|
7891
|
+
}();
|
7947
7892
|
|
7948
7893
|
var FragmentState = {
|
7949
7894
|
NOT_LOADED: "NOT_LOADED",
|
@@ -8962,8 +8907,8 @@
|
|
8962
8907
|
var _frag$decryptdata;
|
8963
8908
|
var byteRangeStart = start;
|
8964
8909
|
var byteRangeEnd = end;
|
8965
|
-
if (frag.sn === 'initSegment' &&
|
8966
|
-
// MAP segment encrypted with method 'AES-128'
|
8910
|
+
if (frag.sn === 'initSegment' && ((_frag$decryptdata = frag.decryptdata) == null ? void 0 : _frag$decryptdata.method) === 'AES-128') {
|
8911
|
+
// MAP segment encrypted with method 'AES-128', when served with HTTP Range,
|
8967
8912
|
// has the unencrypted size specified in the range.
|
8968
8913
|
// Ref: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-6.3.6
|
8969
8914
|
var fragmentLen = end - start;
|
@@ -8996,9 +8941,6 @@
|
|
8996
8941
|
(part ? part : frag).stats.aborted = true;
|
8997
8942
|
return new LoadError(errorData);
|
8998
8943
|
}
|
8999
|
-
function isMethodFullSegmentAesCbc(method) {
|
9000
|
-
return method === 'AES-128' || method === 'AES-256';
|
9001
|
-
}
|
9002
8944
|
var LoadError = /*#__PURE__*/function (_Error) {
|
9003
8945
|
_inheritsLoose(LoadError, _Error);
|
9004
8946
|
function LoadError(data) {
|
@@ -9012,65 +8954,37 @@
|
|
9012
8954
|
}( /*#__PURE__*/_wrapNativeSuper(Error));
|
9013
8955
|
|
9014
8956
|
var AESCrypto = /*#__PURE__*/function () {
|
9015
|
-
function AESCrypto(subtle, iv
|
8957
|
+
function AESCrypto(subtle, iv) {
|
9016
8958
|
this.subtle = void 0;
|
9017
8959
|
this.aesIV = void 0;
|
9018
|
-
this.aesMode = void 0;
|
9019
8960
|
this.subtle = subtle;
|
9020
8961
|
this.aesIV = iv;
|
9021
|
-
this.aesMode = aesMode;
|
9022
8962
|
}
|
9023
8963
|
var _proto = AESCrypto.prototype;
|
9024
8964
|
_proto.decrypt = function decrypt(data, key) {
|
9025
|
-
|
9026
|
-
|
9027
|
-
|
9028
|
-
|
9029
|
-
iv: this.aesIV
|
9030
|
-
}, key, data);
|
9031
|
-
case DecrypterAesMode.ctr:
|
9032
|
-
return this.subtle.decrypt({
|
9033
|
-
name: 'AES-CTR',
|
9034
|
-
counter: this.aesIV,
|
9035
|
-
length: 64
|
9036
|
-
},
|
9037
|
-
//64 : NIST SP800-38A standard suggests that the counter should occupy half of the counter block
|
9038
|
-
key, data);
|
9039
|
-
default:
|
9040
|
-
throw new Error("[AESCrypto] invalid aes mode " + this.aesMode);
|
9041
|
-
}
|
8965
|
+
return this.subtle.decrypt({
|
8966
|
+
name: 'AES-CBC',
|
8967
|
+
iv: this.aesIV
|
8968
|
+
}, key, data);
|
9042
8969
|
};
|
9043
8970
|
return AESCrypto;
|
9044
8971
|
}();
|
9045
8972
|
|
9046
8973
|
var FastAESKey = /*#__PURE__*/function () {
|
9047
|
-
function FastAESKey(subtle, key
|
8974
|
+
function FastAESKey(subtle, key) {
|
9048
8975
|
this.subtle = void 0;
|
9049
8976
|
this.key = void 0;
|
9050
|
-
this.aesMode = void 0;
|
9051
8977
|
this.subtle = subtle;
|
9052
8978
|
this.key = key;
|
9053
|
-
this.aesMode = aesMode;
|
9054
8979
|
}
|
9055
8980
|
var _proto = FastAESKey.prototype;
|
9056
8981
|
_proto.expandKey = function expandKey() {
|
9057
|
-
var subtleAlgoName = getSubtleAlgoName(this.aesMode);
|
9058
8982
|
return this.subtle.importKey('raw', this.key, {
|
9059
|
-
name:
|
8983
|
+
name: 'AES-CBC'
|
9060
8984
|
}, false, ['encrypt', 'decrypt']);
|
9061
8985
|
};
|
9062
8986
|
return FastAESKey;
|
9063
8987
|
}();
|
9064
|
-
function getSubtleAlgoName(aesMode) {
|
9065
|
-
switch (aesMode) {
|
9066
|
-
case DecrypterAesMode.cbc:
|
9067
|
-
return 'AES-CBC';
|
9068
|
-
case DecrypterAesMode.ctr:
|
9069
|
-
return 'AES-CTR';
|
9070
|
-
default:
|
9071
|
-
throw new Error("[FastAESKey] invalid aes mode " + aesMode);
|
9072
|
-
}
|
9073
|
-
}
|
9074
8988
|
|
9075
8989
|
// PKCS7
|
9076
8990
|
function removePadding(array) {
|
@@ -9323,8 +9237,7 @@
|
|
9323
9237
|
this.currentIV = null;
|
9324
9238
|
this.currentResult = null;
|
9325
9239
|
this.useSoftware = void 0;
|
9326
|
-
this.
|
9327
|
-
this.enableSoftwareAES = config.enableSoftwareAES;
|
9240
|
+
this.useSoftware = config.enableSoftwareAES;
|
9328
9241
|
this.removePKCS7Padding = removePKCS7Padding;
|
9329
9242
|
// built in decryptor expects PKCS7 padding
|
9330
9243
|
if (removePKCS7Padding) {
|
@@ -9337,7 +9250,9 @@
|
|
9337
9250
|
/* no-op */
|
9338
9251
|
}
|
9339
9252
|
}
|
9340
|
-
|
9253
|
+
if (this.subtle === null) {
|
9254
|
+
this.useSoftware = true;
|
9255
|
+
}
|
9341
9256
|
}
|
9342
9257
|
var _proto = Decrypter.prototype;
|
9343
9258
|
_proto.destroy = function destroy() {
|
@@ -9374,11 +9289,11 @@
|
|
9374
9289
|
this.softwareDecrypter = null;
|
9375
9290
|
}
|
9376
9291
|
};
|
9377
|
-
_proto.decrypt = function decrypt(data, key, iv
|
9292
|
+
_proto.decrypt = function decrypt(data, key, iv) {
|
9378
9293
|
var _this = this;
|
9379
9294
|
if (this.useSoftware) {
|
9380
9295
|
return new Promise(function (resolve, reject) {
|
9381
|
-
_this.softwareDecrypt(new Uint8Array(data), key, iv
|
9296
|
+
_this.softwareDecrypt(new Uint8Array(data), key, iv);
|
9382
9297
|
var decryptResult = _this.flush();
|
9383
9298
|
if (decryptResult) {
|
9384
9299
|
resolve(decryptResult.buffer);
|
@@ -9387,20 +9302,16 @@
|
|
9387
9302
|
}
|
9388
9303
|
});
|
9389
9304
|
}
|
9390
|
-
return this.webCryptoDecrypt(new Uint8Array(data), key, iv
|
9305
|
+
return this.webCryptoDecrypt(new Uint8Array(data), key, iv);
|
9391
9306
|
}
|
9392
9307
|
|
9393
9308
|
// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
|
9394
9309
|
// data is handled in the flush() call
|
9395
9310
|
;
|
9396
|
-
_proto.softwareDecrypt = function softwareDecrypt(data, key, iv
|
9311
|
+
_proto.softwareDecrypt = function softwareDecrypt(data, key, iv) {
|
9397
9312
|
var currentIV = this.currentIV,
|
9398
9313
|
currentResult = this.currentResult,
|
9399
9314
|
remainderData = this.remainderData;
|
9400
|
-
if (aesMode !== DecrypterAesMode.cbc || key.byteLength !== 16) {
|
9401
|
-
logger.warn('SoftwareDecrypt: can only handle AES-128-CBC');
|
9402
|
-
return null;
|
9403
|
-
}
|
9404
9315
|
this.logOnce('JS AES decrypt');
|
9405
9316
|
// The output is staggered during progressive parsing - the current result is cached, and emitted on the next call
|
9406
9317
|
// This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached
|
@@ -9433,12 +9344,12 @@
|
|
9433
9344
|
}
|
9434
9345
|
return result;
|
9435
9346
|
};
|
9436
|
-
_proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv
|
9347
|
+
_proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv) {
|
9437
9348
|
var _this2 = this;
|
9438
9349
|
var subtle = this.subtle;
|
9439
9350
|
if (this.key !== key || !this.fastAesKey) {
|
9440
9351
|
this.key = key;
|
9441
|
-
this.fastAesKey = new FastAESKey(subtle, key
|
9352
|
+
this.fastAesKey = new FastAESKey(subtle, key);
|
9442
9353
|
}
|
9443
9354
|
return this.fastAesKey.expandKey().then(function (aesKey) {
|
9444
9355
|
// decrypt using web crypto
|
@@ -9446,25 +9357,22 @@
|
|
9446
9357
|
return Promise.reject(new Error('web crypto not initialized'));
|
9447
9358
|
}
|
9448
9359
|
_this2.logOnce('WebCrypto AES decrypt');
|
9449
|
-
var crypto = new AESCrypto(subtle, new Uint8Array(iv)
|
9360
|
+
var crypto = new AESCrypto(subtle, new Uint8Array(iv));
|
9450
9361
|
return crypto.decrypt(data.buffer, aesKey);
|
9451
9362
|
}).catch(function (err) {
|
9452
9363
|
logger.warn("[decrypter]: WebCrypto Error, disable WebCrypto API, " + err.name + ": " + err.message);
|
9453
|
-
return _this2.onWebCryptoError(data, key, iv
|
9364
|
+
return _this2.onWebCryptoError(data, key, iv);
|
9454
9365
|
});
|
9455
9366
|
};
|
9456
|
-
_proto.onWebCryptoError = function onWebCryptoError(data, key, iv
|
9457
|
-
|
9458
|
-
|
9459
|
-
|
9460
|
-
|
9461
|
-
|
9462
|
-
|
9463
|
-
if (decryptResult) {
|
9464
|
-
return decryptResult.buffer;
|
9465
|
-
}
|
9367
|
+
_proto.onWebCryptoError = function onWebCryptoError(data, key, iv) {
|
9368
|
+
this.useSoftware = true;
|
9369
|
+
this.logEnabled = true;
|
9370
|
+
this.softwareDecrypt(data, key, iv);
|
9371
|
+
var decryptResult = this.flush();
|
9372
|
+
if (decryptResult) {
|
9373
|
+
return decryptResult.buffer;
|
9466
9374
|
}
|
9467
|
-
throw new Error('WebCrypto
|
9375
|
+
throw new Error('WebCrypto and softwareDecrypt: failed to decrypt data');
|
9468
9376
|
};
|
9469
9377
|
_proto.getValidChunk = function getValidChunk(data) {
|
9470
9378
|
var currentChunk = data;
|
@@ -9518,7 +9426,7 @@
|
|
9518
9426
|
_inheritsLoose(BaseStreamController, _TaskLoop);
|
9519
9427
|
function BaseStreamController(hls, fragmentTracker, keyLoader, logPrefix, playlistType) {
|
9520
9428
|
var _this;
|
9521
|
-
_this = _TaskLoop.call(this
|
9429
|
+
_this = _TaskLoop.call(this) || this;
|
9522
9430
|
_this.hls = void 0;
|
9523
9431
|
_this.fragPrevious = null;
|
9524
9432
|
_this.fragCurrent = null;
|
@@ -9543,86 +9451,25 @@
|
|
9543
9451
|
_this.startFragRequested = false;
|
9544
9452
|
_this.decrypter = void 0;
|
9545
9453
|
_this.initPTS = [];
|
9546
|
-
_this.
|
9547
|
-
|
9548
|
-
|
9549
|
-
|
9550
|
-
|
9551
|
-
mediaBuffer = _assertThisInitialize.mediaBuffer,
|
9552
|
-
state = _assertThisInitialize.state;
|
9553
|
-
var currentTime = media ? media.currentTime : 0;
|
9554
|
-
var bufferInfo = BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
|
9555
|
-
_this.log("media seeking to " + (isFiniteNumber(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
|
9556
|
-
if (_this.state === State.ENDED) {
|
9557
|
-
_this.resetLoadingState();
|
9558
|
-
} else if (fragCurrent) {
|
9559
|
-
// Seeking while frag load is in progress
|
9560
|
-
var tolerance = config.maxFragLookUpTolerance;
|
9561
|
-
var fragStartOffset = fragCurrent.start - tolerance;
|
9562
|
-
var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
|
9563
|
-
// if seeking out of buffered range or into new one
|
9564
|
-
if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
|
9565
|
-
var pastFragment = currentTime > fragEndOffset;
|
9566
|
-
// if the seek position is outside the current fragment range
|
9567
|
-
if (currentTime < fragStartOffset || pastFragment) {
|
9568
|
-
if (pastFragment && fragCurrent.loader) {
|
9569
|
-
_this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
|
9570
|
-
fragCurrent.abortRequests();
|
9571
|
-
_this.resetLoadingState();
|
9572
|
-
}
|
9573
|
-
_this.fragPrevious = null;
|
9574
|
-
}
|
9575
|
-
}
|
9576
|
-
}
|
9577
|
-
if (media) {
|
9578
|
-
// Remove gap fragments
|
9579
|
-
_this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, _this.playlistType, true);
|
9580
|
-
_this.lastCurrentTime = currentTime;
|
9581
|
-
}
|
9582
|
-
|
9583
|
-
// in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
|
9584
|
-
if (!_this.loadedmetadata && !bufferInfo.len) {
|
9585
|
-
_this.nextLoadPosition = _this.startPosition = currentTime;
|
9586
|
-
}
|
9587
|
-
|
9588
|
-
// Async tick to speed up processing
|
9589
|
-
_this.tickImmediate();
|
9590
|
-
};
|
9591
|
-
_this.onMediaEnded = function () {
|
9592
|
-
// reset startPosition and lastCurrentTime to restart playback @ stream beginning
|
9593
|
-
_this.startPosition = _this.lastCurrentTime = 0;
|
9594
|
-
if (_this.playlistType === PlaylistLevelType.MAIN) {
|
9595
|
-
_this.hls.trigger(Events.MEDIA_ENDED, {
|
9596
|
-
stalled: false
|
9597
|
-
});
|
9598
|
-
}
|
9599
|
-
};
|
9454
|
+
_this.onvseeking = null;
|
9455
|
+
_this.onvended = null;
|
9456
|
+
_this.logPrefix = '';
|
9457
|
+
_this.log = void 0;
|
9458
|
+
_this.warn = void 0;
|
9600
9459
|
_this.playlistType = playlistType;
|
9460
|
+
_this.logPrefix = logPrefix;
|
9461
|
+
_this.log = logger.log.bind(logger, logPrefix + ":");
|
9462
|
+
_this.warn = logger.warn.bind(logger, logPrefix + ":");
|
9601
9463
|
_this.hls = hls;
|
9602
9464
|
_this.fragmentLoader = new FragmentLoader(hls.config);
|
9603
9465
|
_this.keyLoader = keyLoader;
|
9604
9466
|
_this.fragmentTracker = fragmentTracker;
|
9605
9467
|
_this.config = hls.config;
|
9606
9468
|
_this.decrypter = new Decrypter(hls.config);
|
9469
|
+
hls.on(Events.MANIFEST_LOADED, _this.onManifestLoaded, _assertThisInitialized(_this));
|
9607
9470
|
return _this;
|
9608
9471
|
}
|
9609
9472
|
var _proto = BaseStreamController.prototype;
|
9610
|
-
_proto.registerListeners = function registerListeners() {
|
9611
|
-
var hls = this.hls;
|
9612
|
-
hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
9613
|
-
hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
9614
|
-
hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
9615
|
-
hls.on(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
|
9616
|
-
hls.on(Events.ERROR, this.onError, this);
|
9617
|
-
};
|
9618
|
-
_proto.unregisterListeners = function unregisterListeners() {
|
9619
|
-
var hls = this.hls;
|
9620
|
-
hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
9621
|
-
hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
9622
|
-
hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
9623
|
-
hls.off(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
|
9624
|
-
hls.off(Events.ERROR, this.onError, this);
|
9625
|
-
};
|
9626
9473
|
_proto.doTick = function doTick() {
|
9627
9474
|
this.onTickEnd();
|
9628
9475
|
};
|
@@ -9676,8 +9523,10 @@
|
|
9676
9523
|
};
|
9677
9524
|
_proto.onMediaAttached = function onMediaAttached(event, data) {
|
9678
9525
|
var media = this.media = this.mediaBuffer = data.media;
|
9679
|
-
|
9680
|
-
|
9526
|
+
this.onvseeking = this.onMediaSeeking.bind(this);
|
9527
|
+
this.onvended = this.onMediaEnded.bind(this);
|
9528
|
+
media.addEventListener('seeking', this.onvseeking);
|
9529
|
+
media.addEventListener('ended', this.onvended);
|
9681
9530
|
var config = this.config;
|
9682
9531
|
if (this.levels && config.autoStartLoad && this.state === State.STOPPED) {
|
9683
9532
|
this.startLoad(config.startPosition);
|
@@ -9691,9 +9540,10 @@
|
|
9691
9540
|
}
|
9692
9541
|
|
9693
9542
|
// remove video listeners
|
9694
|
-
if (media) {
|
9695
|
-
media.removeEventListener('seeking', this.
|
9696
|
-
media.removeEventListener('ended', this.
|
9543
|
+
if (media && this.onvseeking && this.onvended) {
|
9544
|
+
media.removeEventListener('seeking', this.onvseeking);
|
9545
|
+
media.removeEventListener('ended', this.onvended);
|
9546
|
+
this.onvseeking = this.onvended = null;
|
9697
9547
|
}
|
9698
9548
|
if (this.keyLoader) {
|
9699
9549
|
this.keyLoader.detach();
|
@@ -9703,8 +9553,54 @@
|
|
9703
9553
|
this.fragmentTracker.removeAllFragments();
|
9704
9554
|
this.stopLoad();
|
9705
9555
|
};
|
9706
|
-
_proto.
|
9707
|
-
|
9556
|
+
_proto.onMediaSeeking = function onMediaSeeking() {
|
9557
|
+
var config = this.config,
|
9558
|
+
fragCurrent = this.fragCurrent,
|
9559
|
+
media = this.media,
|
9560
|
+
mediaBuffer = this.mediaBuffer,
|
9561
|
+
state = this.state;
|
9562
|
+
var currentTime = media ? media.currentTime : 0;
|
9563
|
+
var bufferInfo = BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
|
9564
|
+
this.log("media seeking to " + (isFiniteNumber(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
|
9565
|
+
if (this.state === State.ENDED) {
|
9566
|
+
this.resetLoadingState();
|
9567
|
+
} else if (fragCurrent) {
|
9568
|
+
// Seeking while frag load is in progress
|
9569
|
+
var tolerance = config.maxFragLookUpTolerance;
|
9570
|
+
var fragStartOffset = fragCurrent.start - tolerance;
|
9571
|
+
var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
|
9572
|
+
// if seeking out of buffered range or into new one
|
9573
|
+
if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
|
9574
|
+
var pastFragment = currentTime > fragEndOffset;
|
9575
|
+
// if the seek position is outside the current fragment range
|
9576
|
+
if (currentTime < fragStartOffset || pastFragment) {
|
9577
|
+
if (pastFragment && fragCurrent.loader) {
|
9578
|
+
this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
|
9579
|
+
fragCurrent.abortRequests();
|
9580
|
+
this.resetLoadingState();
|
9581
|
+
}
|
9582
|
+
this.fragPrevious = null;
|
9583
|
+
}
|
9584
|
+
}
|
9585
|
+
}
|
9586
|
+
if (media) {
|
9587
|
+
// Remove gap fragments
|
9588
|
+
this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, this.playlistType, true);
|
9589
|
+
this.lastCurrentTime = currentTime;
|
9590
|
+
}
|
9591
|
+
|
9592
|
+
// in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
|
9593
|
+
if (!this.loadedmetadata && !bufferInfo.len) {
|
9594
|
+
this.nextLoadPosition = this.startPosition = currentTime;
|
9595
|
+
}
|
9596
|
+
|
9597
|
+
// Async tick to speed up processing
|
9598
|
+
this.tickImmediate();
|
9599
|
+
};
|
9600
|
+
_proto.onMediaEnded = function onMediaEnded() {
|
9601
|
+
// reset startPosition and lastCurrentTime to restart playback @ stream beginning
|
9602
|
+
this.startPosition = this.lastCurrentTime = 0;
|
9603
|
+
};
|
9708
9604
|
_proto.onManifestLoaded = function onManifestLoaded(event, data) {
|
9709
9605
|
this.startTimeOffset = data.startTimeOffset;
|
9710
9606
|
this.initPTS = [];
|
@@ -9714,7 +9610,7 @@
|
|
9714
9610
|
this.stopLoad();
|
9715
9611
|
_TaskLoop.prototype.onHandlerDestroying.call(this);
|
9716
9612
|
// @ts-ignore
|
9717
|
-
this.hls =
|
9613
|
+
this.hls = null;
|
9718
9614
|
};
|
9719
9615
|
_proto.onHandlerDestroyed = function onHandlerDestroyed() {
|
9720
9616
|
this.state = State.STOPPED;
|
@@ -9844,10 +9740,10 @@
|
|
9844
9740
|
var decryptData = frag.decryptdata;
|
9845
9741
|
|
9846
9742
|
// check to see if the payload needs to be decrypted
|
9847
|
-
if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv &&
|
9743
|
+
if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') {
|
9848
9744
|
var startTime = self.performance.now();
|
9849
9745
|
// decrypt init segment data
|
9850
|
-
return _this3.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer
|
9746
|
+
return _this3.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).catch(function (err) {
|
9851
9747
|
hls.trigger(Events.ERROR, {
|
9852
9748
|
type: ErrorTypes.MEDIA_ERROR,
|
9853
9749
|
details: ErrorDetails.FRAG_DECRYPT_ERROR,
|
@@ -9960,7 +9856,7 @@
|
|
9960
9856
|
}
|
9961
9857
|
var keyLoadingPromise = null;
|
9962
9858
|
if (frag.encrypted && !((_frag$decryptdata = frag.decryptdata) != null && _frag$decryptdata.key)) {
|
9963
|
-
this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.
|
9859
|
+
this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + " " + frag.level);
|
9964
9860
|
this.state = State.KEY_LOADING;
|
9965
9861
|
this.fragCurrent = frag;
|
9966
9862
|
keyLoadingPromise = this.keyLoader.load(frag).then(function (keyLoadedData) {
|
@@ -9991,7 +9887,7 @@
|
|
9991
9887
|
var partIndex = this.getNextPart(partList, frag, targetBufferTime);
|
9992
9888
|
if (partIndex > -1) {
|
9993
9889
|
var part = partList[partIndex];
|
9994
|
-
this.log("Loading part sn: " + frag.sn + " p: " + part.index + " cc: " + frag.cc + " of playlist [" + details.startSN + "-" + details.endSN + "] parts [0-" + partIndex + "-" + (partList.length - 1) + "] " + (this.
|
9890
|
+
this.log("Loading part sn: " + frag.sn + " p: " + part.index + " cc: " + frag.cc + " of playlist [" + details.startSN + "-" + details.endSN + "] parts [0-" + partIndex + "-" + (partList.length - 1) + "] " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3)));
|
9995
9891
|
this.nextLoadPosition = part.start + part.duration;
|
9996
9892
|
this.state = State.FRAG_LOADING;
|
9997
9893
|
var _result;
|
@@ -10024,7 +9920,7 @@
|
|
10024
9920
|
}
|
10025
9921
|
}
|
10026
9922
|
}
|
10027
|
-
this.log("Loading fragment " + frag.sn + " cc: " + frag.cc + " " + (details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : '') + (this.
|
9923
|
+
this.log("Loading fragment " + frag.sn + " cc: " + frag.cc + " " + (details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : '') + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3)));
|
10028
9924
|
// Don't update nextLoadPosition for fragments which are not buffered
|
10029
9925
|
if (isFiniteNumber(frag.sn) && !this.bitrateTest) {
|
10030
9926
|
this.nextLoadPosition = frag.start + frag.duration;
|
@@ -10585,7 +10481,7 @@
|
|
10585
10481
|
errorAction.resolved = true;
|
10586
10482
|
}
|
10587
10483
|
} else {
|
10588
|
-
|
10484
|
+
logger.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
|
10589
10485
|
return;
|
10590
10486
|
}
|
10591
10487
|
} else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
|
@@ -10985,7 +10881,6 @@
|
|
10985
10881
|
*/
|
10986
10882
|
function getAudioConfig(observer, data, offset, audioCodec) {
|
10987
10883
|
var adtsObjectType;
|
10988
|
-
var originalAdtsObjectType;
|
10989
10884
|
var adtsExtensionSamplingIndex;
|
10990
10885
|
var adtsChannelConfig;
|
10991
10886
|
var config;
|
@@ -10993,7 +10888,7 @@
|
|
10993
10888
|
var manifestCodec = audioCodec;
|
10994
10889
|
var adtsSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
|
10995
10890
|
// byte 2
|
10996
|
-
adtsObjectType =
|
10891
|
+
adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;
|
10997
10892
|
var adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2;
|
10998
10893
|
if (adtsSamplingIndex > adtsSamplingRates.length - 1) {
|
10999
10894
|
var error = new Error("invalid ADTS sampling index:" + adtsSamplingIndex);
|
@@ -11010,8 +10905,8 @@
|
|
11010
10905
|
// byte 3
|
11011
10906
|
adtsChannelConfig |= (data[offset + 3] & 0xc0) >>> 6;
|
11012
10907
|
logger.log("manifest codec:" + audioCodec + ", ADTS type:" + adtsObjectType + ", samplingIndex:" + adtsSamplingIndex);
|
11013
|
-
//
|
11014
|
-
if (/firefox
|
10908
|
+
// firefox: freq less than 24kHz = AAC SBR (HE-AAC)
|
10909
|
+
if (/firefox/i.test(userAgent)) {
|
11015
10910
|
if (adtsSamplingIndex >= 6) {
|
11016
10911
|
adtsObjectType = 5;
|
11017
10912
|
config = new Array(4);
|
@@ -11105,7 +11000,6 @@
|
|
11105
11000
|
samplerate: adtsSamplingRates[adtsSamplingIndex],
|
11106
11001
|
channelCount: adtsChannelConfig,
|
11107
11002
|
codec: 'mp4a.40.' + adtsObjectType,
|
11108
|
-
parsedCodec: 'mp4a.40.' + originalAdtsObjectType,
|
11109
11003
|
manifestCodec: manifestCodec
|
11110
11004
|
};
|
11111
11005
|
}
|
@@ -11160,8 +11054,7 @@
|
|
11160
11054
|
track.channelCount = config.channelCount;
|
11161
11055
|
track.codec = config.codec;
|
11162
11056
|
track.manifestCodec = config.manifestCodec;
|
11163
|
-
track.
|
11164
|
-
logger.log("parsed codec:" + track.parsedCodec + ", codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount);
|
11057
|
+
logger.log("parsed codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount);
|
11165
11058
|
}
|
11166
11059
|
}
|
11167
11060
|
function getFrameDuration(samplerate) {
|
@@ -12366,7 +12259,7 @@
|
|
12366
12259
|
}
|
12367
12260
|
var _proto = SampleAesDecrypter.prototype;
|
12368
12261
|
_proto.decryptBuffer = function decryptBuffer(encryptedData) {
|
12369
|
-
return this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer
|
12262
|
+
return this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer);
|
12370
12263
|
}
|
12371
12264
|
|
12372
12265
|
// AAC - encrypt all full 16 bytes blocks starting from offset 16
|
@@ -14357,24 +14250,12 @@
|
|
14357
14250
|
inputSamples[0].dts = firstDTS;
|
14358
14251
|
inputSamples[0].pts = firstPTS;
|
14359
14252
|
} else {
|
14360
|
-
var isPTSOrderRetained = true;
|
14361
14253
|
for (var _i = 0; _i < inputSamples.length; _i++) {
|
14362
|
-
if (inputSamples[_i].dts > firstPTS
|
14254
|
+
if (inputSamples[_i].dts > firstPTS) {
|
14363
14255
|
break;
|
14364
14256
|
}
|
14365
|
-
var prevPTS = inputSamples[_i].pts;
|
14366
14257
|
inputSamples[_i].dts -= delta;
|
14367
14258
|
inputSamples[_i].pts -= delta;
|
14368
|
-
|
14369
|
-
// check to see if this sample's PTS order has changed
|
14370
|
-
// relative to the next one
|
14371
|
-
if (_i < inputSamples.length - 1) {
|
14372
|
-
var nextSamplePTS = inputSamples[_i + 1].pts;
|
14373
|
-
var currentSamplePTS = inputSamples[_i].pts;
|
14374
|
-
var currentOrder = nextSamplePTS <= currentSamplePTS;
|
14375
|
-
var prevOrder = nextSamplePTS <= prevPTS;
|
14376
|
-
isPTSOrderRetained = currentOrder == prevOrder;
|
14377
|
-
}
|
14378
14259
|
}
|
14379
14260
|
}
|
14380
14261
|
logger.log("Video: Initial PTS/DTS adjusted: " + toMsFromMpegTsClock(firstPTS, true) + "/" + toMsFromMpegTsClock(firstDTS, true) + ", delta: " + toMsFromMpegTsClock(delta, true) + " ms");
|
@@ -14657,7 +14538,7 @@
|
|
14657
14538
|
logger.warn("[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round(1000 * delta / inputTimeScale) + " ms gap.");
|
14658
14539
|
for (var j = 0; j < missing; j++) {
|
14659
14540
|
var newStamp = Math.max(nextPts, 0);
|
14660
|
-
var fillFrame = AAC.getSilentFrame(track.
|
14541
|
+
var fillFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
|
14661
14542
|
if (!fillFrame) {
|
14662
14543
|
logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
|
14663
14544
|
fillFrame = sample.unit.subarray();
|
@@ -14785,7 +14666,7 @@
|
|
14785
14666
|
// samples count of this segment's duration
|
14786
14667
|
var nbSamples = Math.ceil((endDTS - startDTS) / frameDuration);
|
14787
14668
|
// silent frame
|
14788
|
-
var silentFrame = AAC.getSilentFrame(track.
|
14669
|
+
var silentFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
|
14789
14670
|
logger.warn('[mp4-remuxer]: remux empty Audio');
|
14790
14671
|
// Can't remux if we can't generate a silent frame...
|
14791
14672
|
if (!silentFrame) {
|
@@ -15175,15 +15056,13 @@
|
|
15175
15056
|
duration = transmuxConfig.duration,
|
15176
15057
|
initSegmentData = transmuxConfig.initSegmentData;
|
15177
15058
|
var keyData = getEncryptionType(uintData, decryptdata);
|
15178
|
-
if (keyData &&
|
15059
|
+
if (keyData && keyData.method === 'AES-128') {
|
15179
15060
|
var decrypter = this.getDecrypter();
|
15180
|
-
var aesMode = getAesModeFromFullSegmentMethod(keyData.method);
|
15181
|
-
|
15182
15061
|
// Software decryption is synchronous; webCrypto is not
|
15183
15062
|
if (decrypter.isSync()) {
|
15184
15063
|
// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
|
15185
15064
|
// data is handled in the flush() call
|
15186
|
-
var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer
|
15065
|
+
var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer);
|
15187
15066
|
// For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
|
15188
15067
|
var loadingParts = chunkMeta.part > -1;
|
15189
15068
|
if (loadingParts) {
|
@@ -15195,7 +15074,7 @@
|
|
15195
15074
|
}
|
15196
15075
|
uintData = new Uint8Array(decryptedData);
|
15197
15076
|
} else {
|
15198
|
-
this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer
|
15077
|
+
this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer).then(function (decryptedData) {
|
15199
15078
|
// Calling push here is important; if flush() is called while this is still resolving, this ensures that
|
15200
15079
|
// the decrypted data has been transmuxed
|
15201
15080
|
var result = _this.push(decryptedData, null, chunkMeta);
|
@@ -15816,7 +15695,7 @@
|
|
15816
15695
|
observer.on(Events.ERROR, forwardMessage);
|
15817
15696
|
|
15818
15697
|
// forward logger events to main thread
|
15819
|
-
var forwardWorkerLogs = function forwardWorkerLogs(
|
15698
|
+
var forwardWorkerLogs = function forwardWorkerLogs() {
|
15820
15699
|
var _loop = function _loop(logFn) {
|
15821
15700
|
var func = function func(message) {
|
15822
15701
|
forwardMessage('workerLog', {
|
@@ -15837,8 +15716,8 @@
|
|
15837
15716
|
{
|
15838
15717
|
var config = JSON.parse(data.config);
|
15839
15718
|
self.transmuxer = new Transmuxer(observer, data.typeSupported, config, data.vendor, data.id);
|
15840
|
-
|
15841
|
-
forwardWorkerLogs(
|
15719
|
+
enableLogs(config.debug, data.id);
|
15720
|
+
forwardWorkerLogs();
|
15842
15721
|
forwardMessage('init', null);
|
15843
15722
|
break;
|
15844
15723
|
}
|
@@ -16012,7 +15891,16 @@
|
|
16012
15891
|
this.observer = new EventEmitter();
|
16013
15892
|
this.observer.on(Events.FRAG_DECRYPTED, forwardMessage);
|
16014
15893
|
this.observer.on(Events.ERROR, forwardMessage);
|
16015
|
-
var
|
15894
|
+
var MediaSource = getMediaSource(config.preferManagedMediaSource) || {
|
15895
|
+
isTypeSupported: function isTypeSupported() {
|
15896
|
+
return false;
|
15897
|
+
}
|
15898
|
+
};
|
15899
|
+
var m2tsTypeSupported = {
|
15900
|
+
mpeg: MediaSource.isTypeSupported('audio/mpeg'),
|
15901
|
+
mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'),
|
15902
|
+
ac3: MediaSource.isTypeSupported('audio/mp4; codecs="ac-3"')
|
15903
|
+
};
|
16016
15904
|
|
16017
15905
|
// navigator.vendor is not always available in Web Worker
|
16018
15906
|
// refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
|
@@ -16296,7 +16184,7 @@
|
|
16296
16184
|
_inheritsLoose(AudioStreamController, _BaseStreamController);
|
16297
16185
|
function AudioStreamController(hls, fragmentTracker, keyLoader) {
|
16298
16186
|
var _this;
|
16299
|
-
_this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, 'audio-stream-controller', PlaylistLevelType.AUDIO) || this;
|
16187
|
+
_this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[audio-stream-controller]', PlaylistLevelType.AUDIO) || this;
|
16300
16188
|
_this.videoBuffer = null;
|
16301
16189
|
_this.videoTrackCC = -1;
|
16302
16190
|
_this.waitingVideoCC = -1;
|
@@ -16308,24 +16196,27 @@
|
|
16308
16196
|
_this.flushing = false;
|
16309
16197
|
_this.bufferFlushed = false;
|
16310
16198
|
_this.cachedTrackLoadedData = null;
|
16311
|
-
_this.
|
16199
|
+
_this._registerListeners();
|
16312
16200
|
return _this;
|
16313
16201
|
}
|
16314
16202
|
var _proto = AudioStreamController.prototype;
|
16315
16203
|
_proto.onHandlerDestroying = function onHandlerDestroying() {
|
16316
|
-
this.
|
16204
|
+
this._unregisterListeners();
|
16317
16205
|
_BaseStreamController.prototype.onHandlerDestroying.call(this);
|
16318
16206
|
this.mainDetails = null;
|
16319
16207
|
this.bufferedTrack = null;
|
16320
16208
|
this.switchingTrack = null;
|
16321
16209
|
};
|
16322
|
-
_proto.
|
16323
|
-
_BaseStreamController.prototype.registerListeners.call(this);
|
16210
|
+
_proto._registerListeners = function _registerListeners() {
|
16324
16211
|
var hls = this.hls;
|
16212
|
+
hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
16213
|
+
hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
16214
|
+
hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
16325
16215
|
hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
16326
16216
|
hls.on(Events.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this);
|
16327
16217
|
hls.on(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
|
16328
16218
|
hls.on(Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
|
16219
|
+
hls.on(Events.ERROR, this.onError, this);
|
16329
16220
|
hls.on(Events.BUFFER_RESET, this.onBufferReset, this);
|
16330
16221
|
hls.on(Events.BUFFER_CREATED, this.onBufferCreated, this);
|
16331
16222
|
hls.on(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
|
@@ -16333,16 +16224,16 @@
|
|
16333
16224
|
hls.on(Events.INIT_PTS_FOUND, this.onInitPtsFound, this);
|
16334
16225
|
hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
16335
16226
|
};
|
16336
|
-
_proto.
|
16227
|
+
_proto._unregisterListeners = function _unregisterListeners() {
|
16337
16228
|
var hls = this.hls;
|
16338
|
-
|
16339
|
-
|
16340
|
-
|
16341
|
-
_BaseStreamController.prototype.unregisterListeners.call(this);
|
16229
|
+
hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
16230
|
+
hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
16231
|
+
hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
16342
16232
|
hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
16343
16233
|
hls.off(Events.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this);
|
16344
16234
|
hls.off(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
|
16345
16235
|
hls.off(Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
|
16236
|
+
hls.off(Events.ERROR, this.onError, this);
|
16346
16237
|
hls.off(Events.BUFFER_RESET, this.onBufferReset, this);
|
16347
16238
|
hls.off(Events.BUFFER_CREATED, this.onBufferCreated, this);
|
16348
16239
|
hls.off(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
|
@@ -17035,7 +16926,7 @@
|
|
17035
16926
|
_inheritsLoose(AudioTrackController, _BasePlaylistControll);
|
17036
16927
|
function AudioTrackController(hls) {
|
17037
16928
|
var _this;
|
17038
|
-
_this = _BasePlaylistControll.call(this, hls, 'audio-track-controller') || this;
|
16929
|
+
_this = _BasePlaylistControll.call(this, hls, '[audio-track-controller]') || this;
|
17039
16930
|
_this.tracks = [];
|
17040
16931
|
_this.groupIds = null;
|
17041
16932
|
_this.tracksInGroup = [];
|
@@ -17364,23 +17255,26 @@
|
|
17364
17255
|
_inheritsLoose(SubtitleStreamController, _BaseStreamController);
|
17365
17256
|
function SubtitleStreamController(hls, fragmentTracker, keyLoader) {
|
17366
17257
|
var _this;
|
17367
|
-
_this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, 'subtitle-stream-controller', PlaylistLevelType.SUBTITLE) || this;
|
17258
|
+
_this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[subtitle-stream-controller]', PlaylistLevelType.SUBTITLE) || this;
|
17368
17259
|
_this.currentTrackId = -1;
|
17369
17260
|
_this.tracksBuffered = [];
|
17370
17261
|
_this.mainDetails = null;
|
17371
|
-
_this.
|
17262
|
+
_this._registerListeners();
|
17372
17263
|
return _this;
|
17373
17264
|
}
|
17374
17265
|
var _proto = SubtitleStreamController.prototype;
|
17375
17266
|
_proto.onHandlerDestroying = function onHandlerDestroying() {
|
17376
|
-
this.
|
17267
|
+
this._unregisterListeners();
|
17377
17268
|
_BaseStreamController.prototype.onHandlerDestroying.call(this);
|
17378
17269
|
this.mainDetails = null;
|
17379
17270
|
};
|
17380
|
-
_proto.
|
17381
|
-
_BaseStreamController.prototype.registerListeners.call(this);
|
17271
|
+
_proto._registerListeners = function _registerListeners() {
|
17382
17272
|
var hls = this.hls;
|
17273
|
+
hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
17274
|
+
hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
17275
|
+
hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
17383
17276
|
hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
17277
|
+
hls.on(Events.ERROR, this.onError, this);
|
17384
17278
|
hls.on(Events.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this);
|
17385
17279
|
hls.on(Events.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this);
|
17386
17280
|
hls.on(Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
|
@@ -17388,10 +17282,13 @@
|
|
17388
17282
|
hls.on(Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
|
17389
17283
|
hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
17390
17284
|
};
|
17391
|
-
_proto.
|
17392
|
-
_BaseStreamController.prototype.unregisterListeners.call(this);
|
17285
|
+
_proto._unregisterListeners = function _unregisterListeners() {
|
17393
17286
|
var hls = this.hls;
|
17287
|
+
hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
17288
|
+
hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
17289
|
+
hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
17394
17290
|
hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
17291
|
+
hls.off(Events.ERROR, this.onError, this);
|
17395
17292
|
hls.off(Events.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this);
|
17396
17293
|
hls.off(Events.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this);
|
17397
17294
|
hls.off(Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
|
@@ -17614,10 +17511,10 @@
|
|
17614
17511
|
return;
|
17615
17512
|
}
|
17616
17513
|
// check to see if the payload needs to be decrypted
|
17617
|
-
if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv &&
|
17514
|
+
if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') {
|
17618
17515
|
var startTime = performance.now();
|
17619
17516
|
// decrypt the subtitles
|
17620
|
-
this.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer
|
17517
|
+
this.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).catch(function (err) {
|
17621
17518
|
hls.trigger(Events.ERROR, {
|
17622
17519
|
type: ErrorTypes.MEDIA_ERROR,
|
17623
17520
|
details: ErrorDetails.FRAG_DECRYPT_ERROR,
|
@@ -17749,7 +17646,7 @@
|
|
17749
17646
|
_inheritsLoose(SubtitleTrackController, _BasePlaylistControll);
|
17750
17647
|
function SubtitleTrackController(hls) {
|
17751
17648
|
var _this;
|
17752
|
-
_this = _BasePlaylistControll.call(this, hls, 'subtitle-track-controller') || this;
|
17649
|
+
_this = _BasePlaylistControll.call(this, hls, '[subtitle-track-controller]') || this;
|
17753
17650
|
_this.media = null;
|
17754
17651
|
_this.tracks = [];
|
17755
17652
|
_this.groupIds = null;
|
@@ -17758,12 +17655,12 @@
|
|
17758
17655
|
_this.currentTrack = null;
|
17759
17656
|
_this.selectDefaultTrack = true;
|
17760
17657
|
_this.queuedDefaultTrack = -1;
|
17761
|
-
_this.useTextTrackPolling = false;
|
17762
|
-
_this.subtitlePollingInterval = -1;
|
17763
|
-
_this._subtitleDisplay = true;
|
17764
17658
|
_this.asyncPollTrackChange = function () {
|
17765
17659
|
return _this.pollTrackChange(0);
|
17766
17660
|
};
|
17661
|
+
_this.useTextTrackPolling = false;
|
17662
|
+
_this.subtitlePollingInterval = -1;
|
17663
|
+
_this._subtitleDisplay = true;
|
17767
17664
|
_this.onTextTracksChanged = function () {
|
17768
17665
|
if (!_this.useTextTrackPolling) {
|
17769
17666
|
self.clearInterval(_this.subtitlePollingInterval);
|
@@ -17799,7 +17696,6 @@
|
|
17799
17696
|
this.tracks.length = 0;
|
17800
17697
|
this.tracksInGroup.length = 0;
|
17801
17698
|
this.currentTrack = null;
|
17802
|
-
// @ts-ignore
|
17803
17699
|
this.onTextTracksChanged = this.asyncPollTrackChange = null;
|
17804
17700
|
_BasePlaylistControll.prototype.destroy.call(this);
|
17805
17701
|
};
|
@@ -18273,57 +18169,57 @@
|
|
18273
18169
|
}();
|
18274
18170
|
|
18275
18171
|
var VIDEO_CODEC_PROFILE_REPLACE = /(avc[1234]|hvc1|hev1|dvh[1e]|vp09|av01)(?:\.[^.,]+)+/;
|
18276
|
-
var BufferController = /*#__PURE__*/function (
|
18277
|
-
_inheritsLoose(BufferController, _Logger);
|
18172
|
+
var BufferController = /*#__PURE__*/function () {
|
18278
18173
|
function BufferController(hls) {
|
18279
|
-
var _this;
|
18280
|
-
_this = _Logger.call(this, 'buffer-controller', hls.logger) || this;
|
18174
|
+
var _this = this;
|
18281
18175
|
// The level details used to determine duration, target-duration and live
|
18282
|
-
|
18176
|
+
this.details = null;
|
18283
18177
|
// cache the self generated object url to detect hijack of video tag
|
18284
|
-
|
18178
|
+
this._objectUrl = null;
|
18285
18179
|
// A queue of buffer operations which require the SourceBuffer to not be updating upon execution
|
18286
|
-
|
18180
|
+
this.operationQueue = void 0;
|
18287
18181
|
// References to event listeners for each SourceBuffer, so that they can be referenced for event removal
|
18288
|
-
|
18289
|
-
|
18182
|
+
this.listeners = void 0;
|
18183
|
+
this.hls = void 0;
|
18290
18184
|
// The number of BUFFER_CODEC events received before any sourceBuffers are created
|
18291
|
-
|
18185
|
+
this.bufferCodecEventsExpected = 0;
|
18292
18186
|
// The total number of BUFFER_CODEC events received
|
18293
|
-
|
18187
|
+
this._bufferCodecEventsTotal = 0;
|
18294
18188
|
// A reference to the attached media element
|
18295
|
-
|
18189
|
+
this.media = null;
|
18296
18190
|
// A reference to the active media source
|
18297
|
-
|
18191
|
+
this.mediaSource = null;
|
18298
18192
|
// Last MP3 audio chunk appended
|
18299
|
-
|
18300
|
-
|
18193
|
+
this.lastMpegAudioChunk = null;
|
18194
|
+
this.appendSource = void 0;
|
18301
18195
|
// counters
|
18302
|
-
|
18196
|
+
this.appendErrors = {
|
18303
18197
|
audio: 0,
|
18304
18198
|
video: 0,
|
18305
18199
|
audiovideo: 0
|
18306
18200
|
};
|
18307
|
-
|
18308
|
-
|
18309
|
-
|
18310
|
-
|
18201
|
+
this.tracks = {};
|
18202
|
+
this.pendingTracks = {};
|
18203
|
+
this.sourceBuffer = void 0;
|
18204
|
+
this.log = void 0;
|
18205
|
+
this.warn = void 0;
|
18206
|
+
this.error = void 0;
|
18207
|
+
this._onEndStreaming = function (event) {
|
18311
18208
|
if (!_this.hls) {
|
18312
18209
|
return;
|
18313
18210
|
}
|
18314
18211
|
_this.hls.pauseBuffering();
|
18315
18212
|
};
|
18316
|
-
|
18213
|
+
this._onStartStreaming = function (event) {
|
18317
18214
|
if (!_this.hls) {
|
18318
18215
|
return;
|
18319
18216
|
}
|
18320
18217
|
_this.hls.resumeBuffering();
|
18321
18218
|
};
|
18322
18219
|
// Keep as arrow functions so that we can directly reference these functions directly as event listeners
|
18323
|
-
|
18324
|
-
var
|
18325
|
-
|
18326
|
-
mediaSource = _assertThisInitialize.mediaSource;
|
18220
|
+
this._onMediaSourceOpen = function () {
|
18221
|
+
var media = _this.media,
|
18222
|
+
mediaSource = _this.mediaSource;
|
18327
18223
|
_this.log('Media source opened');
|
18328
18224
|
if (media) {
|
18329
18225
|
media.removeEventListener('emptied', _this._onMediaEmptied);
|
@@ -18339,25 +18235,27 @@
|
|
18339
18235
|
}
|
18340
18236
|
_this.checkPendingTracks();
|
18341
18237
|
};
|
18342
|
-
|
18238
|
+
this._onMediaSourceClose = function () {
|
18343
18239
|
_this.log('Media source closed');
|
18344
18240
|
};
|
18345
|
-
|
18241
|
+
this._onMediaSourceEnded = function () {
|
18346
18242
|
_this.log('Media source ended');
|
18347
18243
|
};
|
18348
|
-
|
18349
|
-
var
|
18350
|
-
|
18351
|
-
_objectUrl = _assertThisInitialize2._objectUrl;
|
18244
|
+
this._onMediaEmptied = function () {
|
18245
|
+
var mediaSrc = _this.mediaSrc,
|
18246
|
+
_objectUrl = _this._objectUrl;
|
18352
18247
|
if (mediaSrc !== _objectUrl) {
|
18353
|
-
|
18248
|
+
logger.error("Media element src was set while attaching MediaSource (" + _objectUrl + " > " + mediaSrc + ")");
|
18354
18249
|
}
|
18355
18250
|
};
|
18356
|
-
|
18357
|
-
|
18358
|
-
|
18359
|
-
|
18360
|
-
|
18251
|
+
this.hls = hls;
|
18252
|
+
var logPrefix = '[buffer-controller]';
|
18253
|
+
this.appendSource = hls.config.preferManagedMediaSource;
|
18254
|
+
this.log = logger.log.bind(logger, logPrefix);
|
18255
|
+
this.warn = logger.warn.bind(logger, logPrefix);
|
18256
|
+
this.error = logger.error.bind(logger, logPrefix);
|
18257
|
+
this._initSourceBuffer();
|
18258
|
+
this.registerListeners();
|
18361
18259
|
}
|
18362
18260
|
var _proto = BufferController.prototype;
|
18363
18261
|
_proto.hasSourceTypes = function hasSourceTypes() {
|
@@ -18369,12 +18267,6 @@
|
|
18369
18267
|
this.lastMpegAudioChunk = null;
|
18370
18268
|
// @ts-ignore
|
18371
18269
|
this.hls = null;
|
18372
|
-
// @ts-ignore
|
18373
|
-
this._onMediaSourceOpen = this._onMediaSourceClose = null;
|
18374
|
-
// @ts-ignore
|
18375
|
-
this._onMediaSourceEnded = null;
|
18376
|
-
// @ts-ignore
|
18377
|
-
this._onStartStreaming = this._onEndStreaming = null;
|
18378
18270
|
};
|
18379
18271
|
_proto.registerListeners = function registerListeners() {
|
18380
18272
|
var hls = this.hls;
|
@@ -19235,7 +19127,7 @@
|
|
19235
19127
|
}
|
19236
19128
|
}]);
|
19237
19129
|
return BufferController;
|
19238
|
-
}(
|
19130
|
+
}();
|
19239
19131
|
function removeSourceChildren(node) {
|
19240
19132
|
var sourceChildren = node.querySelectorAll('source');
|
19241
19133
|
[].slice.call(sourceChildren).forEach(function (source) {
|
@@ -21674,12 +21566,14 @@
|
|
21674
21566
|
this.cea608Parser1 = this.cea608Parser2 = undefined;
|
21675
21567
|
};
|
21676
21568
|
_proto.initCea608Parsers = function initCea608Parsers() {
|
21677
|
-
|
21678
|
-
|
21679
|
-
|
21680
|
-
|
21681
|
-
|
21682
|
-
|
21569
|
+
if (this.config.enableCEA708Captions && (!this.cea608Parser1 || !this.cea608Parser2)) {
|
21570
|
+
var channel1 = new OutputFilter(this, 'textTrack1');
|
21571
|
+
var channel2 = new OutputFilter(this, 'textTrack2');
|
21572
|
+
var channel3 = new OutputFilter(this, 'textTrack3');
|
21573
|
+
var channel4 = new OutputFilter(this, 'textTrack4');
|
21574
|
+
this.cea608Parser1 = new Cea608Parser(1, channel1, channel2);
|
21575
|
+
this.cea608Parser2 = new Cea608Parser(3, channel3, channel4);
|
21576
|
+
}
|
21683
21577
|
};
|
21684
21578
|
_proto.addCues = function addCues(trackName, startTime, endTime, screen, cueRanges) {
|
21685
21579
|
// skip cues which overlap more than 50% with previously parsed time ranges
|
@@ -21914,7 +21808,7 @@
|
|
21914
21808
|
return t.label;
|
21915
21809
|
});
|
21916
21810
|
if (unusedTextTracks.length) {
|
21917
|
-
|
21811
|
+
logger.warn("Media element contains unused subtitle tracks: " + unusedTextTracks.join(', ') + ". Replace media element for each source to clear TextTracks and captions menu.");
|
21918
21812
|
}
|
21919
21813
|
}
|
21920
21814
|
} else if (this.tracks.length) {
|
@@ -21960,20 +21854,23 @@
|
|
21960
21854
|
return level == null ? void 0 : level.attrs['CLOSED-CAPTIONS'];
|
21961
21855
|
};
|
21962
21856
|
_proto.onFragLoading = function onFragLoading(event, data) {
|
21857
|
+
this.initCea608Parsers();
|
21858
|
+
var cea608Parser1 = this.cea608Parser1,
|
21859
|
+
cea608Parser2 = this.cea608Parser2,
|
21860
|
+
lastCc = this.lastCc,
|
21861
|
+
lastSn = this.lastSn,
|
21862
|
+
lastPartIndex = this.lastPartIndex;
|
21863
|
+
if (!this.enabled || !cea608Parser1 || !cea608Parser2) {
|
21864
|
+
return;
|
21865
|
+
}
|
21963
21866
|
// if this frag isn't contiguous, clear the parser so cues with bad start/end times aren't added to the textTrack
|
21964
|
-
if (
|
21867
|
+
if (data.frag.type === PlaylistLevelType.MAIN) {
|
21965
21868
|
var _data$part$index, _data$part;
|
21966
|
-
var cea608Parser1 = this.cea608Parser1,
|
21967
|
-
cea608Parser2 = this.cea608Parser2,
|
21968
|
-
lastSn = this.lastSn;
|
21969
|
-
if (!cea608Parser1 || !cea608Parser2) {
|
21970
|
-
return;
|
21971
|
-
}
|
21972
21869
|
var _data$frag = data.frag,
|
21973
21870
|
cc = _data$frag.cc,
|
21974
21871
|
sn = _data$frag.sn;
|
21975
|
-
var partIndex = (_data$part$index = (_data$part = data.part) == null ? void 0 : _data$part.index) != null ? _data$part$index : -1;
|
21976
|
-
if (!(sn === lastSn + 1 || sn === lastSn && partIndex ===
|
21872
|
+
var partIndex = (_data$part$index = data == null ? void 0 : (_data$part = data.part) == null ? void 0 : _data$part.index) != null ? _data$part$index : -1;
|
21873
|
+
if (!(sn === lastSn + 1 || sn === lastSn && partIndex === lastPartIndex + 1 || cc === lastCc)) {
|
21977
21874
|
cea608Parser1.reset();
|
21978
21875
|
cea608Parser2.reset();
|
21979
21876
|
}
|
@@ -22029,7 +21926,7 @@
|
|
22029
21926
|
frag: frag
|
22030
21927
|
});
|
22031
21928
|
}, function (error) {
|
22032
|
-
|
21929
|
+
logger.log("Failed to parse IMSC1: " + error);
|
22033
21930
|
hls.trigger(Events.SUBTITLE_FRAG_PROCESSED, {
|
22034
21931
|
success: false,
|
22035
21932
|
frag: frag,
|
@@ -22067,7 +21964,7 @@
|
|
22067
21964
|
_this5._fallbackToIMSC1(frag, payload);
|
22068
21965
|
}
|
22069
21966
|
// Something went wrong while parsing. Trigger event with success false.
|
22070
|
-
|
21967
|
+
logger.log("Failed to parse VTT cue: " + error);
|
22071
21968
|
if (missingInitPTS && maxAvCC > frag.cc) {
|
22072
21969
|
return;
|
22073
21970
|
}
|
@@ -22129,7 +22026,10 @@
|
|
22129
22026
|
this.captionsTracks = {};
|
22130
22027
|
};
|
22131
22028
|
_proto.onFragParsingUserdata = function onFragParsingUserdata(event, data) {
|
22132
|
-
|
22029
|
+
this.initCea608Parsers();
|
22030
|
+
var cea608Parser1 = this.cea608Parser1,
|
22031
|
+
cea608Parser2 = this.cea608Parser2;
|
22032
|
+
if (!this.enabled || !cea608Parser1 || !cea608Parser2) {
|
22133
22033
|
return;
|
22134
22034
|
}
|
22135
22035
|
var frag = data.frag,
|
@@ -22142,12 +22042,9 @@
|
|
22142
22042
|
for (var i = 0; i < samples.length; i++) {
|
22143
22043
|
var ccBytes = samples[i].bytes;
|
22144
22044
|
if (ccBytes) {
|
22145
|
-
if (!this.cea608Parser1) {
|
22146
|
-
this.initCea608Parsers();
|
22147
|
-
}
|
22148
22045
|
var ccdatas = this.extractCea608Data(ccBytes);
|
22149
|
-
|
22150
|
-
|
22046
|
+
cea608Parser1.addData(samples[i].pts, ccdatas[0]);
|
22047
|
+
cea608Parser2.addData(samples[i].pts, ccdatas[1]);
|
22151
22048
|
}
|
22152
22049
|
}
|
22153
22050
|
};
|
@@ -22339,7 +22236,7 @@
|
|
22339
22236
|
var hls = this.hls;
|
22340
22237
|
var maxLevel = this.getMaxLevel(levels.length - 1);
|
22341
22238
|
if (maxLevel !== this.autoLevelCapping) {
|
22342
|
-
|
22239
|
+
logger.log("Setting autoLevelCapping to " + maxLevel + ": " + levels[maxLevel].height + "p@" + levels[maxLevel].bitrate + " for media " + this.mediaWidth + "x" + this.mediaHeight);
|
22343
22240
|
}
|
22344
22241
|
hls.autoLevelCapping = maxLevel;
|
22345
22242
|
if (hls.autoLevelCapping > this.autoLevelCapping && this.streamController) {
|
@@ -22529,10 +22426,10 @@
|
|
22529
22426
|
totalDroppedFrames: droppedFrames
|
22530
22427
|
});
|
22531
22428
|
if (droppedFPS > 0) {
|
22532
|
-
//
|
22429
|
+
// logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
|
22533
22430
|
if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
|
22534
22431
|
var currentLevel = hls.currentLevel;
|
22535
|
-
|
22432
|
+
logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
|
22536
22433
|
if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
|
22537
22434
|
currentLevel = currentLevel - 1;
|
22538
22435
|
hls.trigger(Events.FPS_DROP_LEVEL_CAPPING, {
|
@@ -22565,6 +22462,7 @@
|
|
22565
22462
|
return FPSController;
|
22566
22463
|
}();
|
22567
22464
|
|
22465
|
+
var LOGGER_PREFIX = '[eme]';
|
22568
22466
|
/**
|
22569
22467
|
* Controller to deal with encrypted media extensions (EME)
|
22570
22468
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Encrypted_Media_Extensions_API
|
@@ -22572,122 +22470,26 @@
|
|
22572
22470
|
* @class
|
22573
22471
|
* @constructor
|
22574
22472
|
*/
|
22575
|
-
var EMEController = /*#__PURE__*/function (
|
22576
|
-
_inheritsLoose(EMEController, _Logger);
|
22473
|
+
var EMEController = /*#__PURE__*/function () {
|
22577
22474
|
function EMEController(hls) {
|
22578
|
-
|
22579
|
-
|
22580
|
-
|
22581
|
-
|
22582
|
-
|
22583
|
-
|
22584
|
-
|
22585
|
-
|
22586
|
-
|
22587
|
-
|
22588
|
-
|
22589
|
-
|
22590
|
-
|
22591
|
-
|
22592
|
-
|
22593
|
-
|
22594
|
-
|
22595
|
-
|
22596
|
-
return;
|
22597
|
-
}
|
22598
|
-
var keyId;
|
22599
|
-
var keySystemDomain;
|
22600
|
-
if (initDataType === 'sinf' && _this.config.drmSystems[KeySystems.FAIRPLAY]) {
|
22601
|
-
// Match sinf keyId to playlist skd://keyId=
|
22602
|
-
var json = bin2str(new Uint8Array(initData));
|
22603
|
-
try {
|
22604
|
-
var sinf = base64Decode(JSON.parse(json).sinf);
|
22605
|
-
var tenc = parseSinf(new Uint8Array(sinf));
|
22606
|
-
if (!tenc) {
|
22607
|
-
return;
|
22608
|
-
}
|
22609
|
-
keyId = tenc.subarray(8, 24);
|
22610
|
-
keySystemDomain = KeySystems.FAIRPLAY;
|
22611
|
-
} catch (error) {
|
22612
|
-
_this.warn('Failed to parse sinf "encrypted" event message initData');
|
22613
|
-
return;
|
22614
|
-
}
|
22615
|
-
} else {
|
22616
|
-
// Support clear-lead key-session creation (otherwise depend on playlist keys)
|
22617
|
-
var psshInfo = parsePssh(initData);
|
22618
|
-
if (psshInfo === null) {
|
22619
|
-
return;
|
22620
|
-
}
|
22621
|
-
if (psshInfo.version === 0 && psshInfo.systemId === KeySystemIds.WIDEVINE && psshInfo.data) {
|
22622
|
-
keyId = psshInfo.data.subarray(8, 24);
|
22623
|
-
}
|
22624
|
-
keySystemDomain = keySystemIdToKeySystemDomain(psshInfo.systemId);
|
22625
|
-
}
|
22626
|
-
if (!keySystemDomain || !keyId) {
|
22627
|
-
return;
|
22628
|
-
}
|
22629
|
-
var keyIdHex = Hex.hexDump(keyId);
|
22630
|
-
var _assertThisInitialize = _assertThisInitialized(_this),
|
22631
|
-
keyIdToKeySessionPromise = _assertThisInitialize.keyIdToKeySessionPromise,
|
22632
|
-
mediaKeySessions = _assertThisInitialize.mediaKeySessions;
|
22633
|
-
var keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex];
|
22634
|
-
var _loop = function _loop() {
|
22635
|
-
// Match playlist key
|
22636
|
-
var keyContext = mediaKeySessions[i];
|
22637
|
-
var decryptdata = keyContext.decryptdata;
|
22638
|
-
if (decryptdata.pssh || !decryptdata.keyId) {
|
22639
|
-
return 0; // continue
|
22640
|
-
}
|
22641
|
-
var oldKeyIdHex = Hex.hexDump(decryptdata.keyId);
|
22642
|
-
if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
|
22643
|
-
keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
|
22644
|
-
delete keyIdToKeySessionPromise[oldKeyIdHex];
|
22645
|
-
decryptdata.pssh = new Uint8Array(initData);
|
22646
|
-
decryptdata.keyId = keyId;
|
22647
|
-
keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = keySessionContextPromise.then(function () {
|
22648
|
-
return _this.generateRequestWithPreferredKeySession(keyContext, initDataType, initData, 'encrypted-event-key-match');
|
22649
|
-
});
|
22650
|
-
return 1; // break
|
22651
|
-
}
|
22652
|
-
},
|
22653
|
-
_ret;
|
22654
|
-
for (var i = 0; i < mediaKeySessions.length; i++) {
|
22655
|
-
_ret = _loop();
|
22656
|
-
if (_ret === 0) continue;
|
22657
|
-
if (_ret === 1) break;
|
22658
|
-
}
|
22659
|
-
if (!keySessionContextPromise) {
|
22660
|
-
// Clear-lead key (not encountered in playlist)
|
22661
|
-
keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = _this.getKeySystemSelectionPromise([keySystemDomain]).then(function (_ref) {
|
22662
|
-
var _keySystemToKeySystem;
|
22663
|
-
var keySystem = _ref.keySystem,
|
22664
|
-
mediaKeys = _ref.mediaKeys;
|
22665
|
-
_this.throwIfDestroyed();
|
22666
|
-
var decryptdata = new LevelKey('ISO-23001-7', keyIdHex, (_keySystemToKeySystem = keySystemDomainToKeySystemFormat(keySystem)) != null ? _keySystemToKeySystem : '');
|
22667
|
-
decryptdata.pssh = new Uint8Array(initData);
|
22668
|
-
decryptdata.keyId = keyId;
|
22669
|
-
return _this.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
|
22670
|
-
_this.throwIfDestroyed();
|
22671
|
-
var keySessionContext = _this.createMediaKeySessionContext({
|
22672
|
-
decryptdata: decryptdata,
|
22673
|
-
keySystem: keySystem,
|
22674
|
-
mediaKeys: mediaKeys
|
22675
|
-
});
|
22676
|
-
return _this.generateRequestWithPreferredKeySession(keySessionContext, initDataType, initData, 'encrypted-event-no-match');
|
22677
|
-
});
|
22678
|
-
});
|
22679
|
-
}
|
22680
|
-
keySessionContextPromise.catch(function (error) {
|
22681
|
-
return _this.handleError(error);
|
22682
|
-
});
|
22683
|
-
};
|
22684
|
-
_this.onWaitingForKey = function (event) {
|
22685
|
-
_this.log("\"" + event.type + "\" event");
|
22686
|
-
};
|
22687
|
-
_this.hls = hls;
|
22688
|
-
_this.config = hls.config;
|
22689
|
-
_this.registerListeners();
|
22690
|
-
return _this;
|
22475
|
+
this.hls = void 0;
|
22476
|
+
this.config = void 0;
|
22477
|
+
this.media = null;
|
22478
|
+
this.keyFormatPromise = null;
|
22479
|
+
this.keySystemAccessPromises = {};
|
22480
|
+
this._requestLicenseFailureCount = 0;
|
22481
|
+
this.mediaKeySessions = [];
|
22482
|
+
this.keyIdToKeySessionPromise = {};
|
22483
|
+
this.setMediaKeysQueue = EMEController.CDMCleanupPromise ? [EMEController.CDMCleanupPromise] : [];
|
22484
|
+
this.onMediaEncrypted = this._onMediaEncrypted.bind(this);
|
22485
|
+
this.onWaitingForKey = this._onWaitingForKey.bind(this);
|
22486
|
+
this.debug = logger.debug.bind(logger, LOGGER_PREFIX);
|
22487
|
+
this.log = logger.log.bind(logger, LOGGER_PREFIX);
|
22488
|
+
this.warn = logger.warn.bind(logger, LOGGER_PREFIX);
|
22489
|
+
this.error = logger.error.bind(logger, LOGGER_PREFIX);
|
22490
|
+
this.hls = hls;
|
22491
|
+
this.config = hls.config;
|
22492
|
+
this.registerListeners();
|
22691
22493
|
}
|
22692
22494
|
var _proto = EMEController.prototype;
|
22693
22495
|
_proto.destroy = function destroy() {
|
@@ -22699,9 +22501,9 @@
|
|
22699
22501
|
config.licenseXhrSetup = config.licenseResponseCallback = undefined;
|
22700
22502
|
config.drmSystems = config.drmSystemOptions = {};
|
22701
22503
|
// @ts-ignore
|
22702
|
-
this.hls = this.
|
22504
|
+
this.hls = this.onMediaEncrypted = this.onWaitingForKey = this.keyIdToKeySessionPromise = null;
|
22703
22505
|
// @ts-ignore
|
22704
|
-
this.
|
22506
|
+
this.config = null;
|
22705
22507
|
};
|
22706
22508
|
_proto.registerListeners = function registerListeners() {
|
22707
22509
|
this.hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
@@ -22740,7 +22542,7 @@
|
|
22740
22542
|
}
|
22741
22543
|
};
|
22742
22544
|
_proto.attemptKeySystemAccess = function attemptKeySystemAccess(keySystemsToAttempt) {
|
22743
|
-
var
|
22545
|
+
var _this = this;
|
22744
22546
|
var levels = this.hls.levels;
|
22745
22547
|
var uniqueCodec = function uniqueCodec(value, i, a) {
|
22746
22548
|
return !!value && a.indexOf(value) === i;
|
@@ -22757,7 +22559,7 @@
|
|
22757
22559
|
return new Promise(function (resolve, reject) {
|
22758
22560
|
var attempt = function attempt(keySystems) {
|
22759
22561
|
var keySystem = keySystems.shift();
|
22760
|
-
|
22562
|
+
_this.getMediaKeysPromise(keySystem, audioCodecs, videoCodecs).then(function (mediaKeys) {
|
22761
22563
|
return resolve({
|
22762
22564
|
keySystem: keySystem,
|
22763
22565
|
mediaKeys: mediaKeys
|
@@ -22792,7 +22594,7 @@
|
|
22792
22594
|
return requestMediaKeySystemAccessFunc(keySystem, supportedConfigurations);
|
22793
22595
|
};
|
22794
22596
|
_proto.getMediaKeysPromise = function getMediaKeysPromise(keySystem, audioCodecs, videoCodecs) {
|
22795
|
-
var
|
22597
|
+
var _this2 = this;
|
22796
22598
|
// This can throw, but is caught in event handler callpath
|
22797
22599
|
var mediaKeySystemConfigs = getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, this.config.drmSystemOptions);
|
22798
22600
|
var keySystemAccessPromises = this.keySystemAccessPromises[keySystem];
|
@@ -22804,23 +22606,23 @@
|
|
22804
22606
|
keySystemAccess: keySystemAccess
|
22805
22607
|
};
|
22806
22608
|
keySystemAccess.catch(function (error) {
|
22807
|
-
|
22609
|
+
_this2.log("Failed to obtain access to key-system \"" + keySystem + "\": " + error);
|
22808
22610
|
});
|
22809
22611
|
return keySystemAccess.then(function (mediaKeySystemAccess) {
|
22810
|
-
|
22811
|
-
var certificateRequest =
|
22812
|
-
|
22612
|
+
_this2.log("Access for key-system \"" + mediaKeySystemAccess.keySystem + "\" obtained");
|
22613
|
+
var certificateRequest = _this2.fetchServerCertificate(keySystem);
|
22614
|
+
_this2.log("Create media-keys for \"" + keySystem + "\"");
|
22813
22615
|
_keySystemAccessPromises.mediaKeys = mediaKeySystemAccess.createMediaKeys().then(function (mediaKeys) {
|
22814
|
-
|
22616
|
+
_this2.log("Media-keys created for \"" + keySystem + "\"");
|
22815
22617
|
return certificateRequest.then(function (certificate) {
|
22816
22618
|
if (certificate) {
|
22817
|
-
return
|
22619
|
+
return _this2.setMediaKeysServerCertificate(mediaKeys, keySystem, certificate);
|
22818
22620
|
}
|
22819
22621
|
return mediaKeys;
|
22820
22622
|
});
|
22821
22623
|
});
|
22822
22624
|
_keySystemAccessPromises.mediaKeys.catch(function (error) {
|
22823
|
-
|
22625
|
+
_this2.error("Failed to create media-keys for \"" + keySystem + "\"}: " + error);
|
22824
22626
|
});
|
22825
22627
|
return _keySystemAccessPromises.mediaKeys;
|
22826
22628
|
});
|
@@ -22829,10 +22631,10 @@
|
|
22829
22631
|
return keySystemAccessPromises.mediaKeys;
|
22830
22632
|
});
|
22831
22633
|
};
|
22832
|
-
_proto.createMediaKeySessionContext = function createMediaKeySessionContext(
|
22833
|
-
var decryptdata =
|
22834
|
-
keySystem =
|
22835
|
-
mediaKeys =
|
22634
|
+
_proto.createMediaKeySessionContext = function createMediaKeySessionContext(_ref) {
|
22635
|
+
var decryptdata = _ref.decryptdata,
|
22636
|
+
keySystem = _ref.keySystem,
|
22637
|
+
mediaKeys = _ref.mediaKeys;
|
22836
22638
|
this.log("Creating key-system session \"" + keySystem + "\" keyId: " + Hex.hexDump(decryptdata.keyId || []));
|
22837
22639
|
var mediaKeysSession = mediaKeys.createSession();
|
22838
22640
|
var mediaKeySessionContext = {
|
@@ -22881,14 +22683,14 @@
|
|
22881
22683
|
return this.keyFormatPromise;
|
22882
22684
|
};
|
22883
22685
|
_proto.getKeyFormatPromise = function getKeyFormatPromise(keyFormats) {
|
22884
|
-
var
|
22686
|
+
var _this3 = this;
|
22885
22687
|
return new Promise(function (resolve, reject) {
|
22886
|
-
var keySystemsInConfig = getKeySystemsForConfig(
|
22688
|
+
var keySystemsInConfig = getKeySystemsForConfig(_this3.config);
|
22887
22689
|
var keySystemsToAttempt = keyFormats.map(keySystemFormatToKeySystemDomain).filter(function (value) {
|
22888
22690
|
return !!value && keySystemsInConfig.indexOf(value) !== -1;
|
22889
22691
|
});
|
22890
|
-
return
|
22891
|
-
var keySystem =
|
22692
|
+
return _this3.getKeySystemSelectionPromise(keySystemsToAttempt).then(function (_ref2) {
|
22693
|
+
var keySystem = _ref2.keySystem;
|
22892
22694
|
var keySystemFormat = keySystemDomainToKeySystemFormat(keySystem);
|
22893
22695
|
if (keySystemFormat) {
|
22894
22696
|
resolve(keySystemFormat);
|
@@ -22899,31 +22701,31 @@
|
|
22899
22701
|
});
|
22900
22702
|
};
|
22901
22703
|
_proto.loadKey = function loadKey(data) {
|
22902
|
-
var
|
22704
|
+
var _this4 = this;
|
22903
22705
|
var decryptdata = data.keyInfo.decryptdata;
|
22904
22706
|
var keyId = this.getKeyIdString(decryptdata);
|
22905
22707
|
var keyDetails = "(keyId: " + keyId + " format: \"" + decryptdata.keyFormat + "\" method: " + decryptdata.method + " uri: " + decryptdata.uri + ")";
|
22906
22708
|
this.log("Starting session for key " + keyDetails);
|
22907
22709
|
var keySessionContextPromise = this.keyIdToKeySessionPromise[keyId];
|
22908
22710
|
if (!keySessionContextPromise) {
|
22909
|
-
keySessionContextPromise = this.keyIdToKeySessionPromise[keyId] = this.getKeySystemForKeyPromise(decryptdata).then(function (
|
22910
|
-
var keySystem =
|
22911
|
-
mediaKeys =
|
22912
|
-
|
22913
|
-
|
22914
|
-
return
|
22915
|
-
|
22916
|
-
var keySessionContext =
|
22711
|
+
keySessionContextPromise = this.keyIdToKeySessionPromise[keyId] = this.getKeySystemForKeyPromise(decryptdata).then(function (_ref3) {
|
22712
|
+
var keySystem = _ref3.keySystem,
|
22713
|
+
mediaKeys = _ref3.mediaKeys;
|
22714
|
+
_this4.throwIfDestroyed();
|
22715
|
+
_this4.log("Handle encrypted media sn: " + data.frag.sn + " " + data.frag.type + ": " + data.frag.level + " using key " + keyDetails);
|
22716
|
+
return _this4.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
|
22717
|
+
_this4.throwIfDestroyed();
|
22718
|
+
var keySessionContext = _this4.createMediaKeySessionContext({
|
22917
22719
|
keySystem: keySystem,
|
22918
22720
|
mediaKeys: mediaKeys,
|
22919
22721
|
decryptdata: decryptdata
|
22920
22722
|
});
|
22921
22723
|
var scheme = 'cenc';
|
22922
|
-
return
|
22724
|
+
return _this4.generateRequestWithPreferredKeySession(keySessionContext, scheme, decryptdata.pssh, 'playlist-key');
|
22923
22725
|
});
|
22924
22726
|
});
|
22925
22727
|
keySessionContextPromise.catch(function (error) {
|
22926
|
-
return
|
22728
|
+
return _this4.handleError(error);
|
22927
22729
|
});
|
22928
22730
|
}
|
22929
22731
|
return keySessionContextPromise;
|
@@ -22974,6 +22776,104 @@
|
|
22974
22776
|
}
|
22975
22777
|
return this.attemptKeySystemAccess(keySystemsToAttempt);
|
22976
22778
|
};
|
22779
|
+
_proto._onMediaEncrypted = function _onMediaEncrypted(event) {
|
22780
|
+
var _this5 = this;
|
22781
|
+
var initDataType = event.initDataType,
|
22782
|
+
initData = event.initData;
|
22783
|
+
this.debug("\"" + event.type + "\" event: init data type: \"" + initDataType + "\"");
|
22784
|
+
|
22785
|
+
// Ignore event when initData is null
|
22786
|
+
if (initData === null) {
|
22787
|
+
return;
|
22788
|
+
}
|
22789
|
+
var keyId;
|
22790
|
+
var keySystemDomain;
|
22791
|
+
if (initDataType === 'sinf' && this.config.drmSystems[KeySystems.FAIRPLAY]) {
|
22792
|
+
// Match sinf keyId to playlist skd://keyId=
|
22793
|
+
var json = bin2str(new Uint8Array(initData));
|
22794
|
+
try {
|
22795
|
+
var sinf = base64Decode(JSON.parse(json).sinf);
|
22796
|
+
var tenc = parseSinf(new Uint8Array(sinf));
|
22797
|
+
if (!tenc) {
|
22798
|
+
return;
|
22799
|
+
}
|
22800
|
+
keyId = tenc.subarray(8, 24);
|
22801
|
+
keySystemDomain = KeySystems.FAIRPLAY;
|
22802
|
+
} catch (error) {
|
22803
|
+
this.warn('Failed to parse sinf "encrypted" event message initData');
|
22804
|
+
return;
|
22805
|
+
}
|
22806
|
+
} else {
|
22807
|
+
// Support clear-lead key-session creation (otherwise depend on playlist keys)
|
22808
|
+
var psshInfo = parsePssh(initData);
|
22809
|
+
if (psshInfo === null) {
|
22810
|
+
return;
|
22811
|
+
}
|
22812
|
+
if (psshInfo.version === 0 && psshInfo.systemId === KeySystemIds.WIDEVINE && psshInfo.data) {
|
22813
|
+
keyId = psshInfo.data.subarray(8, 24);
|
22814
|
+
}
|
22815
|
+
keySystemDomain = keySystemIdToKeySystemDomain(psshInfo.systemId);
|
22816
|
+
}
|
22817
|
+
if (!keySystemDomain || !keyId) {
|
22818
|
+
return;
|
22819
|
+
}
|
22820
|
+
var keyIdHex = Hex.hexDump(keyId);
|
22821
|
+
var keyIdToKeySessionPromise = this.keyIdToKeySessionPromise,
|
22822
|
+
mediaKeySessions = this.mediaKeySessions;
|
22823
|
+
var keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex];
|
22824
|
+
var _loop = function _loop() {
|
22825
|
+
// Match playlist key
|
22826
|
+
var keyContext = mediaKeySessions[i];
|
22827
|
+
var decryptdata = keyContext.decryptdata;
|
22828
|
+
if (decryptdata.pssh || !decryptdata.keyId) {
|
22829
|
+
return 0; // continue
|
22830
|
+
}
|
22831
|
+
var oldKeyIdHex = Hex.hexDump(decryptdata.keyId);
|
22832
|
+
if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
|
22833
|
+
keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
|
22834
|
+
delete keyIdToKeySessionPromise[oldKeyIdHex];
|
22835
|
+
decryptdata.pssh = new Uint8Array(initData);
|
22836
|
+
decryptdata.keyId = keyId;
|
22837
|
+
keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = keySessionContextPromise.then(function () {
|
22838
|
+
return _this5.generateRequestWithPreferredKeySession(keyContext, initDataType, initData, 'encrypted-event-key-match');
|
22839
|
+
});
|
22840
|
+
return 1; // break
|
22841
|
+
}
|
22842
|
+
},
|
22843
|
+
_ret;
|
22844
|
+
for (var i = 0; i < mediaKeySessions.length; i++) {
|
22845
|
+
_ret = _loop();
|
22846
|
+
if (_ret === 0) continue;
|
22847
|
+
if (_ret === 1) break;
|
22848
|
+
}
|
22849
|
+
if (!keySessionContextPromise) {
|
22850
|
+
// Clear-lead key (not encountered in playlist)
|
22851
|
+
keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = this.getKeySystemSelectionPromise([keySystemDomain]).then(function (_ref4) {
|
22852
|
+
var _keySystemToKeySystem;
|
22853
|
+
var keySystem = _ref4.keySystem,
|
22854
|
+
mediaKeys = _ref4.mediaKeys;
|
22855
|
+
_this5.throwIfDestroyed();
|
22856
|
+
var decryptdata = new LevelKey('ISO-23001-7', keyIdHex, (_keySystemToKeySystem = keySystemDomainToKeySystemFormat(keySystem)) != null ? _keySystemToKeySystem : '');
|
22857
|
+
decryptdata.pssh = new Uint8Array(initData);
|
22858
|
+
decryptdata.keyId = keyId;
|
22859
|
+
return _this5.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
|
22860
|
+
_this5.throwIfDestroyed();
|
22861
|
+
var keySessionContext = _this5.createMediaKeySessionContext({
|
22862
|
+
decryptdata: decryptdata,
|
22863
|
+
keySystem: keySystem,
|
22864
|
+
mediaKeys: mediaKeys
|
22865
|
+
});
|
22866
|
+
return _this5.generateRequestWithPreferredKeySession(keySessionContext, initDataType, initData, 'encrypted-event-no-match');
|
22867
|
+
});
|
22868
|
+
});
|
22869
|
+
}
|
22870
|
+
keySessionContextPromise.catch(function (error) {
|
22871
|
+
return _this5.handleError(error);
|
22872
|
+
});
|
22873
|
+
};
|
22874
|
+
_proto._onWaitingForKey = function _onWaitingForKey(event) {
|
22875
|
+
this.log("\"" + event.type + "\" event");
|
22876
|
+
};
|
22977
22877
|
_proto.attemptSetMediaKeys = function attemptSetMediaKeys(keySystem, mediaKeys) {
|
22978
22878
|
var _this6 = this;
|
22979
22879
|
var queue = this.setMediaKeysQueue.slice();
|
@@ -23429,7 +23329,7 @@
|
|
23429
23329
|
}
|
23430
23330
|
};
|
23431
23331
|
return EMEController;
|
23432
|
-
}(
|
23332
|
+
}();
|
23433
23333
|
EMEController.CDMCleanupPromise = void 0;
|
23434
23334
|
var EMEKeyError = /*#__PURE__*/function (_Error) {
|
23435
23335
|
_inheritsLoose(EMEKeyError, _Error);
|
@@ -23577,6 +23477,18 @@
|
|
23577
23477
|
this.params = params;
|
23578
23478
|
};
|
23579
23479
|
|
23480
|
+
/**
|
23481
|
+
* A class to represent structured field tokens when `Symbol` is not available.
|
23482
|
+
*
|
23483
|
+
* @group Structured Field
|
23484
|
+
*
|
23485
|
+
* @beta
|
23486
|
+
*/
|
23487
|
+
var SfToken = function SfToken(description) {
|
23488
|
+
this.description = void 0;
|
23489
|
+
this.description = description;
|
23490
|
+
};
|
23491
|
+
|
23580
23492
|
var DICT = 'Dict';
|
23581
23493
|
|
23582
23494
|
function format(value) {
|
@@ -23600,25 +23512,29 @@
|
|
23600
23512
|
});
|
23601
23513
|
}
|
23602
23514
|
|
23603
|
-
|
23604
|
-
|
23515
|
+
var BARE_ITEM = 'Bare Item';
|
23516
|
+
|
23517
|
+
var BOOLEAN = 'Boolean';
|
23518
|
+
|
23519
|
+
var BYTES = 'Byte Sequence';
|
23520
|
+
|
23521
|
+
var DECIMAL = 'Decimal';
|
23522
|
+
|
23523
|
+
var INTEGER = 'Integer';
|
23524
|
+
|
23525
|
+
function isInvalidInt(value) {
|
23526
|
+
return value < -999999999999999 || 999999999999999 < value;
|
23605
23527
|
}
|
23606
23528
|
|
23607
|
-
|
23608
|
-
* A class to represent structured field tokens when `Symbol` is not available.
|
23609
|
-
*
|
23610
|
-
* @group Structured Field
|
23611
|
-
*
|
23612
|
-
* @beta
|
23613
|
-
*/
|
23614
|
-
var SfToken = function SfToken(description) {
|
23615
|
-
this.description = void 0;
|
23616
|
-
this.description = description;
|
23617
|
-
};
|
23529
|
+
var STRING_REGEX = /[\x00-\x1f\x7f]+/; // eslint-disable-line no-control-regex
|
23618
23530
|
|
23619
|
-
var
|
23531
|
+
var TOKEN = 'Token';
|
23620
23532
|
|
23621
|
-
var
|
23533
|
+
var KEY = 'Key';
|
23534
|
+
|
23535
|
+
function serializeError(src, type, cause) {
|
23536
|
+
return throwError('serialize', src, type, cause);
|
23537
|
+
}
|
23622
23538
|
|
23623
23539
|
// 4.1.9. Serializing a Boolean
|
23624
23540
|
//
|
@@ -23657,8 +23573,6 @@
|
|
23657
23573
|
return btoa(String.fromCharCode.apply(String, binary));
|
23658
23574
|
}
|
23659
23575
|
|
23660
|
-
var BYTES = 'Byte Sequence';
|
23661
|
-
|
23662
23576
|
// 4.1.8. Serializing a Byte Sequence
|
23663
23577
|
//
|
23664
23578
|
// Given a Byte Sequence as input_bytes, return an ASCII string suitable
|
@@ -23690,12 +23604,6 @@
|
|
23690
23604
|
return ":" + base64encode(value) + ":";
|
23691
23605
|
}
|
23692
23606
|
|
23693
|
-
var INTEGER = 'Integer';
|
23694
|
-
|
23695
|
-
function isInvalidInt(value) {
|
23696
|
-
return value < -999999999999999 || 999999999999999 < value;
|
23697
|
-
}
|
23698
|
-
|
23699
23607
|
// 4.1.4. Serializing an Integer
|
23700
23608
|
//
|
23701
23609
|
// Given an Integer as input_integer, return an ASCII string suitable
|
@@ -23761,8 +23669,6 @@
|
|
23761
23669
|
}
|
23762
23670
|
}
|
23763
23671
|
|
23764
|
-
var DECIMAL = 'Decimal';
|
23765
|
-
|
23766
23672
|
// 4.1.5. Serializing a Decimal
|
23767
23673
|
//
|
23768
23674
|
// Given a decimal number as input_decimal, return an ASCII string
|
@@ -23808,8 +23714,6 @@
|
|
23808
23714
|
|
23809
23715
|
var STRING = 'String';
|
23810
23716
|
|
23811
|
-
var STRING_REGEX = /[\x00-\x1f\x7f]+/; // eslint-disable-line no-control-regex
|
23812
|
-
|
23813
23717
|
// 4.1.6. Serializing a String
|
23814
23718
|
//
|
23815
23719
|
// Given a String as input_string, return an ASCII string suitable for
|
@@ -23845,8 +23749,6 @@
|
|
23845
23749
|
return symbol.description || symbol.toString().slice(7, -1);
|
23846
23750
|
}
|
23847
23751
|
|
23848
|
-
var TOKEN = 'Token';
|
23849
|
-
|
23850
23752
|
function serializeToken(token) {
|
23851
23753
|
var value = symbolToStr(token);
|
23852
23754
|
if (/^([a-zA-Z*])([!#$%&'*+\-.^_`|~\w:/]*)$/.test(value) === false) {
|
@@ -23914,8 +23816,6 @@
|
|
23914
23816
|
}
|
23915
23817
|
}
|
23916
23818
|
|
23917
|
-
var KEY = 'Key';
|
23918
|
-
|
23919
23819
|
// 4.1.1.3. Serializing a Key
|
23920
23820
|
//
|
23921
23821
|
// Given a key as input_key, return an ASCII string suitable for use in
|
@@ -24167,6 +24067,36 @@
|
|
24167
24067
|
return toPath.join('/');
|
24168
24068
|
}
|
24169
24069
|
|
24070
|
+
/**
|
24071
|
+
* Generate a random v4 UUID
|
24072
|
+
*
|
24073
|
+
* @returns A random v4 UUID
|
24074
|
+
*
|
24075
|
+
* @group Utils
|
24076
|
+
*
|
24077
|
+
* @beta
|
24078
|
+
*/
|
24079
|
+
function uuid() {
|
24080
|
+
try {
|
24081
|
+
return crypto.randomUUID();
|
24082
|
+
} catch (error) {
|
24083
|
+
try {
|
24084
|
+
var url = URL.createObjectURL(new Blob());
|
24085
|
+
var _uuid = url.toString();
|
24086
|
+
URL.revokeObjectURL(url);
|
24087
|
+
return _uuid.slice(_uuid.lastIndexOf('/') + 1);
|
24088
|
+
} catch (error) {
|
24089
|
+
var dt = new Date().getTime();
|
24090
|
+
var _uuid2 = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
24091
|
+
var r = (dt + Math.random() * 16) % 16 | 0;
|
24092
|
+
dt = Math.floor(dt / 16);
|
24093
|
+
return (c == 'x' ? r : r & 0x3 | 0x8).toString(16);
|
24094
|
+
});
|
24095
|
+
return _uuid2;
|
24096
|
+
}
|
24097
|
+
}
|
24098
|
+
}
|
24099
|
+
|
24170
24100
|
var toRounded = function toRounded(value) {
|
24171
24101
|
return Math.round(value);
|
24172
24102
|
};
|
@@ -24411,36 +24341,6 @@
|
|
24411
24341
|
return "" + url + separator + query;
|
24412
24342
|
}
|
24413
24343
|
|
24414
|
-
/**
|
24415
|
-
* Generate a random v4 UUID
|
24416
|
-
*
|
24417
|
-
* @returns A random v4 UUID
|
24418
|
-
*
|
24419
|
-
* @group Utils
|
24420
|
-
*
|
24421
|
-
* @beta
|
24422
|
-
*/
|
24423
|
-
function uuid() {
|
24424
|
-
try {
|
24425
|
-
return crypto.randomUUID();
|
24426
|
-
} catch (error) {
|
24427
|
-
try {
|
24428
|
-
var url = URL.createObjectURL(new Blob());
|
24429
|
-
var _uuid = url.toString();
|
24430
|
-
URL.revokeObjectURL(url);
|
24431
|
-
return _uuid.slice(_uuid.lastIndexOf('/') + 1);
|
24432
|
-
} catch (error) {
|
24433
|
-
var dt = new Date().getTime();
|
24434
|
-
var _uuid2 = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
24435
|
-
var r = (dt + Math.random() * 16) % 16 | 0;
|
24436
|
-
dt = Math.floor(dt / 16);
|
24437
|
-
return (c == 'x' ? r : r & 0x3 | 0x8).toString(16);
|
24438
|
-
});
|
24439
|
-
return _uuid2;
|
24440
|
-
}
|
24441
|
-
}
|
24442
|
-
}
|
24443
|
-
|
24444
24344
|
/**
|
24445
24345
|
* Controller to deal with Common Media Client Data (CMCD)
|
24446
24346
|
* @see https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf
|
@@ -24505,12 +24405,6 @@
|
|
24505
24405
|
data.tb = _this.getTopBandwidth(ot) / 1000;
|
24506
24406
|
data.bl = _this.getBufferLength(ot);
|
24507
24407
|
}
|
24508
|
-
var next = _this.getNextFrag(fragment);
|
24509
|
-
if (next) {
|
24510
|
-
if (next.url && next.url !== fragment.url) {
|
24511
|
-
data.nor = next.url;
|
24512
|
-
}
|
24513
|
-
}
|
24514
24408
|
_this.apply(context, data);
|
24515
24409
|
} catch (error) {
|
24516
24410
|
logger.warn('Could not generate segment CMCD data.', error);
|
@@ -24605,7 +24499,7 @@
|
|
24605
24499
|
data.su = this.buffering;
|
24606
24500
|
}
|
24607
24501
|
|
24608
|
-
// TODO: Implement rtp, nrr, dl
|
24502
|
+
// TODO: Implement rtp, nrr, nor, dl
|
24609
24503
|
|
24610
24504
|
var includeKeys = this.includeKeys;
|
24611
24505
|
if (includeKeys) {
|
@@ -24614,31 +24508,18 @@
|
|
24614
24508
|
return acc;
|
24615
24509
|
}, {});
|
24616
24510
|
}
|
24617
|
-
var options = {
|
24618
|
-
baseUrl: context.url
|
24619
|
-
};
|
24620
24511
|
if (this.useHeaders) {
|
24621
24512
|
if (!context.headers) {
|
24622
24513
|
context.headers = {};
|
24623
24514
|
}
|
24624
|
-
appendCmcdHeaders(context.headers, data
|
24515
|
+
appendCmcdHeaders(context.headers, data);
|
24625
24516
|
} else {
|
24626
|
-
context.url = appendCmcdQuery(context.url, data
|
24517
|
+
context.url = appendCmcdQuery(context.url, data);
|
24627
24518
|
}
|
24628
24519
|
};
|
24629
|
-
_proto.getNextFrag = function getNextFrag(fragment) {
|
24630
|
-
var _this$hls$levels$frag;
|
24631
|
-
var levelDetails = (_this$hls$levels$frag = this.hls.levels[fragment.level]) == null ? void 0 : _this$hls$levels$frag.details;
|
24632
|
-
if (levelDetails) {
|
24633
|
-
var index = fragment.sn - levelDetails.startSN;
|
24634
|
-
return levelDetails.fragments[index + 1];
|
24635
|
-
}
|
24636
|
-
return undefined;
|
24637
|
-
}
|
24638
|
-
|
24639
24520
|
/**
|
24640
24521
|
* The CMCD object type.
|
24641
|
-
|
24522
|
+
*/
|
24642
24523
|
_proto.getObjectType = function getObjectType(fragment) {
|
24643
24524
|
var type = fragment.type;
|
24644
24525
|
if (type === 'subtitle') {
|
@@ -24774,28 +24655,26 @@
|
|
24774
24655
|
}();
|
24775
24656
|
|
24776
24657
|
var PATHWAY_PENALTY_DURATION_MS = 300000;
|
24777
|
-
var ContentSteeringController = /*#__PURE__*/function (
|
24778
|
-
_inheritsLoose(ContentSteeringController, _Logger);
|
24658
|
+
var ContentSteeringController = /*#__PURE__*/function () {
|
24779
24659
|
function ContentSteeringController(hls) {
|
24780
|
-
|
24781
|
-
|
24782
|
-
|
24783
|
-
|
24784
|
-
|
24785
|
-
|
24786
|
-
|
24787
|
-
|
24788
|
-
|
24789
|
-
|
24790
|
-
|
24791
|
-
|
24792
|
-
|
24793
|
-
|
24794
|
-
|
24795
|
-
|
24796
|
-
|
24797
|
-
|
24798
|
-
return _this;
|
24660
|
+
this.hls = void 0;
|
24661
|
+
this.log = void 0;
|
24662
|
+
this.loader = null;
|
24663
|
+
this.uri = null;
|
24664
|
+
this.pathwayId = '.';
|
24665
|
+
this.pathwayPriority = null;
|
24666
|
+
this.timeToLoad = 300;
|
24667
|
+
this.reloadTimer = -1;
|
24668
|
+
this.updated = 0;
|
24669
|
+
this.started = false;
|
24670
|
+
this.enabled = true;
|
24671
|
+
this.levels = null;
|
24672
|
+
this.audioTracks = null;
|
24673
|
+
this.subtitleTracks = null;
|
24674
|
+
this.penalizedPathways = {};
|
24675
|
+
this.hls = hls;
|
24676
|
+
this.log = logger.log.bind(logger, "[content-steering]:");
|
24677
|
+
this.registerListeners();
|
24799
24678
|
}
|
24800
24679
|
var _proto = ContentSteeringController.prototype;
|
24801
24680
|
_proto.registerListeners = function registerListeners() {
|
@@ -24916,7 +24795,7 @@
|
|
24916
24795
|
errorAction.resolved = this.pathwayId !== errorPathway;
|
24917
24796
|
}
|
24918
24797
|
if (!errorAction.resolved) {
|
24919
|
-
|
24798
|
+
logger.warn("Could not resolve " + data.details + " (\"" + data.error.message + "\") with content-steering for Pathway: " + errorPathway + " levels: " + (levels ? levels.length : levels) + " priorities: " + JSON.stringify(pathwayPriority) + " penalized: " + JSON.stringify(this.penalizedPathways));
|
24920
24799
|
}
|
24921
24800
|
}
|
24922
24801
|
};
|
@@ -24996,7 +24875,7 @@
|
|
24996
24875
|
return defaultPathway;
|
24997
24876
|
};
|
24998
24877
|
_proto.clonePathways = function clonePathways(pathwayClones) {
|
24999
|
-
var
|
24878
|
+
var _this = this;
|
25000
24879
|
var levels = this.levels;
|
25001
24880
|
if (!levels) {
|
25002
24881
|
return;
|
@@ -25012,7 +24891,7 @@
|
|
25012
24891
|
})) {
|
25013
24892
|
return;
|
25014
24893
|
}
|
25015
|
-
var clonedVariants =
|
24894
|
+
var clonedVariants = _this.getLevelsForPathway(baseId).map(function (baseLevel) {
|
25016
24895
|
var attributes = new AttrList(baseLevel.attrs);
|
25017
24896
|
attributes['PATHWAY-ID'] = cloneId;
|
25018
24897
|
var clonedAudioGroupId = attributes.AUDIO && attributes.AUDIO + "_clone_" + cloneId;
|
@@ -25049,12 +24928,12 @@
|
|
25049
24928
|
return clonedLevel;
|
25050
24929
|
});
|
25051
24930
|
levels.push.apply(levels, clonedVariants);
|
25052
|
-
cloneRenditionGroups(
|
25053
|
-
cloneRenditionGroups(
|
24931
|
+
cloneRenditionGroups(_this.audioTracks, audioGroupCloneMap, uriReplacement, cloneId);
|
24932
|
+
cloneRenditionGroups(_this.subtitleTracks, subtitleGroupCloneMap, uriReplacement, cloneId);
|
25054
24933
|
});
|
25055
24934
|
};
|
25056
24935
|
_proto.loadSteeringManifest = function loadSteeringManifest(uri) {
|
25057
|
-
var
|
24936
|
+
var _this2 = this;
|
25058
24937
|
var config = this.hls.config;
|
25059
24938
|
var Loader = config.loader;
|
25060
24939
|
if (this.loader) {
|
@@ -25089,87 +24968,87 @@
|
|
25089
24968
|
};
|
25090
24969
|
var callbacks = {
|
25091
24970
|
onSuccess: function onSuccess(response, stats, context, networkDetails) {
|
25092
|
-
|
24971
|
+
_this2.log("Loaded steering manifest: \"" + url + "\"");
|
25093
24972
|
var steeringData = response.data;
|
25094
|
-
if (
|
25095
|
-
|
24973
|
+
if (steeringData.VERSION !== 1) {
|
24974
|
+
_this2.log("Steering VERSION " + steeringData.VERSION + " not supported!");
|
25096
24975
|
return;
|
25097
24976
|
}
|
25098
|
-
|
25099
|
-
|
24977
|
+
_this2.updated = performance.now();
|
24978
|
+
_this2.timeToLoad = steeringData.TTL;
|
25100
24979
|
var reloadUri = steeringData['RELOAD-URI'],
|
25101
24980
|
pathwayClones = steeringData['PATHWAY-CLONES'],
|
25102
24981
|
pathwayPriority = steeringData['PATHWAY-PRIORITY'];
|
25103
24982
|
if (reloadUri) {
|
25104
24983
|
try {
|
25105
|
-
|
24984
|
+
_this2.uri = new self.URL(reloadUri, url).href;
|
25106
24985
|
} catch (error) {
|
25107
|
-
|
25108
|
-
|
24986
|
+
_this2.enabled = false;
|
24987
|
+
_this2.log("Failed to parse Steering Manifest RELOAD-URI: " + reloadUri);
|
25109
24988
|
return;
|
25110
24989
|
}
|
25111
24990
|
}
|
25112
|
-
|
24991
|
+
_this2.scheduleRefresh(_this2.uri || context.url);
|
25113
24992
|
if (pathwayClones) {
|
25114
|
-
|
24993
|
+
_this2.clonePathways(pathwayClones);
|
25115
24994
|
}
|
25116
24995
|
var loadedSteeringData = {
|
25117
24996
|
steeringManifest: steeringData,
|
25118
24997
|
url: url.toString()
|
25119
24998
|
};
|
25120
|
-
|
24999
|
+
_this2.hls.trigger(Events.STEERING_MANIFEST_LOADED, loadedSteeringData);
|
25121
25000
|
if (pathwayPriority) {
|
25122
|
-
|
25001
|
+
_this2.updatePathwayPriority(pathwayPriority);
|
25123
25002
|
}
|
25124
25003
|
},
|
25125
25004
|
onError: function onError(error, context, networkDetails, stats) {
|
25126
|
-
|
25127
|
-
|
25005
|
+
_this2.log("Error loading steering manifest: " + error.code + " " + error.text + " (" + context.url + ")");
|
25006
|
+
_this2.stopLoad();
|
25128
25007
|
if (error.code === 410) {
|
25129
|
-
|
25130
|
-
|
25008
|
+
_this2.enabled = false;
|
25009
|
+
_this2.log("Steering manifest " + context.url + " no longer available");
|
25131
25010
|
return;
|
25132
25011
|
}
|
25133
|
-
var ttl =
|
25012
|
+
var ttl = _this2.timeToLoad * 1000;
|
25134
25013
|
if (error.code === 429) {
|
25135
|
-
var loader =
|
25014
|
+
var loader = _this2.loader;
|
25136
25015
|
if (typeof (loader == null ? void 0 : loader.getResponseHeader) === 'function') {
|
25137
25016
|
var retryAfter = loader.getResponseHeader('Retry-After');
|
25138
25017
|
if (retryAfter) {
|
25139
25018
|
ttl = parseFloat(retryAfter) * 1000;
|
25140
25019
|
}
|
25141
25020
|
}
|
25142
|
-
|
25021
|
+
_this2.log("Steering manifest " + context.url + " rate limited");
|
25143
25022
|
return;
|
25144
25023
|
}
|
25145
|
-
|
25024
|
+
_this2.scheduleRefresh(_this2.uri || context.url, ttl);
|
25146
25025
|
},
|
25147
25026
|
onTimeout: function onTimeout(stats, context, networkDetails) {
|
25148
|
-
|
25149
|
-
|
25027
|
+
_this2.log("Timeout loading steering manifest (" + context.url + ")");
|
25028
|
+
_this2.scheduleRefresh(_this2.uri || context.url);
|
25150
25029
|
}
|
25151
25030
|
};
|
25152
25031
|
this.log("Requesting steering manifest: " + url);
|
25153
25032
|
this.loader.load(context, loaderConfig, callbacks);
|
25154
25033
|
};
|
25155
25034
|
_proto.scheduleRefresh = function scheduleRefresh(uri, ttlMs) {
|
25156
|
-
var
|
25035
|
+
var _this3 = this;
|
25157
25036
|
if (ttlMs === void 0) {
|
25158
25037
|
ttlMs = this.timeToLoad * 1000;
|
25159
25038
|
}
|
25160
25039
|
this.clearTimeout();
|
25161
25040
|
this.reloadTimer = self.setTimeout(function () {
|
25162
|
-
var
|
25163
|
-
var media = (
|
25041
|
+
var _this3$hls;
|
25042
|
+
var media = (_this3$hls = _this3.hls) == null ? void 0 : _this3$hls.media;
|
25164
25043
|
if (media && !media.ended) {
|
25165
|
-
|
25044
|
+
_this3.loadSteeringManifest(uri);
|
25166
25045
|
return;
|
25167
25046
|
}
|
25168
|
-
|
25047
|
+
_this3.scheduleRefresh(uri, _this3.timeToLoad * 1000);
|
25169
25048
|
}, ttlMs);
|
25170
25049
|
};
|
25171
25050
|
return ContentSteeringController;
|
25172
|
-
}(
|
25051
|
+
}();
|
25173
25052
|
function cloneRenditionGroups(tracks, groupCloneMap, uriReplacement, cloneId) {
|
25174
25053
|
if (!tracks) {
|
25175
25054
|
return;
|
@@ -26069,7 +25948,7 @@
|
|
26069
25948
|
/**
|
26070
25949
|
* @ignore
|
26071
25950
|
*/
|
26072
|
-
function mergeConfig(defaultConfig, userConfig
|
25951
|
+
function mergeConfig(defaultConfig, userConfig) {
|
26073
25952
|
if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) {
|
26074
25953
|
throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration");
|
26075
25954
|
}
|
@@ -26139,7 +26018,7 @@
|
|
26139
26018
|
/**
|
26140
26019
|
* @ignore
|
26141
26020
|
*/
|
26142
|
-
function enableStreamingMode(config
|
26021
|
+
function enableStreamingMode(config) {
|
26143
26022
|
var currentLoader = config.loader;
|
26144
26023
|
if (currentLoader !== FetchLoader && currentLoader !== XhrLoader) {
|
26145
26024
|
// If a developer has configured their own loader, respect that choice
|
@@ -26156,11 +26035,12 @@
|
|
26156
26035
|
}
|
26157
26036
|
}
|
26158
26037
|
|
26038
|
+
var chromeOrFirefox;
|
26159
26039
|
var LevelController = /*#__PURE__*/function (_BasePlaylistControll) {
|
26160
26040
|
_inheritsLoose(LevelController, _BasePlaylistControll);
|
26161
26041
|
function LevelController(hls, contentSteeringController) {
|
26162
26042
|
var _this;
|
26163
|
-
_this = _BasePlaylistControll.call(this, hls, 'level-controller') || this;
|
26043
|
+
_this = _BasePlaylistControll.call(this, hls, '[level-controller]') || this;
|
26164
26044
|
_this._levels = [];
|
26165
26045
|
_this._firstLevel = -1;
|
26166
26046
|
_this._maxAutoLevel = -1;
|
@@ -26229,13 +26109,21 @@
|
|
26229
26109
|
var videoCodecFound = false;
|
26230
26110
|
var audioCodecFound = false;
|
26231
26111
|
data.levels.forEach(function (levelParsed) {
|
26232
|
-
var _videoCodec;
|
26112
|
+
var _audioCodec, _videoCodec;
|
26233
26113
|
var attributes = levelParsed.attrs;
|
26114
|
+
|
26115
|
+
// erase audio codec info if browser does not support mp4a.40.34.
|
26116
|
+
// demuxer will autodetect codec and fallback to mpeg/audio
|
26234
26117
|
var audioCodec = levelParsed.audioCodec,
|
26235
26118
|
videoCodec = levelParsed.videoCodec;
|
26119
|
+
if (((_audioCodec = audioCodec) == null ? void 0 : _audioCodec.indexOf('mp4a.40.34')) !== -1) {
|
26120
|
+
chromeOrFirefox || (chromeOrFirefox = /chrome|firefox/i.test(navigator.userAgent));
|
26121
|
+
if (chromeOrFirefox) {
|
26122
|
+
levelParsed.audioCodec = audioCodec = undefined;
|
26123
|
+
}
|
26124
|
+
}
|
26236
26125
|
if (audioCodec) {
|
26237
|
-
|
26238
|
-
levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource) || undefined;
|
26126
|
+
levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource);
|
26239
26127
|
}
|
26240
26128
|
if (((_videoCodec = videoCodec) == null ? void 0 : _videoCodec.indexOf('avc1')) === 0) {
|
26241
26129
|
videoCodec = levelParsed.videoCodec = convertAVC1ToAVCOTI(videoCodec);
|
@@ -26843,8 +26731,6 @@
|
|
26843
26731
|
}
|
26844
26732
|
return this.loadKeyEME(keyInfo, frag);
|
26845
26733
|
case 'AES-128':
|
26846
|
-
case 'AES-256':
|
26847
|
-
case 'AES-256-CTR':
|
26848
26734
|
return this.loadKeyHTTP(keyInfo, frag);
|
26849
26735
|
default:
|
26850
26736
|
return Promise.reject(this.createKeyLoadError(frag, ErrorDetails.KEY_LOAD_ERROR, new Error("Key supplied with unsupported METHOD: \"" + decryptdata.method + "\"")));
|
@@ -26984,26 +26870,21 @@
|
|
26984
26870
|
var MAX_START_GAP_JUMP = 2.0;
|
26985
26871
|
var SKIP_BUFFER_HOLE_STEP_SECONDS = 0.1;
|
26986
26872
|
var SKIP_BUFFER_RANGE_START = 0.05;
|
26987
|
-
var GapController = /*#__PURE__*/function (
|
26988
|
-
_inheritsLoose(GapController, _Logger);
|
26873
|
+
var GapController = /*#__PURE__*/function () {
|
26989
26874
|
function GapController(config, media, fragmentTracker, hls) {
|
26990
|
-
|
26991
|
-
|
26992
|
-
|
26993
|
-
|
26994
|
-
|
26995
|
-
|
26996
|
-
|
26997
|
-
|
26998
|
-
|
26999
|
-
|
27000
|
-
|
27001
|
-
|
27002
|
-
|
27003
|
-
_this.media = media;
|
27004
|
-
_this.fragmentTracker = fragmentTracker;
|
27005
|
-
_this.hls = hls;
|
27006
|
-
return _this;
|
26875
|
+
this.config = void 0;
|
26876
|
+
this.media = null;
|
26877
|
+
this.fragmentTracker = void 0;
|
26878
|
+
this.hls = void 0;
|
26879
|
+
this.nudgeRetry = 0;
|
26880
|
+
this.stallReported = false;
|
26881
|
+
this.stalled = null;
|
26882
|
+
this.moved = false;
|
26883
|
+
this.seeking = false;
|
26884
|
+
this.config = config;
|
26885
|
+
this.media = media;
|
26886
|
+
this.fragmentTracker = fragmentTracker;
|
26887
|
+
this.hls = hls;
|
27007
26888
|
}
|
27008
26889
|
var _proto = GapController.prototype;
|
27009
26890
|
_proto.destroy = function destroy() {
|
@@ -27018,7 +26899,7 @@
|
|
27018
26899
|
*
|
27019
26900
|
* @param lastCurrentTime - Previously read playhead position
|
27020
26901
|
*/;
|
27021
|
-
_proto.poll = function poll(lastCurrentTime, activeFrag
|
26902
|
+
_proto.poll = function poll(lastCurrentTime, activeFrag) {
|
27022
26903
|
var config = this.config,
|
27023
26904
|
media = this.media,
|
27024
26905
|
stalled = this.stalled;
|
@@ -27033,7 +26914,6 @@
|
|
27033
26914
|
|
27034
26915
|
// The playhead is moving, no-op
|
27035
26916
|
if (currentTime !== lastCurrentTime) {
|
27036
|
-
this.ended = 0;
|
27037
26917
|
this.moved = true;
|
27038
26918
|
if (!seeking) {
|
27039
26919
|
this.nudgeRetry = 0;
|
@@ -27042,7 +26922,7 @@
|
|
27042
26922
|
// The playhead is now moving, but was previously stalled
|
27043
26923
|
if (this.stallReported) {
|
27044
26924
|
var _stalledDuration = self.performance.now() - stalled;
|
27045
|
-
|
26925
|
+
logger.warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms");
|
27046
26926
|
this.stallReported = false;
|
27047
26927
|
}
|
27048
26928
|
this.stalled = null;
|
@@ -27078,6 +26958,7 @@
|
|
27078
26958
|
// Skip start gaps if we haven't played, but the last poll detected the start of a stall
|
27079
26959
|
// The addition poll gives the browser a chance to jump the gap for us
|
27080
26960
|
if (!this.moved && this.stalled !== null) {
|
26961
|
+
var _level$details;
|
27081
26962
|
// There is no playable buffer (seeked, waiting for buffer)
|
27082
26963
|
var isBuffered = bufferInfo.len > 0;
|
27083
26964
|
if (!isBuffered && !nextStart) {
|
@@ -27089,8 +26970,9 @@
|
|
27089
26970
|
// When joining a live stream with audio tracks, account for live playlist window sliding by allowing
|
27090
26971
|
// a larger jump over start gaps caused by the audio-stream-controller buffering a start fragment
|
27091
26972
|
// that begins over 1 target duration after the video start position.
|
27092
|
-
var
|
27093
|
-
var
|
26973
|
+
var level = this.hls.levels ? this.hls.levels[this.hls.currentLevel] : null;
|
26974
|
+
var isLive = level == null ? void 0 : (_level$details = level.details) == null ? void 0 : _level$details.live;
|
26975
|
+
var maxStartGapJump = isLive ? level.details.targetduration * 2 : MAX_START_GAP_JUMP;
|
27094
26976
|
var partialOrGap = this.fragmentTracker.getPartialFragment(currentTime);
|
27095
26977
|
if (startJump > 0 && (startJump <= maxStartGapJump || partialOrGap)) {
|
27096
26978
|
if (!media.paused) {
|
@@ -27108,17 +26990,6 @@
|
|
27108
26990
|
}
|
27109
26991
|
var stalledDuration = tnow - stalled;
|
27110
26992
|
if (!seeking && stalledDuration >= STALL_MINIMUM_DURATION_MS) {
|
27111
|
-
// Dispatch MEDIA_ENDED when media.ended/ended event is not signalled at end of stream
|
27112
|
-
if (state === State.ENDED && !(levelDetails && levelDetails.live) && Math.abs(currentTime - ((levelDetails == null ? void 0 : levelDetails.edge) || 0)) < 1) {
|
27113
|
-
if (stalledDuration < 1000 || this.ended) {
|
27114
|
-
return;
|
27115
|
-
}
|
27116
|
-
this.ended = currentTime;
|
27117
|
-
this.hls.trigger(Events.MEDIA_ENDED, {
|
27118
|
-
stalled: true
|
27119
|
-
});
|
27120
|
-
return;
|
27121
|
-
}
|
27122
26993
|
// Report stalling after trying to fix
|
27123
26994
|
this._reportStall(bufferInfo);
|
27124
26995
|
if (!this.media) {
|
@@ -27160,7 +27031,7 @@
|
|
27160
27031
|
// needs to cross some sort of threshold covering all source-buffers content
|
27161
27032
|
// to start playing properly.
|
27162
27033
|
if ((bufferInfo.len > config.maxBufferHole || bufferInfo.nextStart && bufferInfo.nextStart - currentTime < config.maxBufferHole) && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) {
|
27163
|
-
|
27034
|
+
logger.warn('Trying to nudge playhead over buffer-hole');
|
27164
27035
|
// Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds
|
27165
27036
|
// We only try to jump the hole if it's under the configured size
|
27166
27037
|
// Reset stalled so to rearm watchdog timer
|
@@ -27182,7 +27053,7 @@
|
|
27182
27053
|
// Report stalled error once
|
27183
27054
|
this.stallReported = true;
|
27184
27055
|
var error = new Error("Playback stalling at @" + media.currentTime + " due to low buffer (" + JSON.stringify(bufferInfo) + ")");
|
27185
|
-
|
27056
|
+
logger.warn(error.message);
|
27186
27057
|
hls.trigger(Events.ERROR, {
|
27187
27058
|
type: ErrorTypes.MEDIA_ERROR,
|
27188
27059
|
details: ErrorDetails.BUFFER_STALLED_ERROR,
|
@@ -27246,7 +27117,7 @@
|
|
27246
27117
|
}
|
27247
27118
|
}
|
27248
27119
|
var targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS);
|
27249
|
-
|
27120
|
+
logger.warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime);
|
27250
27121
|
this.moved = true;
|
27251
27122
|
this.stalled = null;
|
27252
27123
|
media.currentTime = targetTime;
|
@@ -27285,7 +27156,7 @@
|
|
27285
27156
|
var targetTime = currentTime + (nudgeRetry + 1) * config.nudgeOffset;
|
27286
27157
|
// playback stalled in buffered area ... let's nudge currentTime to try to overcome this
|
27287
27158
|
var error = new Error("Nudging 'currentTime' from " + currentTime + " to " + targetTime);
|
27288
|
-
|
27159
|
+
logger.warn(error.message);
|
27289
27160
|
media.currentTime = targetTime;
|
27290
27161
|
hls.trigger(Events.ERROR, {
|
27291
27162
|
type: ErrorTypes.MEDIA_ERROR,
|
@@ -27295,7 +27166,7 @@
|
|
27295
27166
|
});
|
27296
27167
|
} else {
|
27297
27168
|
var _error = new Error("Playhead still not moving while enough data buffered @" + currentTime + " after " + config.nudgeMaxRetry + " nudges");
|
27298
|
-
|
27169
|
+
logger.error(_error.message);
|
27299
27170
|
hls.trigger(Events.ERROR, {
|
27300
27171
|
type: ErrorTypes.MEDIA_ERROR,
|
27301
27172
|
details: ErrorDetails.BUFFER_STALLED_ERROR,
|
@@ -27305,14 +27176,14 @@
|
|
27305
27176
|
}
|
27306
27177
|
};
|
27307
27178
|
return GapController;
|
27308
|
-
}(
|
27179
|
+
}();
|
27309
27180
|
|
27310
27181
|
var TICK_INTERVAL = 100; // how often to tick in ms
|
27311
27182
|
var StreamController = /*#__PURE__*/function (_BaseStreamController) {
|
27312
27183
|
_inheritsLoose(StreamController, _BaseStreamController);
|
27313
27184
|
function StreamController(hls, fragmentTracker, keyLoader) {
|
27314
27185
|
var _this;
|
27315
|
-
_this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, 'stream-controller', PlaylistLevelType.MAIN) || this;
|
27186
|
+
_this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[stream-controller]', PlaylistLevelType.MAIN) || this;
|
27316
27187
|
_this.audioCodecSwap = false;
|
27317
27188
|
_this.gapController = null;
|
27318
27189
|
_this.level = -1;
|
@@ -27320,43 +27191,27 @@
|
|
27320
27191
|
_this.altAudio = false;
|
27321
27192
|
_this.audioOnly = false;
|
27322
27193
|
_this.fragPlaying = null;
|
27194
|
+
_this.onvplaying = null;
|
27195
|
+
_this.onvseeked = null;
|
27323
27196
|
_this.fragLastKbps = 0;
|
27324
27197
|
_this.couldBacktrack = false;
|
27325
27198
|
_this.backtrackFragment = null;
|
27326
27199
|
_this.audioCodecSwitch = false;
|
27327
27200
|
_this.videoBuffer = null;
|
27328
|
-
_this.
|
27329
|
-
// tick to speed up FRAG_CHANGED triggering
|
27330
|
-
_this.tick();
|
27331
|
-
};
|
27332
|
-
_this.onMediaSeeked = function () {
|
27333
|
-
var media = _this.media;
|
27334
|
-
var currentTime = media ? media.currentTime : null;
|
27335
|
-
if (isFiniteNumber(currentTime)) {
|
27336
|
-
_this.log("Media seeked to " + currentTime.toFixed(3));
|
27337
|
-
}
|
27338
|
-
|
27339
|
-
// If seeked was issued before buffer was appended do not tick immediately
|
27340
|
-
var bufferInfo = _this.getMainFwdBufferInfo();
|
27341
|
-
if (bufferInfo === null || bufferInfo.len === 0) {
|
27342
|
-
_this.warn("Main forward buffer length on \"seeked\" event " + (bufferInfo ? bufferInfo.len : 'empty') + ")");
|
27343
|
-
return;
|
27344
|
-
}
|
27345
|
-
|
27346
|
-
// tick to speed up FRAG_CHANGED triggering
|
27347
|
-
_this.tick();
|
27348
|
-
};
|
27349
|
-
_this.registerListeners();
|
27201
|
+
_this._registerListeners();
|
27350
27202
|
return _this;
|
27351
27203
|
}
|
27352
27204
|
var _proto = StreamController.prototype;
|
27353
|
-
_proto.
|
27354
|
-
_BaseStreamController.prototype.registerListeners.call(this);
|
27205
|
+
_proto._registerListeners = function _registerListeners() {
|
27355
27206
|
var hls = this.hls;
|
27207
|
+
hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
27208
|
+
hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
27209
|
+
hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
27356
27210
|
hls.on(Events.MANIFEST_PARSED, this.onManifestParsed, this);
|
27357
27211
|
hls.on(Events.LEVEL_LOADING, this.onLevelLoading, this);
|
27358
27212
|
hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
27359
27213
|
hls.on(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
|
27214
|
+
hls.on(Events.ERROR, this.onError, this);
|
27360
27215
|
hls.on(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
|
27361
27216
|
hls.on(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
|
27362
27217
|
hls.on(Events.BUFFER_CREATED, this.onBufferCreated, this);
|
@@ -27364,12 +27219,15 @@
|
|
27364
27219
|
hls.on(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
|
27365
27220
|
hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
27366
27221
|
};
|
27367
|
-
_proto.
|
27368
|
-
_BaseStreamController.prototype.unregisterListeners.call(this);
|
27222
|
+
_proto._unregisterListeners = function _unregisterListeners() {
|
27369
27223
|
var hls = this.hls;
|
27224
|
+
hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
27225
|
+
hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
27226
|
+
hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
27370
27227
|
hls.off(Events.MANIFEST_PARSED, this.onManifestParsed, this);
|
27371
27228
|
hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
27372
27229
|
hls.off(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
|
27230
|
+
hls.off(Events.ERROR, this.onError, this);
|
27373
27231
|
hls.off(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
|
27374
27232
|
hls.off(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
|
27375
27233
|
hls.off(Events.BUFFER_CREATED, this.onBufferCreated, this);
|
@@ -27378,9 +27236,7 @@
|
|
27378
27236
|
hls.off(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
27379
27237
|
};
|
27380
27238
|
_proto.onHandlerDestroying = function onHandlerDestroying() {
|
27381
|
-
|
27382
|
-
this.onMediaPlaying = this.onMediaSeeked = null;
|
27383
|
-
this.unregisterListeners();
|
27239
|
+
this._unregisterListeners();
|
27384
27240
|
_BaseStreamController.prototype.onHandlerDestroying.call(this);
|
27385
27241
|
};
|
27386
27242
|
_proto.startLoad = function startLoad(startPosition) {
|
@@ -27695,15 +27551,18 @@
|
|
27695
27551
|
_proto.onMediaAttached = function onMediaAttached(event, data) {
|
27696
27552
|
_BaseStreamController.prototype.onMediaAttached.call(this, event, data);
|
27697
27553
|
var media = data.media;
|
27698
|
-
|
27699
|
-
|
27554
|
+
this.onvplaying = this.onMediaPlaying.bind(this);
|
27555
|
+
this.onvseeked = this.onMediaSeeked.bind(this);
|
27556
|
+
media.addEventListener('playing', this.onvplaying);
|
27557
|
+
media.addEventListener('seeked', this.onvseeked);
|
27700
27558
|
this.gapController = new GapController(this.config, media, this.fragmentTracker, this.hls);
|
27701
27559
|
};
|
27702
27560
|
_proto.onMediaDetaching = function onMediaDetaching() {
|
27703
27561
|
var media = this.media;
|
27704
|
-
if (media) {
|
27705
|
-
media.removeEventListener('playing', this.
|
27706
|
-
media.removeEventListener('seeked', this.
|
27562
|
+
if (media && this.onvplaying && this.onvseeked) {
|
27563
|
+
media.removeEventListener('playing', this.onvplaying);
|
27564
|
+
media.removeEventListener('seeked', this.onvseeked);
|
27565
|
+
this.onvplaying = this.onvseeked = null;
|
27707
27566
|
this.videoBuffer = null;
|
27708
27567
|
}
|
27709
27568
|
this.fragPlaying = null;
|
@@ -27713,6 +27572,27 @@
|
|
27713
27572
|
}
|
27714
27573
|
_BaseStreamController.prototype.onMediaDetaching.call(this);
|
27715
27574
|
};
|
27575
|
+
_proto.onMediaPlaying = function onMediaPlaying() {
|
27576
|
+
// tick to speed up FRAG_CHANGED triggering
|
27577
|
+
this.tick();
|
27578
|
+
};
|
27579
|
+
_proto.onMediaSeeked = function onMediaSeeked() {
|
27580
|
+
var media = this.media;
|
27581
|
+
var currentTime = media ? media.currentTime : null;
|
27582
|
+
if (isFiniteNumber(currentTime)) {
|
27583
|
+
this.log("Media seeked to " + currentTime.toFixed(3));
|
27584
|
+
}
|
27585
|
+
|
27586
|
+
// If seeked was issued before buffer was appended do not tick immediately
|
27587
|
+
var bufferInfo = this.getMainFwdBufferInfo();
|
27588
|
+
if (bufferInfo === null || bufferInfo.len === 0) {
|
27589
|
+
this.warn("Main forward buffer length on \"seeked\" event " + (bufferInfo ? bufferInfo.len : 'empty') + ")");
|
27590
|
+
return;
|
27591
|
+
}
|
27592
|
+
|
27593
|
+
// tick to speed up FRAG_CHANGED triggering
|
27594
|
+
this.tick();
|
27595
|
+
};
|
27716
27596
|
_proto.onManifestLoading = function onManifestLoading() {
|
27717
27597
|
// reset buffer on manifest loading
|
27718
27598
|
this.log('Trigger BUFFER_RESET');
|
@@ -27993,10 +27873,8 @@
|
|
27993
27873
|
}
|
27994
27874
|
if (this.loadedmetadata || !BufferHelper.getBuffered(media).length) {
|
27995
27875
|
// Resolve gaps using the main buffer, whose ranges are the intersections of the A/V sourcebuffers
|
27996
|
-
var
|
27997
|
-
|
27998
|
-
var levelDetails = this.getLevelDetails();
|
27999
|
-
gapController.poll(this.lastCurrentTime, activeFrag, levelDetails, state);
|
27876
|
+
var activeFrag = this.state !== State.IDLE ? this.fragCurrent : null;
|
27877
|
+
gapController.poll(this.lastCurrentTime, activeFrag);
|
28000
27878
|
}
|
28001
27879
|
this.lastCurrentTime = media.currentTime;
|
28002
27880
|
};
|
@@ -28461,10 +28339,6 @@
|
|
28461
28339
|
* The configuration object provided on player instantiation.
|
28462
28340
|
*/
|
28463
28341
|
this.userConfig = void 0;
|
28464
|
-
/**
|
28465
|
-
* The logger functions used by this player instance, configured on player instantiation.
|
28466
|
-
*/
|
28467
|
-
this.logger = void 0;
|
28468
28342
|
this.coreComponents = void 0;
|
28469
28343
|
this.networkControllers = void 0;
|
28470
28344
|
this.started = false;
|
@@ -28484,11 +28358,11 @@
|
|
28484
28358
|
this._media = null;
|
28485
28359
|
this.url = null;
|
28486
28360
|
this.triggeringException = void 0;
|
28487
|
-
|
28488
|
-
var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig
|
28361
|
+
enableLogs(userConfig.debug || false, 'Hls instance');
|
28362
|
+
var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig);
|
28489
28363
|
this.userConfig = userConfig;
|
28490
28364
|
if (config.progressive) {
|
28491
|
-
enableStreamingMode(config
|
28365
|
+
enableStreamingMode(config);
|
28492
28366
|
}
|
28493
28367
|
|
28494
28368
|
// core controllers and network loaders
|
@@ -28596,7 +28470,7 @@
|
|
28596
28470
|
try {
|
28597
28471
|
return this.emit(event, event, eventObject);
|
28598
28472
|
} catch (error) {
|
28599
|
-
|
28473
|
+
logger.error('An internal error happened while handling event ' + event + '. Error message: "' + error.message + '". Here is a stacktrace:', error);
|
28600
28474
|
// Prevent recursion in error event handlers that throw #5497
|
28601
28475
|
if (!this.triggeringException) {
|
28602
28476
|
this.triggeringException = true;
|
@@ -28622,7 +28496,7 @@
|
|
28622
28496
|
* Dispose of the instance
|
28623
28497
|
*/;
|
28624
28498
|
_proto.destroy = function destroy() {
|
28625
|
-
|
28499
|
+
logger.log('destroy');
|
28626
28500
|
this.trigger(Events.DESTROYING, undefined);
|
28627
28501
|
this.detachMedia();
|
28628
28502
|
this.removeAllListeners();
|
@@ -28647,7 +28521,7 @@
|
|
28647
28521
|
* Attaches Hls.js to a media element
|
28648
28522
|
*/;
|
28649
28523
|
_proto.attachMedia = function attachMedia(media) {
|
28650
|
-
|
28524
|
+
logger.log('attachMedia');
|
28651
28525
|
this._media = media;
|
28652
28526
|
this.trigger(Events.MEDIA_ATTACHING, {
|
28653
28527
|
media: media
|
@@ -28658,7 +28532,7 @@
|
|
28658
28532
|
* Detach Hls.js from the media
|
28659
28533
|
*/;
|
28660
28534
|
_proto.detachMedia = function detachMedia() {
|
28661
|
-
|
28535
|
+
logger.log('detachMedia');
|
28662
28536
|
this.trigger(Events.MEDIA_DETACHING, undefined);
|
28663
28537
|
this._media = null;
|
28664
28538
|
}
|
@@ -28675,7 +28549,7 @@
|
|
28675
28549
|
});
|
28676
28550
|
this._autoLevelCapping = -1;
|
28677
28551
|
this._maxHdcpLevel = null;
|
28678
|
-
|
28552
|
+
logger.log("loadSource:" + loadingSource);
|
28679
28553
|
if (media && loadedSource && (loadedSource !== loadingSource || this.bufferController.hasSourceTypes())) {
|
28680
28554
|
this.detachMedia();
|
28681
28555
|
this.attachMedia(media);
|
@@ -28697,7 +28571,7 @@
|
|
28697
28571
|
if (startPosition === void 0) {
|
28698
28572
|
startPosition = -1;
|
28699
28573
|
}
|
28700
|
-
|
28574
|
+
logger.log("startLoad(" + startPosition + ")");
|
28701
28575
|
this.started = true;
|
28702
28576
|
this.networkControllers.forEach(function (controller) {
|
28703
28577
|
controller.startLoad(startPosition);
|
@@ -28708,7 +28582,7 @@
|
|
28708
28582
|
* Stop loading of any stream data.
|
28709
28583
|
*/;
|
28710
28584
|
_proto.stopLoad = function stopLoad() {
|
28711
|
-
|
28585
|
+
logger.log('stopLoad');
|
28712
28586
|
this.started = false;
|
28713
28587
|
this.networkControllers.forEach(function (controller) {
|
28714
28588
|
controller.stopLoad();
|
@@ -28744,7 +28618,7 @@
|
|
28744
28618
|
* Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1)
|
28745
28619
|
*/;
|
28746
28620
|
_proto.swapAudioCodec = function swapAudioCodec() {
|
28747
|
-
|
28621
|
+
logger.log('swapAudioCodec');
|
28748
28622
|
this.streamController.swapAudioCodec();
|
28749
28623
|
}
|
28750
28624
|
|
@@ -28755,7 +28629,7 @@
|
|
28755
28629
|
* Automatic recovery of media-errors by this process is configurable.
|
28756
28630
|
*/;
|
28757
28631
|
_proto.recoverMediaError = function recoverMediaError() {
|
28758
|
-
|
28632
|
+
logger.log('recoverMediaError');
|
28759
28633
|
var media = this._media;
|
28760
28634
|
this.detachMedia();
|
28761
28635
|
if (media) {
|
@@ -28810,7 +28684,7 @@
|
|
28810
28684
|
* Set quality level index immediately. This will flush the current buffer to replace the quality asap. That means playback will interrupt at least shortly to re-buffer and re-sync eventually. Set to -1 for automatic level selection.
|
28811
28685
|
*/,
|
28812
28686
|
set: function set(newLevel) {
|
28813
|
-
|
28687
|
+
logger.log("set currentLevel:" + newLevel);
|
28814
28688
|
this.levelController.manualLevel = newLevel;
|
28815
28689
|
this.streamController.immediateLevelSwitch();
|
28816
28690
|
}
|
@@ -28831,7 +28705,7 @@
|
|
28831
28705
|
* @param newLevel - Pass -1 for automatic level selection
|
28832
28706
|
*/,
|
28833
28707
|
set: function set(newLevel) {
|
28834
|
-
|
28708
|
+
logger.log("set nextLevel:" + newLevel);
|
28835
28709
|
this.levelController.manualLevel = newLevel;
|
28836
28710
|
this.streamController.nextLevelSwitch();
|
28837
28711
|
}
|
@@ -28852,7 +28726,7 @@
|
|
28852
28726
|
* @param newLevel - Pass -1 for automatic level selection
|
28853
28727
|
*/,
|
28854
28728
|
set: function set(newLevel) {
|
28855
|
-
|
28729
|
+
logger.log("set loadLevel:" + newLevel);
|
28856
28730
|
this.levelController.manualLevel = newLevel;
|
28857
28731
|
}
|
28858
28732
|
|
@@ -28887,7 +28761,7 @@
|
|
28887
28761
|
* Sets "first-level", see getter.
|
28888
28762
|
*/,
|
28889
28763
|
set: function set(newLevel) {
|
28890
|
-
|
28764
|
+
logger.log("set firstLevel:" + newLevel);
|
28891
28765
|
this.levelController.firstLevel = newLevel;
|
28892
28766
|
}
|
28893
28767
|
|
@@ -28914,7 +28788,7 @@
|
|
28914
28788
|
* (determined from download of first segment)
|
28915
28789
|
*/,
|
28916
28790
|
set: function set(newLevel) {
|
28917
|
-
|
28791
|
+
logger.log("set startLevel:" + newLevel);
|
28918
28792
|
// if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
|
28919
28793
|
if (newLevel !== -1) {
|
28920
28794
|
newLevel = Math.max(newLevel, this.minAutoLevel);
|
@@ -28967,7 +28841,7 @@
|
|
28967
28841
|
*/
|
28968
28842
|
function set(newLevel) {
|
28969
28843
|
if (this._autoLevelCapping !== newLevel) {
|
28970
|
-
|
28844
|
+
logger.log("set autoLevelCapping:" + newLevel);
|
28971
28845
|
this._autoLevelCapping = newLevel;
|
28972
28846
|
this.levelController.checkMaxAutoUpdated();
|
28973
28847
|
}
|
@@ -29292,7 +29166,7 @@
|
|
29292
29166
|
* Get the video-dev/hls.js package version.
|
29293
29167
|
*/
|
29294
29168
|
function get() {
|
29295
|
-
return "1.5.
|
29169
|
+
return "1.5.3";
|
29296
29170
|
}
|
29297
29171
|
}, {
|
29298
29172
|
key: "Events",
|