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.light.js
CHANGED
@@ -363,7 +363,6 @@
|
|
363
363
|
Events["MEDIA_ATTACHED"] = "hlsMediaAttached";
|
364
364
|
Events["MEDIA_DETACHING"] = "hlsMediaDetaching";
|
365
365
|
Events["MEDIA_DETACHED"] = "hlsMediaDetached";
|
366
|
-
Events["MEDIA_ENDED"] = "hlsMediaEnded";
|
367
366
|
Events["BUFFER_RESET"] = "hlsBufferReset";
|
368
367
|
Events["BUFFER_CODECS"] = "hlsBufferCodecs";
|
369
368
|
Events["BUFFER_CREATED"] = "hlsBufferCreated";
|
@@ -477,21 +476,6 @@
|
|
477
476
|
return ErrorDetails;
|
478
477
|
}({});
|
479
478
|
|
480
|
-
var Logger = function Logger(label, logger) {
|
481
|
-
this.trace = void 0;
|
482
|
-
this.debug = void 0;
|
483
|
-
this.log = void 0;
|
484
|
-
this.warn = void 0;
|
485
|
-
this.info = void 0;
|
486
|
-
this.error = void 0;
|
487
|
-
var lb = "[" + label + "]:";
|
488
|
-
this.trace = noop;
|
489
|
-
this.debug = logger.debug.bind(null, lb);
|
490
|
-
this.log = logger.log.bind(null, lb);
|
491
|
-
this.warn = logger.warn.bind(null, lb);
|
492
|
-
this.info = logger.info.bind(null, lb);
|
493
|
-
this.error = logger.error.bind(null, lb);
|
494
|
-
};
|
495
479
|
var noop = function noop() {};
|
496
480
|
var fakeLogger = {
|
497
481
|
trace: noop,
|
@@ -501,9 +485,7 @@
|
|
501
485
|
info: noop,
|
502
486
|
error: noop
|
503
487
|
};
|
504
|
-
|
505
|
-
return _extends({}, fakeLogger);
|
506
|
-
}
|
488
|
+
var exportedLogger = fakeLogger;
|
507
489
|
|
508
490
|
// let lastCallTime;
|
509
491
|
// function formatMsgWithTimeInfo(type, msg) {
|
@@ -514,36 +496,38 @@
|
|
514
496
|
// return msg;
|
515
497
|
// }
|
516
498
|
|
517
|
-
function consolePrintFn(type
|
499
|
+
function consolePrintFn(type) {
|
518
500
|
var func = self.console[type];
|
519
|
-
|
501
|
+
if (func) {
|
502
|
+
return func.bind(self.console, "[" + type + "] >");
|
503
|
+
}
|
504
|
+
return noop;
|
520
505
|
}
|
521
|
-
function
|
522
|
-
|
506
|
+
function exportLoggerFunctions(debugConfig) {
|
507
|
+
for (var _len = arguments.length, functions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
508
|
+
functions[_key - 1] = arguments[_key];
|
509
|
+
}
|
510
|
+
functions.forEach(function (type) {
|
511
|
+
exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);
|
512
|
+
});
|
523
513
|
}
|
524
|
-
|
525
|
-
function enableLogs(debugConfig, context, id) {
|
514
|
+
function enableLogs(debugConfig, id) {
|
526
515
|
// check that console is available
|
527
|
-
var newLogger = createLogger();
|
528
516
|
if (typeof console === 'object' && debugConfig === true || typeof debugConfig === 'object') {
|
529
|
-
|
517
|
+
exportLoggerFunctions(debugConfig,
|
530
518
|
// Remove out from list here to hard-disable a log-level
|
531
519
|
// 'trace',
|
532
|
-
'debug', 'log', 'info', 'warn', 'error'
|
533
|
-
keys.forEach(function (key) {
|
534
|
-
newLogger[key] = getLoggerFn(key, debugConfig, id);
|
535
|
-
});
|
520
|
+
'debug', 'log', 'info', 'warn', 'error');
|
536
521
|
// Some browsers don't allow to use bind on console object anyway
|
537
522
|
// fallback to default if needed
|
538
523
|
try {
|
539
|
-
|
524
|
+
exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.5.3");
|
540
525
|
} catch (e) {
|
541
|
-
|
542
|
-
return createLogger();
|
526
|
+
exportedLogger = fakeLogger;
|
543
527
|
}
|
528
|
+
} else {
|
529
|
+
exportedLogger = fakeLogger;
|
544
530
|
}
|
545
|
-
exportedLogger = newLogger;
|
546
|
-
return newLogger;
|
547
531
|
}
|
548
532
|
var logger = exportedLogger;
|
549
533
|
|
@@ -1189,26 +1173,6 @@
|
|
1189
1173
|
return LevelDetails;
|
1190
1174
|
}();
|
1191
1175
|
|
1192
|
-
var DecrypterAesMode = {
|
1193
|
-
cbc: 0,
|
1194
|
-
ctr: 1
|
1195
|
-
};
|
1196
|
-
|
1197
|
-
function isFullSegmentEncryption(method) {
|
1198
|
-
return method === 'AES-128' || method === 'AES-256' || method === 'AES-256-CTR';
|
1199
|
-
}
|
1200
|
-
function getAesModeFromFullSegmentMethod(method) {
|
1201
|
-
switch (method) {
|
1202
|
-
case 'AES-128':
|
1203
|
-
case 'AES-256':
|
1204
|
-
return DecrypterAesMode.cbc;
|
1205
|
-
case 'AES-256-CTR':
|
1206
|
-
return DecrypterAesMode.ctr;
|
1207
|
-
default:
|
1208
|
-
throw new Error("invalid full segment method " + method);
|
1209
|
-
}
|
1210
|
-
}
|
1211
|
-
|
1212
1176
|
// This file is inserted as a shim for modules which we do not want to include into the distro.
|
1213
1177
|
// This replacement is done in the "alias" plugin of the rollup config.
|
1214
1178
|
var empty = undefined;
|
@@ -2650,13 +2614,13 @@
|
|
2650
2614
|
this.keyFormatVersions = formatversions;
|
2651
2615
|
this.iv = iv;
|
2652
2616
|
this.encrypted = method ? method !== 'NONE' : false;
|
2653
|
-
this.isCommonEncryption = this.encrypted &&
|
2617
|
+
this.isCommonEncryption = this.encrypted && method !== 'AES-128';
|
2654
2618
|
}
|
2655
2619
|
var _proto = LevelKey.prototype;
|
2656
2620
|
_proto.isSupported = function isSupported() {
|
2657
2621
|
// If it's Segment encryption or No encryption, just select that key system
|
2658
2622
|
if (this.method) {
|
2659
|
-
if (
|
2623
|
+
if (this.method === 'AES-128' || this.method === 'NONE') {
|
2660
2624
|
return true;
|
2661
2625
|
}
|
2662
2626
|
if (this.keyFormat === 'identity') {
|
@@ -2670,13 +2634,14 @@
|
|
2670
2634
|
if (!this.encrypted || !this.uri) {
|
2671
2635
|
return null;
|
2672
2636
|
}
|
2673
|
-
if (
|
2637
|
+
if (this.method === 'AES-128' && this.uri && !this.iv) {
|
2674
2638
|
if (typeof sn !== 'number') {
|
2675
2639
|
// We are fetching decryption data for a initialization segment
|
2676
|
-
// If the segment was encrypted with AES-128
|
2640
|
+
// If the segment was encrypted with AES-128
|
2677
2641
|
// It must have an IV defined. We cannot substitute the Segment Number in.
|
2678
|
-
|
2679
|
-
|
2642
|
+
if (this.method === 'AES-128' && !this.iv) {
|
2643
|
+
logger.warn("missing IV for initialization segment with method=\"" + this.method + "\" - compliance issue");
|
2644
|
+
}
|
2680
2645
|
// Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
|
2681
2646
|
sn = 0;
|
2682
2647
|
}
|
@@ -2838,28 +2803,23 @@
|
|
2838
2803
|
if (CODEC_COMPATIBLE_NAMES[lowerCaseCodec]) {
|
2839
2804
|
return CODEC_COMPATIBLE_NAMES[lowerCaseCodec];
|
2840
2805
|
}
|
2806
|
+
|
2807
|
+
// Idealy fLaC and Opus would be first (spec-compliant) but
|
2808
|
+
// some browsers will report that fLaC is supported then fail.
|
2809
|
+
// see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
|
2841
2810
|
var codecsToCheck = {
|
2842
|
-
// Idealy fLaC and Opus would be first (spec-compliant) but
|
2843
|
-
// some browsers will report that fLaC is supported then fail.
|
2844
|
-
// see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
|
2845
2811
|
flac: ['flac', 'fLaC', 'FLAC'],
|
2846
|
-
opus: ['opus', 'Opus']
|
2847
|
-
// Replace audio codec info if browser does not support mp4a.40.34,
|
2848
|
-
// and demuxer can fallback to 'audio/mpeg' or 'audio/mp4;codecs="mp3"'
|
2849
|
-
'mp4a.40.34': ['mp3']
|
2812
|
+
opus: ['opus', 'Opus']
|
2850
2813
|
}[lowerCaseCodec];
|
2851
2814
|
for (var i = 0; i < codecsToCheck.length; i++) {
|
2852
|
-
var _getMediaSource;
|
2853
2815
|
if (isCodecMediaSourceSupported(codecsToCheck[i], 'audio', preferManagedMediaSource)) {
|
2854
2816
|
CODEC_COMPATIBLE_NAMES[lowerCaseCodec] = codecsToCheck[i];
|
2855
2817
|
return codecsToCheck[i];
|
2856
|
-
} else if (codecsToCheck[i] === 'mp3' && (_getMediaSource = getMediaSource(preferManagedMediaSource)) != null && _getMediaSource.isTypeSupported('audio/mpeg')) {
|
2857
|
-
return '';
|
2858
2818
|
}
|
2859
2819
|
}
|
2860
2820
|
return lowerCaseCodec;
|
2861
2821
|
}
|
2862
|
-
var AUDIO_CODEC_REGEXP = /flac|opus
|
2822
|
+
var AUDIO_CODEC_REGEXP = /flac|opus/i;
|
2863
2823
|
function getCodecCompatibleName(codec, preferManagedMediaSource) {
|
2864
2824
|
if (preferManagedMediaSource === void 0) {
|
2865
2825
|
preferManagedMediaSource = true;
|
@@ -2887,18 +2847,6 @@
|
|
2887
2847
|
}
|
2888
2848
|
return codec;
|
2889
2849
|
}
|
2890
|
-
function getM2TSSupportedAudioTypes(preferManagedMediaSource) {
|
2891
|
-
var MediaSource = getMediaSource(preferManagedMediaSource) || {
|
2892
|
-
isTypeSupported: function isTypeSupported() {
|
2893
|
-
return false;
|
2894
|
-
}
|
2895
|
-
};
|
2896
|
-
return {
|
2897
|
-
mpeg: MediaSource.isTypeSupported('audio/mpeg'),
|
2898
|
-
mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'),
|
2899
|
-
ac3: false
|
2900
|
-
};
|
2901
|
-
}
|
2902
2850
|
|
2903
2851
|
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;
|
2904
2852
|
var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g;
|
@@ -4473,43 +4421,8 @@
|
|
4473
4421
|
this.currentTime = 0;
|
4474
4422
|
this.stallCount = 0;
|
4475
4423
|
this._latency = null;
|
4476
|
-
this.
|
4477
|
-
|
4478
|
-
levelDetails = _this.levelDetails;
|
4479
|
-
if (!media || !levelDetails) {
|
4480
|
-
return;
|
4481
|
-
}
|
4482
|
-
_this.currentTime = media.currentTime;
|
4483
|
-
var latency = _this.computeLatency();
|
4484
|
-
if (latency === null) {
|
4485
|
-
return;
|
4486
|
-
}
|
4487
|
-
_this._latency = latency;
|
4488
|
-
|
4489
|
-
// Adapt playbackRate to meet target latency in low-latency mode
|
4490
|
-
var _this$config = _this.config,
|
4491
|
-
lowLatencyMode = _this$config.lowLatencyMode,
|
4492
|
-
maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
|
4493
|
-
if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1 || !levelDetails.live) {
|
4494
|
-
return;
|
4495
|
-
}
|
4496
|
-
var targetLatency = _this.targetLatency;
|
4497
|
-
if (targetLatency === null) {
|
4498
|
-
return;
|
4499
|
-
}
|
4500
|
-
var distanceFromTarget = latency - targetLatency;
|
4501
|
-
// Only adjust playbackRate when within one target duration of targetLatency
|
4502
|
-
// and more than one second from under-buffering.
|
4503
|
-
// Playback further than one target duration from target can be considered DVR playback.
|
4504
|
-
var liveMinLatencyDuration = Math.min(_this.maxLatency, targetLatency + levelDetails.targetduration);
|
4505
|
-
var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
|
4506
|
-
if (inLiveRange && distanceFromTarget > 0.05 && _this.forwardBufferLength > 1) {
|
4507
|
-
var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
|
4508
|
-
var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - _this.edgeStalled)) * 20) / 20;
|
4509
|
-
media.playbackRate = Math.min(max, Math.max(1, rate));
|
4510
|
-
} else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
|
4511
|
-
media.playbackRate = 1;
|
4512
|
-
}
|
4424
|
+
this.timeupdateHandler = function () {
|
4425
|
+
return _this.timeupdate();
|
4513
4426
|
};
|
4514
4427
|
this.hls = hls;
|
4515
4428
|
this.config = hls.config;
|
@@ -4521,7 +4434,7 @@
|
|
4521
4434
|
this.onMediaDetaching();
|
4522
4435
|
this.levelDetails = null;
|
4523
4436
|
// @ts-ignore
|
4524
|
-
this.hls = null;
|
4437
|
+
this.hls = this.timeupdateHandler = null;
|
4525
4438
|
};
|
4526
4439
|
_proto.registerListeners = function registerListeners() {
|
4527
4440
|
this.hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
@@ -4539,11 +4452,11 @@
|
|
4539
4452
|
};
|
4540
4453
|
_proto.onMediaAttached = function onMediaAttached(event, data) {
|
4541
4454
|
this.media = data.media;
|
4542
|
-
this.media.addEventListener('timeupdate', this.
|
4455
|
+
this.media.addEventListener('timeupdate', this.timeupdateHandler);
|
4543
4456
|
};
|
4544
4457
|
_proto.onMediaDetaching = function onMediaDetaching() {
|
4545
4458
|
if (this.media) {
|
4546
|
-
this.media.removeEventListener('timeupdate', this.
|
4459
|
+
this.media.removeEventListener('timeupdate', this.timeupdateHandler);
|
4547
4460
|
this.media = null;
|
4548
4461
|
}
|
4549
4462
|
};
|
@@ -4556,10 +4469,10 @@
|
|
4556
4469
|
var details = _ref.details;
|
4557
4470
|
this.levelDetails = details;
|
4558
4471
|
if (details.advanced) {
|
4559
|
-
this.
|
4472
|
+
this.timeupdate();
|
4560
4473
|
}
|
4561
4474
|
if (!details.live && this.media) {
|
4562
|
-
this.media.removeEventListener('timeupdate', this.
|
4475
|
+
this.media.removeEventListener('timeupdate', this.timeupdateHandler);
|
4563
4476
|
}
|
4564
4477
|
};
|
4565
4478
|
_proto.onError = function onError(event, data) {
|
@@ -4569,7 +4482,45 @@
|
|
4569
4482
|
}
|
4570
4483
|
this.stallCount++;
|
4571
4484
|
if ((_this$levelDetails = this.levelDetails) != null && _this$levelDetails.live) {
|
4572
|
-
|
4485
|
+
logger.warn('[playback-rate-controller]: Stall detected, adjusting target latency');
|
4486
|
+
}
|
4487
|
+
};
|
4488
|
+
_proto.timeupdate = function timeupdate() {
|
4489
|
+
var media = this.media,
|
4490
|
+
levelDetails = this.levelDetails;
|
4491
|
+
if (!media || !levelDetails) {
|
4492
|
+
return;
|
4493
|
+
}
|
4494
|
+
this.currentTime = media.currentTime;
|
4495
|
+
var latency = this.computeLatency();
|
4496
|
+
if (latency === null) {
|
4497
|
+
return;
|
4498
|
+
}
|
4499
|
+
this._latency = latency;
|
4500
|
+
|
4501
|
+
// Adapt playbackRate to meet target latency in low-latency mode
|
4502
|
+
var _this$config = this.config,
|
4503
|
+
lowLatencyMode = _this$config.lowLatencyMode,
|
4504
|
+
maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
|
4505
|
+
if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1 || !levelDetails.live) {
|
4506
|
+
return;
|
4507
|
+
}
|
4508
|
+
var targetLatency = this.targetLatency;
|
4509
|
+
if (targetLatency === null) {
|
4510
|
+
return;
|
4511
|
+
}
|
4512
|
+
var distanceFromTarget = latency - targetLatency;
|
4513
|
+
// Only adjust playbackRate when within one target duration of targetLatency
|
4514
|
+
// and more than one second from under-buffering.
|
4515
|
+
// Playback further than one target duration from target can be considered DVR playback.
|
4516
|
+
var liveMinLatencyDuration = Math.min(this.maxLatency, targetLatency + levelDetails.targetduration);
|
4517
|
+
var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
|
4518
|
+
if (inLiveRange && distanceFromTarget > 0.05 && this.forwardBufferLength > 1) {
|
4519
|
+
var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
|
4520
|
+
var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - this.edgeStalled)) * 20) / 20;
|
4521
|
+
media.playbackRate = Math.min(max, Math.max(1, rate));
|
4522
|
+
} else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
|
4523
|
+
media.playbackRate = 1;
|
4573
4524
|
}
|
4574
4525
|
};
|
4575
4526
|
_proto.estimateLiveEdge = function estimateLiveEdge() {
|
@@ -5477,17 +5428,19 @@
|
|
5477
5428
|
MoveAllAlternatesMatchingHDCP: 2,
|
5478
5429
|
SwitchToSDR: 4
|
5479
5430
|
}; // Reserved for future use
|
5480
|
-
var ErrorController = /*#__PURE__*/function (
|
5481
|
-
_inheritsLoose(ErrorController, _Logger);
|
5431
|
+
var ErrorController = /*#__PURE__*/function () {
|
5482
5432
|
function ErrorController(hls) {
|
5483
|
-
|
5484
|
-
|
5485
|
-
|
5486
|
-
|
5487
|
-
|
5488
|
-
|
5489
|
-
|
5490
|
-
|
5433
|
+
this.hls = void 0;
|
5434
|
+
this.playlistError = 0;
|
5435
|
+
this.penalizedRenditions = {};
|
5436
|
+
this.log = void 0;
|
5437
|
+
this.warn = void 0;
|
5438
|
+
this.error = void 0;
|
5439
|
+
this.hls = hls;
|
5440
|
+
this.log = logger.log.bind(logger, "[info]:");
|
5441
|
+
this.warn = logger.warn.bind(logger, "[warning]:");
|
5442
|
+
this.error = logger.error.bind(logger, "[error]:");
|
5443
|
+
this.registerListeners();
|
5491
5444
|
}
|
5492
5445
|
var _proto = ErrorController.prototype;
|
5493
5446
|
_proto.registerListeners = function registerListeners() {
|
@@ -5843,19 +5796,19 @@
|
|
5843
5796
|
}
|
5844
5797
|
};
|
5845
5798
|
return ErrorController;
|
5846
|
-
}(
|
5799
|
+
}();
|
5847
5800
|
|
5848
|
-
var BasePlaylistController = /*#__PURE__*/function (
|
5849
|
-
_inheritsLoose(BasePlaylistController, _Logger);
|
5801
|
+
var BasePlaylistController = /*#__PURE__*/function () {
|
5850
5802
|
function BasePlaylistController(hls, logPrefix) {
|
5851
|
-
|
5852
|
-
|
5853
|
-
|
5854
|
-
|
5855
|
-
|
5856
|
-
|
5857
|
-
|
5858
|
-
|
5803
|
+
this.hls = void 0;
|
5804
|
+
this.timer = -1;
|
5805
|
+
this.requestScheduled = -1;
|
5806
|
+
this.canLoad = false;
|
5807
|
+
this.log = void 0;
|
5808
|
+
this.warn = void 0;
|
5809
|
+
this.log = logger.log.bind(logger, logPrefix + ":");
|
5810
|
+
this.warn = logger.warn.bind(logger, logPrefix + ":");
|
5811
|
+
this.hls = hls;
|
5859
5812
|
}
|
5860
5813
|
var _proto = BasePlaylistController.prototype;
|
5861
5814
|
_proto.destroy = function destroy() {
|
@@ -5888,7 +5841,7 @@
|
|
5888
5841
|
try {
|
5889
5842
|
uri = new self.URL(attr.URI, previous.url).href;
|
5890
5843
|
} catch (error) {
|
5891
|
-
|
5844
|
+
logger.warn("Could not construct new URL for Rendition Report: " + error);
|
5892
5845
|
uri = attr.URI || '';
|
5893
5846
|
}
|
5894
5847
|
// Use exact match. Otherwise, the last partial match, if any, will be used
|
@@ -5927,7 +5880,7 @@
|
|
5927
5880
|
return this.timer === -1 && this.requestScheduled === -1 && this.shouldLoadPlaylist(playlist);
|
5928
5881
|
};
|
5929
5882
|
_proto.playlistLoaded = function playlistLoaded(index, data, previousDetails) {
|
5930
|
-
var
|
5883
|
+
var _this = this;
|
5931
5884
|
var details = data.details,
|
5932
5885
|
stats = data.stats;
|
5933
5886
|
|
@@ -6032,7 +5985,7 @@
|
|
6032
5985
|
// );
|
6033
5986
|
|
6034
5987
|
this.timer = self.setTimeout(function () {
|
6035
|
-
return
|
5988
|
+
return _this.loadPlaylist(deliveryDirectives);
|
6036
5989
|
}, estimatedTimeUntilUpdate);
|
6037
5990
|
} else {
|
6038
5991
|
this.clearTimer();
|
@@ -6048,7 +6001,7 @@
|
|
6048
6001
|
return new HlsUrlParameters(msn, part, skip);
|
6049
6002
|
};
|
6050
6003
|
_proto.checkRetry = function checkRetry(errorEvent) {
|
6051
|
-
var
|
6004
|
+
var _this2 = this;
|
6052
6005
|
var errorDetails = errorEvent.details;
|
6053
6006
|
var isTimeout = isTimeoutError(errorEvent);
|
6054
6007
|
var errorAction = errorEvent.errorAction;
|
@@ -6072,7 +6025,7 @@
|
|
6072
6025
|
var delay = getRetryDelay(retryConfig, retryCount);
|
6073
6026
|
// Schedule level/track reload
|
6074
6027
|
this.timer = self.setTimeout(function () {
|
6075
|
-
return
|
6028
|
+
return _this2.loadPlaylist();
|
6076
6029
|
}, delay);
|
6077
6030
|
this.warn("Retrying playlist loading " + (retryCount + 1) + "/" + retryConfig.maxNumRetry + " after \"" + errorDetails + "\" in " + delay + "ms");
|
6078
6031
|
}
|
@@ -6083,7 +6036,7 @@
|
|
6083
6036
|
return retry;
|
6084
6037
|
};
|
6085
6038
|
return BasePlaylistController;
|
6086
|
-
}(
|
6039
|
+
}();
|
6087
6040
|
|
6088
6041
|
/*
|
6089
6042
|
* compute an Exponential Weighted moving average
|
@@ -6457,33 +6410,30 @@
|
|
6457
6410
|
}, {});
|
6458
6411
|
}
|
6459
6412
|
|
6460
|
-
var AbrController = /*#__PURE__*/function (
|
6461
|
-
_inheritsLoose(AbrController, _Logger);
|
6413
|
+
var AbrController = /*#__PURE__*/function () {
|
6462
6414
|
function AbrController(_hls) {
|
6463
|
-
var _this;
|
6464
|
-
|
6465
|
-
|
6466
|
-
|
6467
|
-
|
6468
|
-
|
6469
|
-
|
6470
|
-
|
6471
|
-
|
6472
|
-
|
6473
|
-
|
6474
|
-
|
6475
|
-
|
6476
|
-
|
6477
|
-
_this.bwEstimator = void 0;
|
6415
|
+
var _this = this;
|
6416
|
+
this.hls = void 0;
|
6417
|
+
this.lastLevelLoadSec = 0;
|
6418
|
+
this.lastLoadedFragLevel = -1;
|
6419
|
+
this.firstSelection = -1;
|
6420
|
+
this._nextAutoLevel = -1;
|
6421
|
+
this.nextAutoLevelKey = '';
|
6422
|
+
this.audioTracksByGroup = null;
|
6423
|
+
this.codecTiers = null;
|
6424
|
+
this.timer = -1;
|
6425
|
+
this.fragCurrent = null;
|
6426
|
+
this.partCurrent = null;
|
6427
|
+
this.bitrateTestDelay = 0;
|
6428
|
+
this.bwEstimator = void 0;
|
6478
6429
|
/*
|
6479
6430
|
This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
|
6480
6431
|
quickly enough to prevent underbuffering
|
6481
6432
|
*/
|
6482
|
-
|
6483
|
-
var
|
6484
|
-
|
6485
|
-
|
6486
|
-
hls = _assertThisInitialize.hls;
|
6433
|
+
this._abandonRulesCheck = function () {
|
6434
|
+
var frag = _this.fragCurrent,
|
6435
|
+
part = _this.partCurrent,
|
6436
|
+
hls = _this.hls;
|
6487
6437
|
var autoLevelEnabled = hls.autoLevelEnabled,
|
6488
6438
|
media = hls.media;
|
6489
6439
|
if (!frag || !media) {
|
@@ -6572,22 +6522,21 @@
|
|
6572
6522
|
_this.resetEstimator(nextLoadLevelBitrate);
|
6573
6523
|
}
|
6574
6524
|
_this.clearTimer();
|
6575
|
-
|
6525
|
+
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");
|
6576
6526
|
hls.trigger(Events.FRAG_LOAD_EMERGENCY_ABORTED, {
|
6577
6527
|
frag: frag,
|
6578
6528
|
part: part,
|
6579
6529
|
stats: stats
|
6580
6530
|
});
|
6581
6531
|
};
|
6582
|
-
|
6583
|
-
|
6584
|
-
|
6585
|
-
return _this;
|
6532
|
+
this.hls = _hls;
|
6533
|
+
this.bwEstimator = this.initEstimator();
|
6534
|
+
this.registerListeners();
|
6586
6535
|
}
|
6587
6536
|
var _proto = AbrController.prototype;
|
6588
6537
|
_proto.resetEstimator = function resetEstimator(abrEwmaDefaultEstimate) {
|
6589
6538
|
if (abrEwmaDefaultEstimate) {
|
6590
|
-
|
6539
|
+
logger.log("setting initial bwe to " + abrEwmaDefaultEstimate);
|
6591
6540
|
this.hls.config.abrEwmaDefaultEstimate = abrEwmaDefaultEstimate;
|
6592
6541
|
}
|
6593
6542
|
this.firstSelection = -1;
|
@@ -6839,13 +6788,13 @@
|
|
6839
6788
|
// cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
|
6840
6789
|
var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay;
|
6841
6790
|
maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
|
6842
|
-
|
6791
|
+
logger.info("[abr] bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms");
|
6843
6792
|
// don't use conservative factor on bitrate test
|
6844
6793
|
bwFactor = bwUpFactor = 1;
|
6845
6794
|
}
|
6846
6795
|
}
|
6847
6796
|
var bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor);
|
6848
|
-
|
6797
|
+
logger.info("[abr] " + (bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty') + ", optimal quality level " + bestLevel);
|
6849
6798
|
if (bestLevel > -1) {
|
6850
6799
|
return bestLevel;
|
6851
6800
|
}
|
@@ -6901,7 +6850,7 @@
|
|
6901
6850
|
currentVideoRange = preferHDR ? videoRanges[videoRanges.length - 1] : videoRanges[0];
|
6902
6851
|
currentFrameRate = minFramerate;
|
6903
6852
|
currentBw = Math.max(currentBw, minBitrate);
|
6904
|
-
|
6853
|
+
logger.log("[abr] picked start tier " + JSON.stringify(startTier));
|
6905
6854
|
} else {
|
6906
6855
|
currentCodecSet = level == null ? void 0 : level.codecSet;
|
6907
6856
|
currentVideoRange = level == null ? void 0 : level.videoRange;
|
@@ -6910,7 +6859,7 @@
|
|
6910
6859
|
var ttfbEstimateSec = this.bwEstimator.getEstimateTTFB() / 1000;
|
6911
6860
|
var levelsSkipped = [];
|
6912
6861
|
var _loop = function _loop() {
|
6913
|
-
var _levelInfo$supportedR
|
6862
|
+
var _levelInfo$supportedR;
|
6914
6863
|
var levelInfo = levels[i];
|
6915
6864
|
var upSwitch = i > selectionBaseLevel;
|
6916
6865
|
if (!levelInfo) {
|
@@ -6919,7 +6868,7 @@
|
|
6919
6868
|
|
6920
6869
|
// skip candidates which change codec-family or video-range,
|
6921
6870
|
// and which decrease or increase frame-rate for up and down-switch respectfully
|
6922
|
-
if (currentCodecSet && levelInfo.codecSet !== currentCodecSet || currentVideoRange && levelInfo.videoRange !== currentVideoRange || upSwitch && currentFrameRate > levelInfo.frameRate || !upSwitch && currentFrameRate > 0 && currentFrameRate < levelInfo.frameRate ||
|
6871
|
+
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)) {
|
6923
6872
|
levelsSkipped.push(i);
|
6924
6873
|
return 0; // continue
|
6925
6874
|
}
|
@@ -6954,9 +6903,9 @@
|
|
6954
6903
|
var forcedAutoLevel = _this2.forcedAutoLevel;
|
6955
6904
|
if (i !== loadLevel && (forcedAutoLevel === -1 || forcedAutoLevel !== loadLevel)) {
|
6956
6905
|
if (levelsSkipped.length) {
|
6957
|
-
|
6906
|
+
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);
|
6958
6907
|
}
|
6959
|
-
|
6908
|
+
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);
|
6960
6909
|
}
|
6961
6910
|
if (firstSelection) {
|
6962
6911
|
_this2.firstSelection = i;
|
@@ -6990,7 +6939,7 @@
|
|
6990
6939
|
}
|
6991
6940
|
var firstLevel = this.hls.firstLevel;
|
6992
6941
|
var clamped = Math.min(Math.max(firstLevel, minAutoLevel), maxAutoLevel);
|
6993
|
-
|
6942
|
+
logger.warn("[abr] Could not find best starting auto level. Defaulting to first in playlist " + firstLevel + " clamped to " + clamped);
|
6994
6943
|
return clamped;
|
6995
6944
|
}
|
6996
6945
|
}, {
|
@@ -7040,7 +6989,7 @@
|
|
7040
6989
|
}
|
7041
6990
|
}]);
|
7042
6991
|
return AbrController;
|
7043
|
-
}(
|
6992
|
+
}();
|
7044
6993
|
|
7045
6994
|
/**
|
7046
6995
|
* Provides methods dealing with buffer length retrieval for example.
|
@@ -7261,57 +7210,57 @@
|
|
7261
7210
|
}();
|
7262
7211
|
|
7263
7212
|
var VIDEO_CODEC_PROFILE_REPLACE = /(avc[1234]|hvc1|hev1|dvh[1e]|vp09|av01)(?:\.[^.,]+)+/;
|
7264
|
-
var BufferController = /*#__PURE__*/function (
|
7265
|
-
_inheritsLoose(BufferController, _Logger);
|
7213
|
+
var BufferController = /*#__PURE__*/function () {
|
7266
7214
|
function BufferController(hls) {
|
7267
|
-
var _this;
|
7268
|
-
_this = _Logger.call(this, 'buffer-controller', hls.logger) || this;
|
7215
|
+
var _this = this;
|
7269
7216
|
// The level details used to determine duration, target-duration and live
|
7270
|
-
|
7217
|
+
this.details = null;
|
7271
7218
|
// cache the self generated object url to detect hijack of video tag
|
7272
|
-
|
7219
|
+
this._objectUrl = null;
|
7273
7220
|
// A queue of buffer operations which require the SourceBuffer to not be updating upon execution
|
7274
|
-
|
7221
|
+
this.operationQueue = void 0;
|
7275
7222
|
// References to event listeners for each SourceBuffer, so that they can be referenced for event removal
|
7276
|
-
|
7277
|
-
|
7223
|
+
this.listeners = void 0;
|
7224
|
+
this.hls = void 0;
|
7278
7225
|
// The number of BUFFER_CODEC events received before any sourceBuffers are created
|
7279
|
-
|
7226
|
+
this.bufferCodecEventsExpected = 0;
|
7280
7227
|
// The total number of BUFFER_CODEC events received
|
7281
|
-
|
7228
|
+
this._bufferCodecEventsTotal = 0;
|
7282
7229
|
// A reference to the attached media element
|
7283
|
-
|
7230
|
+
this.media = null;
|
7284
7231
|
// A reference to the active media source
|
7285
|
-
|
7232
|
+
this.mediaSource = null;
|
7286
7233
|
// Last MP3 audio chunk appended
|
7287
|
-
|
7288
|
-
|
7234
|
+
this.lastMpegAudioChunk = null;
|
7235
|
+
this.appendSource = void 0;
|
7289
7236
|
// counters
|
7290
|
-
|
7237
|
+
this.appendErrors = {
|
7291
7238
|
audio: 0,
|
7292
7239
|
video: 0,
|
7293
7240
|
audiovideo: 0
|
7294
7241
|
};
|
7295
|
-
|
7296
|
-
|
7297
|
-
|
7298
|
-
|
7242
|
+
this.tracks = {};
|
7243
|
+
this.pendingTracks = {};
|
7244
|
+
this.sourceBuffer = void 0;
|
7245
|
+
this.log = void 0;
|
7246
|
+
this.warn = void 0;
|
7247
|
+
this.error = void 0;
|
7248
|
+
this._onEndStreaming = function (event) {
|
7299
7249
|
if (!_this.hls) {
|
7300
7250
|
return;
|
7301
7251
|
}
|
7302
7252
|
_this.hls.pauseBuffering();
|
7303
7253
|
};
|
7304
|
-
|
7254
|
+
this._onStartStreaming = function (event) {
|
7305
7255
|
if (!_this.hls) {
|
7306
7256
|
return;
|
7307
7257
|
}
|
7308
7258
|
_this.hls.resumeBuffering();
|
7309
7259
|
};
|
7310
7260
|
// Keep as arrow functions so that we can directly reference these functions directly as event listeners
|
7311
|
-
|
7312
|
-
var
|
7313
|
-
|
7314
|
-
mediaSource = _assertThisInitialize.mediaSource;
|
7261
|
+
this._onMediaSourceOpen = function () {
|
7262
|
+
var media = _this.media,
|
7263
|
+
mediaSource = _this.mediaSource;
|
7315
7264
|
_this.log('Media source opened');
|
7316
7265
|
if (media) {
|
7317
7266
|
media.removeEventListener('emptied', _this._onMediaEmptied);
|
@@ -7327,25 +7276,27 @@
|
|
7327
7276
|
}
|
7328
7277
|
_this.checkPendingTracks();
|
7329
7278
|
};
|
7330
|
-
|
7279
|
+
this._onMediaSourceClose = function () {
|
7331
7280
|
_this.log('Media source closed');
|
7332
7281
|
};
|
7333
|
-
|
7282
|
+
this._onMediaSourceEnded = function () {
|
7334
7283
|
_this.log('Media source ended');
|
7335
7284
|
};
|
7336
|
-
|
7337
|
-
var
|
7338
|
-
|
7339
|
-
_objectUrl = _assertThisInitialize2._objectUrl;
|
7285
|
+
this._onMediaEmptied = function () {
|
7286
|
+
var mediaSrc = _this.mediaSrc,
|
7287
|
+
_objectUrl = _this._objectUrl;
|
7340
7288
|
if (mediaSrc !== _objectUrl) {
|
7341
|
-
|
7289
|
+
logger.error("Media element src was set while attaching MediaSource (" + _objectUrl + " > " + mediaSrc + ")");
|
7342
7290
|
}
|
7343
7291
|
};
|
7344
|
-
|
7345
|
-
|
7346
|
-
|
7347
|
-
|
7348
|
-
|
7292
|
+
this.hls = hls;
|
7293
|
+
var logPrefix = '[buffer-controller]';
|
7294
|
+
this.appendSource = hls.config.preferManagedMediaSource;
|
7295
|
+
this.log = logger.log.bind(logger, logPrefix);
|
7296
|
+
this.warn = logger.warn.bind(logger, logPrefix);
|
7297
|
+
this.error = logger.error.bind(logger, logPrefix);
|
7298
|
+
this._initSourceBuffer();
|
7299
|
+
this.registerListeners();
|
7349
7300
|
}
|
7350
7301
|
var _proto = BufferController.prototype;
|
7351
7302
|
_proto.hasSourceTypes = function hasSourceTypes() {
|
@@ -7357,12 +7308,6 @@
|
|
7357
7308
|
this.lastMpegAudioChunk = null;
|
7358
7309
|
// @ts-ignore
|
7359
7310
|
this.hls = null;
|
7360
|
-
// @ts-ignore
|
7361
|
-
this._onMediaSourceOpen = this._onMediaSourceClose = null;
|
7362
|
-
// @ts-ignore
|
7363
|
-
this._onMediaSourceEnded = null;
|
7364
|
-
// @ts-ignore
|
7365
|
-
this._onStartStreaming = this._onEndStreaming = null;
|
7366
7311
|
};
|
7367
7312
|
_proto.registerListeners = function registerListeners() {
|
7368
7313
|
var hls = this.hls;
|
@@ -8223,7 +8168,7 @@
|
|
8223
8168
|
}
|
8224
8169
|
}]);
|
8225
8170
|
return BufferController;
|
8226
|
-
}(
|
8171
|
+
}();
|
8227
8172
|
function removeSourceChildren(node) {
|
8228
8173
|
var sourceChildren = node.querySelectorAll('source');
|
8229
8174
|
[].slice.call(sourceChildren).forEach(function (source) {
|
@@ -8347,7 +8292,7 @@
|
|
8347
8292
|
var hls = this.hls;
|
8348
8293
|
var maxLevel = this.getMaxLevel(levels.length - 1);
|
8349
8294
|
if (maxLevel !== this.autoLevelCapping) {
|
8350
|
-
|
8295
|
+
logger.log("Setting autoLevelCapping to " + maxLevel + ": " + levels[maxLevel].height + "p@" + levels[maxLevel].bitrate + " for media " + this.mediaWidth + "x" + this.mediaHeight);
|
8351
8296
|
}
|
8352
8297
|
hls.autoLevelCapping = maxLevel;
|
8353
8298
|
if (hls.autoLevelCapping > this.autoLevelCapping && this.streamController) {
|
@@ -8537,10 +8482,10 @@
|
|
8537
8482
|
totalDroppedFrames: droppedFrames
|
8538
8483
|
});
|
8539
8484
|
if (droppedFPS > 0) {
|
8540
|
-
//
|
8485
|
+
// logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
|
8541
8486
|
if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
|
8542
8487
|
var currentLevel = hls.currentLevel;
|
8543
|
-
|
8488
|
+
logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
|
8544
8489
|
if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
|
8545
8490
|
currentLevel = currentLevel - 1;
|
8546
8491
|
hls.trigger(Events.FPS_DROP_LEVEL_CAPPING, {
|
@@ -8574,28 +8519,26 @@
|
|
8574
8519
|
}();
|
8575
8520
|
|
8576
8521
|
var PATHWAY_PENALTY_DURATION_MS = 300000;
|
8577
|
-
var ContentSteeringController = /*#__PURE__*/function (
|
8578
|
-
_inheritsLoose(ContentSteeringController, _Logger);
|
8522
|
+
var ContentSteeringController = /*#__PURE__*/function () {
|
8579
8523
|
function ContentSteeringController(hls) {
|
8580
|
-
|
8581
|
-
|
8582
|
-
|
8583
|
-
|
8584
|
-
|
8585
|
-
|
8586
|
-
|
8587
|
-
|
8588
|
-
|
8589
|
-
|
8590
|
-
|
8591
|
-
|
8592
|
-
|
8593
|
-
|
8594
|
-
|
8595
|
-
|
8596
|
-
|
8597
|
-
|
8598
|
-
return _this;
|
8524
|
+
this.hls = void 0;
|
8525
|
+
this.log = void 0;
|
8526
|
+
this.loader = null;
|
8527
|
+
this.uri = null;
|
8528
|
+
this.pathwayId = '.';
|
8529
|
+
this.pathwayPriority = null;
|
8530
|
+
this.timeToLoad = 300;
|
8531
|
+
this.reloadTimer = -1;
|
8532
|
+
this.updated = 0;
|
8533
|
+
this.started = false;
|
8534
|
+
this.enabled = true;
|
8535
|
+
this.levels = null;
|
8536
|
+
this.audioTracks = null;
|
8537
|
+
this.subtitleTracks = null;
|
8538
|
+
this.penalizedPathways = {};
|
8539
|
+
this.hls = hls;
|
8540
|
+
this.log = logger.log.bind(logger, "[content-steering]:");
|
8541
|
+
this.registerListeners();
|
8599
8542
|
}
|
8600
8543
|
var _proto = ContentSteeringController.prototype;
|
8601
8544
|
_proto.registerListeners = function registerListeners() {
|
@@ -8716,7 +8659,7 @@
|
|
8716
8659
|
errorAction.resolved = this.pathwayId !== errorPathway;
|
8717
8660
|
}
|
8718
8661
|
if (!errorAction.resolved) {
|
8719
|
-
|
8662
|
+
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));
|
8720
8663
|
}
|
8721
8664
|
}
|
8722
8665
|
};
|
@@ -8796,7 +8739,7 @@
|
|
8796
8739
|
return defaultPathway;
|
8797
8740
|
};
|
8798
8741
|
_proto.clonePathways = function clonePathways(pathwayClones) {
|
8799
|
-
var
|
8742
|
+
var _this = this;
|
8800
8743
|
var levels = this.levels;
|
8801
8744
|
if (!levels) {
|
8802
8745
|
return;
|
@@ -8812,7 +8755,7 @@
|
|
8812
8755
|
})) {
|
8813
8756
|
return;
|
8814
8757
|
}
|
8815
|
-
var clonedVariants =
|
8758
|
+
var clonedVariants = _this.getLevelsForPathway(baseId).map(function (baseLevel) {
|
8816
8759
|
var attributes = new AttrList(baseLevel.attrs);
|
8817
8760
|
attributes['PATHWAY-ID'] = cloneId;
|
8818
8761
|
var clonedAudioGroupId = attributes.AUDIO && attributes.AUDIO + "_clone_" + cloneId;
|
@@ -8849,12 +8792,12 @@
|
|
8849
8792
|
return clonedLevel;
|
8850
8793
|
});
|
8851
8794
|
levels.push.apply(levels, clonedVariants);
|
8852
|
-
cloneRenditionGroups(
|
8853
|
-
cloneRenditionGroups(
|
8795
|
+
cloneRenditionGroups(_this.audioTracks, audioGroupCloneMap, uriReplacement, cloneId);
|
8796
|
+
cloneRenditionGroups(_this.subtitleTracks, subtitleGroupCloneMap, uriReplacement, cloneId);
|
8854
8797
|
});
|
8855
8798
|
};
|
8856
8799
|
_proto.loadSteeringManifest = function loadSteeringManifest(uri) {
|
8857
|
-
var
|
8800
|
+
var _this2 = this;
|
8858
8801
|
var config = this.hls.config;
|
8859
8802
|
var Loader = config.loader;
|
8860
8803
|
if (this.loader) {
|
@@ -8889,87 +8832,87 @@
|
|
8889
8832
|
};
|
8890
8833
|
var callbacks = {
|
8891
8834
|
onSuccess: function onSuccess(response, stats, context, networkDetails) {
|
8892
|
-
|
8835
|
+
_this2.log("Loaded steering manifest: \"" + url + "\"");
|
8893
8836
|
var steeringData = response.data;
|
8894
|
-
if (
|
8895
|
-
|
8837
|
+
if (steeringData.VERSION !== 1) {
|
8838
|
+
_this2.log("Steering VERSION " + steeringData.VERSION + " not supported!");
|
8896
8839
|
return;
|
8897
8840
|
}
|
8898
|
-
|
8899
|
-
|
8841
|
+
_this2.updated = performance.now();
|
8842
|
+
_this2.timeToLoad = steeringData.TTL;
|
8900
8843
|
var reloadUri = steeringData['RELOAD-URI'],
|
8901
8844
|
pathwayClones = steeringData['PATHWAY-CLONES'],
|
8902
8845
|
pathwayPriority = steeringData['PATHWAY-PRIORITY'];
|
8903
8846
|
if (reloadUri) {
|
8904
8847
|
try {
|
8905
|
-
|
8848
|
+
_this2.uri = new self.URL(reloadUri, url).href;
|
8906
8849
|
} catch (error) {
|
8907
|
-
|
8908
|
-
|
8850
|
+
_this2.enabled = false;
|
8851
|
+
_this2.log("Failed to parse Steering Manifest RELOAD-URI: " + reloadUri);
|
8909
8852
|
return;
|
8910
8853
|
}
|
8911
8854
|
}
|
8912
|
-
|
8855
|
+
_this2.scheduleRefresh(_this2.uri || context.url);
|
8913
8856
|
if (pathwayClones) {
|
8914
|
-
|
8857
|
+
_this2.clonePathways(pathwayClones);
|
8915
8858
|
}
|
8916
8859
|
var loadedSteeringData = {
|
8917
8860
|
steeringManifest: steeringData,
|
8918
8861
|
url: url.toString()
|
8919
8862
|
};
|
8920
|
-
|
8863
|
+
_this2.hls.trigger(Events.STEERING_MANIFEST_LOADED, loadedSteeringData);
|
8921
8864
|
if (pathwayPriority) {
|
8922
|
-
|
8865
|
+
_this2.updatePathwayPriority(pathwayPriority);
|
8923
8866
|
}
|
8924
8867
|
},
|
8925
8868
|
onError: function onError(error, context, networkDetails, stats) {
|
8926
|
-
|
8927
|
-
|
8869
|
+
_this2.log("Error loading steering manifest: " + error.code + " " + error.text + " (" + context.url + ")");
|
8870
|
+
_this2.stopLoad();
|
8928
8871
|
if (error.code === 410) {
|
8929
|
-
|
8930
|
-
|
8872
|
+
_this2.enabled = false;
|
8873
|
+
_this2.log("Steering manifest " + context.url + " no longer available");
|
8931
8874
|
return;
|
8932
8875
|
}
|
8933
|
-
var ttl =
|
8876
|
+
var ttl = _this2.timeToLoad * 1000;
|
8934
8877
|
if (error.code === 429) {
|
8935
|
-
var loader =
|
8878
|
+
var loader = _this2.loader;
|
8936
8879
|
if (typeof (loader == null ? void 0 : loader.getResponseHeader) === 'function') {
|
8937
8880
|
var retryAfter = loader.getResponseHeader('Retry-After');
|
8938
8881
|
if (retryAfter) {
|
8939
8882
|
ttl = parseFloat(retryAfter) * 1000;
|
8940
8883
|
}
|
8941
8884
|
}
|
8942
|
-
|
8885
|
+
_this2.log("Steering manifest " + context.url + " rate limited");
|
8943
8886
|
return;
|
8944
8887
|
}
|
8945
|
-
|
8888
|
+
_this2.scheduleRefresh(_this2.uri || context.url, ttl);
|
8946
8889
|
},
|
8947
8890
|
onTimeout: function onTimeout(stats, context, networkDetails) {
|
8948
|
-
|
8949
|
-
|
8891
|
+
_this2.log("Timeout loading steering manifest (" + context.url + ")");
|
8892
|
+
_this2.scheduleRefresh(_this2.uri || context.url);
|
8950
8893
|
}
|
8951
8894
|
};
|
8952
8895
|
this.log("Requesting steering manifest: " + url);
|
8953
8896
|
this.loader.load(context, loaderConfig, callbacks);
|
8954
8897
|
};
|
8955
8898
|
_proto.scheduleRefresh = function scheduleRefresh(uri, ttlMs) {
|
8956
|
-
var
|
8899
|
+
var _this3 = this;
|
8957
8900
|
if (ttlMs === void 0) {
|
8958
8901
|
ttlMs = this.timeToLoad * 1000;
|
8959
8902
|
}
|
8960
8903
|
this.clearTimeout();
|
8961
8904
|
this.reloadTimer = self.setTimeout(function () {
|
8962
|
-
var
|
8963
|
-
var media = (
|
8905
|
+
var _this3$hls;
|
8906
|
+
var media = (_this3$hls = _this3.hls) == null ? void 0 : _this3$hls.media;
|
8964
8907
|
if (media && !media.ended) {
|
8965
|
-
|
8908
|
+
_this3.loadSteeringManifest(uri);
|
8966
8909
|
return;
|
8967
8910
|
}
|
8968
|
-
|
8911
|
+
_this3.scheduleRefresh(uri, _this3.timeToLoad * 1000);
|
8969
8912
|
}, ttlMs);
|
8970
8913
|
};
|
8971
8914
|
return ContentSteeringController;
|
8972
|
-
}(
|
8915
|
+
}();
|
8973
8916
|
function cloneRenditionGroups(tracks, groupCloneMap, uriReplacement, cloneId) {
|
8974
8917
|
if (!tracks) {
|
8975
8918
|
return;
|
@@ -9836,7 +9779,7 @@
|
|
9836
9779
|
/**
|
9837
9780
|
* @ignore
|
9838
9781
|
*/
|
9839
|
-
function mergeConfig(defaultConfig, userConfig
|
9782
|
+
function mergeConfig(defaultConfig, userConfig) {
|
9840
9783
|
if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) {
|
9841
9784
|
throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration");
|
9842
9785
|
}
|
@@ -9906,7 +9849,7 @@
|
|
9906
9849
|
/**
|
9907
9850
|
* @ignore
|
9908
9851
|
*/
|
9909
|
-
function enableStreamingMode(config
|
9852
|
+
function enableStreamingMode(config) {
|
9910
9853
|
var currentLoader = config.loader;
|
9911
9854
|
if (currentLoader !== FetchLoader && currentLoader !== XhrLoader) {
|
9912
9855
|
// If a developer has configured their own loader, respect that choice
|
@@ -9923,11 +9866,12 @@
|
|
9923
9866
|
}
|
9924
9867
|
}
|
9925
9868
|
|
9869
|
+
var chromeOrFirefox;
|
9926
9870
|
var LevelController = /*#__PURE__*/function (_BasePlaylistControll) {
|
9927
9871
|
_inheritsLoose(LevelController, _BasePlaylistControll);
|
9928
9872
|
function LevelController(hls, contentSteeringController) {
|
9929
9873
|
var _this;
|
9930
|
-
_this = _BasePlaylistControll.call(this, hls, 'level-controller') || this;
|
9874
|
+
_this = _BasePlaylistControll.call(this, hls, '[level-controller]') || this;
|
9931
9875
|
_this._levels = [];
|
9932
9876
|
_this._firstLevel = -1;
|
9933
9877
|
_this._maxAutoLevel = -1;
|
@@ -9996,13 +9940,21 @@
|
|
9996
9940
|
var videoCodecFound = false;
|
9997
9941
|
var audioCodecFound = false;
|
9998
9942
|
data.levels.forEach(function (levelParsed) {
|
9999
|
-
var _videoCodec;
|
9943
|
+
var _audioCodec, _videoCodec;
|
10000
9944
|
var attributes = levelParsed.attrs;
|
9945
|
+
|
9946
|
+
// erase audio codec info if browser does not support mp4a.40.34.
|
9947
|
+
// demuxer will autodetect codec and fallback to mpeg/audio
|
10001
9948
|
var audioCodec = levelParsed.audioCodec,
|
10002
9949
|
videoCodec = levelParsed.videoCodec;
|
9950
|
+
if (((_audioCodec = audioCodec) == null ? void 0 : _audioCodec.indexOf('mp4a.40.34')) !== -1) {
|
9951
|
+
chromeOrFirefox || (chromeOrFirefox = /chrome|firefox/i.test(navigator.userAgent));
|
9952
|
+
if (chromeOrFirefox) {
|
9953
|
+
levelParsed.audioCodec = audioCodec = undefined;
|
9954
|
+
}
|
9955
|
+
}
|
10003
9956
|
if (audioCodec) {
|
10004
|
-
|
10005
|
-
levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource) || undefined;
|
9957
|
+
levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource);
|
10006
9958
|
}
|
10007
9959
|
if (((_videoCodec = videoCodec) == null ? void 0 : _videoCodec.indexOf('avc1')) === 0) {
|
10008
9960
|
videoCodec = levelParsed.videoCodec = convertAVC1ToAVCOTI(videoCodec);
|
@@ -11149,8 +11101,8 @@
|
|
11149
11101
|
var _frag$decryptdata;
|
11150
11102
|
var byteRangeStart = start;
|
11151
11103
|
var byteRangeEnd = end;
|
11152
|
-
if (frag.sn === 'initSegment' &&
|
11153
|
-
// MAP segment encrypted with method 'AES-128'
|
11104
|
+
if (frag.sn === 'initSegment' && ((_frag$decryptdata = frag.decryptdata) == null ? void 0 : _frag$decryptdata.method) === 'AES-128') {
|
11105
|
+
// MAP segment encrypted with method 'AES-128', when served with HTTP Range,
|
11154
11106
|
// has the unencrypted size specified in the range.
|
11155
11107
|
// Ref: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-6.3.6
|
11156
11108
|
var fragmentLen = end - start;
|
@@ -11183,9 +11135,6 @@
|
|
11183
11135
|
(part ? part : frag).stats.aborted = true;
|
11184
11136
|
return new LoadError(errorData);
|
11185
11137
|
}
|
11186
|
-
function isMethodFullSegmentAesCbc(method) {
|
11187
|
-
return method === 'AES-128' || method === 'AES-256';
|
11188
|
-
}
|
11189
11138
|
var LoadError = /*#__PURE__*/function (_Error) {
|
11190
11139
|
_inheritsLoose(LoadError, _Error);
|
11191
11140
|
function LoadError(data) {
|
@@ -11342,8 +11291,6 @@
|
|
11342
11291
|
}
|
11343
11292
|
return this.loadKeyEME(keyInfo, frag);
|
11344
11293
|
case 'AES-128':
|
11345
|
-
case 'AES-256':
|
11346
|
-
case 'AES-256-CTR':
|
11347
11294
|
return this.loadKeyHTTP(keyInfo, frag);
|
11348
11295
|
default:
|
11349
11296
|
return Promise.reject(this.createKeyLoadError(frag, ErrorDetails.KEY_LOAD_ERROR, new Error("Key supplied with unsupported METHOD: \"" + decryptdata.method + "\"")));
|
@@ -11477,17 +11424,13 @@
|
|
11477
11424
|
* we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further
|
11478
11425
|
* task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo).
|
11479
11426
|
*/
|
11480
|
-
var TaskLoop = /*#__PURE__*/function (
|
11481
|
-
|
11482
|
-
|
11483
|
-
|
11484
|
-
|
11485
|
-
|
11486
|
-
|
11487
|
-
_this._tickInterval = null;
|
11488
|
-
_this._tickCallCount = 0;
|
11489
|
-
_this._boundTick = _this.tick.bind(_assertThisInitialized(_this));
|
11490
|
-
return _this;
|
11427
|
+
var TaskLoop = /*#__PURE__*/function () {
|
11428
|
+
function TaskLoop() {
|
11429
|
+
this._boundTick = void 0;
|
11430
|
+
this._tickTimer = null;
|
11431
|
+
this._tickInterval = null;
|
11432
|
+
this._tickCallCount = 0;
|
11433
|
+
this._boundTick = this.tick.bind(this);
|
11491
11434
|
}
|
11492
11435
|
var _proto = TaskLoop.prototype;
|
11493
11436
|
_proto.destroy = function destroy() {
|
@@ -11573,7 +11516,7 @@
|
|
11573
11516
|
*/;
|
11574
11517
|
_proto.doTick = function doTick() {};
|
11575
11518
|
return TaskLoop;
|
11576
|
-
}(
|
11519
|
+
}();
|
11577
11520
|
|
11578
11521
|
var ChunkMetadata = function ChunkMetadata(level, sn, id, size, part, partial) {
|
11579
11522
|
if (size === void 0) {
|
@@ -11759,65 +11702,37 @@
|
|
11759
11702
|
}
|
11760
11703
|
|
11761
11704
|
var AESCrypto = /*#__PURE__*/function () {
|
11762
|
-
function AESCrypto(subtle, iv
|
11705
|
+
function AESCrypto(subtle, iv) {
|
11763
11706
|
this.subtle = void 0;
|
11764
11707
|
this.aesIV = void 0;
|
11765
|
-
this.aesMode = void 0;
|
11766
11708
|
this.subtle = subtle;
|
11767
11709
|
this.aesIV = iv;
|
11768
|
-
this.aesMode = aesMode;
|
11769
11710
|
}
|
11770
11711
|
var _proto = AESCrypto.prototype;
|
11771
11712
|
_proto.decrypt = function decrypt(data, key) {
|
11772
|
-
|
11773
|
-
|
11774
|
-
|
11775
|
-
|
11776
|
-
iv: this.aesIV
|
11777
|
-
}, key, data);
|
11778
|
-
case DecrypterAesMode.ctr:
|
11779
|
-
return this.subtle.decrypt({
|
11780
|
-
name: 'AES-CTR',
|
11781
|
-
counter: this.aesIV,
|
11782
|
-
length: 64
|
11783
|
-
},
|
11784
|
-
//64 : NIST SP800-38A standard suggests that the counter should occupy half of the counter block
|
11785
|
-
key, data);
|
11786
|
-
default:
|
11787
|
-
throw new Error("[AESCrypto] invalid aes mode " + this.aesMode);
|
11788
|
-
}
|
11713
|
+
return this.subtle.decrypt({
|
11714
|
+
name: 'AES-CBC',
|
11715
|
+
iv: this.aesIV
|
11716
|
+
}, key, data);
|
11789
11717
|
};
|
11790
11718
|
return AESCrypto;
|
11791
11719
|
}();
|
11792
11720
|
|
11793
11721
|
var FastAESKey = /*#__PURE__*/function () {
|
11794
|
-
function FastAESKey(subtle, key
|
11722
|
+
function FastAESKey(subtle, key) {
|
11795
11723
|
this.subtle = void 0;
|
11796
11724
|
this.key = void 0;
|
11797
|
-
this.aesMode = void 0;
|
11798
11725
|
this.subtle = subtle;
|
11799
11726
|
this.key = key;
|
11800
|
-
this.aesMode = aesMode;
|
11801
11727
|
}
|
11802
11728
|
var _proto = FastAESKey.prototype;
|
11803
11729
|
_proto.expandKey = function expandKey() {
|
11804
|
-
var subtleAlgoName = getSubtleAlgoName(this.aesMode);
|
11805
11730
|
return this.subtle.importKey('raw', this.key, {
|
11806
|
-
name:
|
11731
|
+
name: 'AES-CBC'
|
11807
11732
|
}, false, ['encrypt', 'decrypt']);
|
11808
11733
|
};
|
11809
11734
|
return FastAESKey;
|
11810
11735
|
}();
|
11811
|
-
function getSubtleAlgoName(aesMode) {
|
11812
|
-
switch (aesMode) {
|
11813
|
-
case DecrypterAesMode.cbc:
|
11814
|
-
return 'AES-CBC';
|
11815
|
-
case DecrypterAesMode.ctr:
|
11816
|
-
return 'AES-CTR';
|
11817
|
-
default:
|
11818
|
-
throw new Error("[FastAESKey] invalid aes mode " + aesMode);
|
11819
|
-
}
|
11820
|
-
}
|
11821
11736
|
|
11822
11737
|
// PKCS7
|
11823
11738
|
function removePadding(array) {
|
@@ -12070,8 +11985,7 @@
|
|
12070
11985
|
this.currentIV = null;
|
12071
11986
|
this.currentResult = null;
|
12072
11987
|
this.useSoftware = void 0;
|
12073
|
-
this.
|
12074
|
-
this.enableSoftwareAES = config.enableSoftwareAES;
|
11988
|
+
this.useSoftware = config.enableSoftwareAES;
|
12075
11989
|
this.removePKCS7Padding = removePKCS7Padding;
|
12076
11990
|
// built in decryptor expects PKCS7 padding
|
12077
11991
|
if (removePKCS7Padding) {
|
@@ -12084,7 +11998,9 @@
|
|
12084
11998
|
/* no-op */
|
12085
11999
|
}
|
12086
12000
|
}
|
12087
|
-
|
12001
|
+
if (this.subtle === null) {
|
12002
|
+
this.useSoftware = true;
|
12003
|
+
}
|
12088
12004
|
}
|
12089
12005
|
var _proto = Decrypter.prototype;
|
12090
12006
|
_proto.destroy = function destroy() {
|
@@ -12121,11 +12037,11 @@
|
|
12121
12037
|
this.softwareDecrypter = null;
|
12122
12038
|
}
|
12123
12039
|
};
|
12124
|
-
_proto.decrypt = function decrypt(data, key, iv
|
12040
|
+
_proto.decrypt = function decrypt(data, key, iv) {
|
12125
12041
|
var _this = this;
|
12126
12042
|
if (this.useSoftware) {
|
12127
12043
|
return new Promise(function (resolve, reject) {
|
12128
|
-
_this.softwareDecrypt(new Uint8Array(data), key, iv
|
12044
|
+
_this.softwareDecrypt(new Uint8Array(data), key, iv);
|
12129
12045
|
var decryptResult = _this.flush();
|
12130
12046
|
if (decryptResult) {
|
12131
12047
|
resolve(decryptResult.buffer);
|
@@ -12134,20 +12050,16 @@
|
|
12134
12050
|
}
|
12135
12051
|
});
|
12136
12052
|
}
|
12137
|
-
return this.webCryptoDecrypt(new Uint8Array(data), key, iv
|
12053
|
+
return this.webCryptoDecrypt(new Uint8Array(data), key, iv);
|
12138
12054
|
}
|
12139
12055
|
|
12140
12056
|
// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
|
12141
12057
|
// data is handled in the flush() call
|
12142
12058
|
;
|
12143
|
-
_proto.softwareDecrypt = function softwareDecrypt(data, key, iv
|
12059
|
+
_proto.softwareDecrypt = function softwareDecrypt(data, key, iv) {
|
12144
12060
|
var currentIV = this.currentIV,
|
12145
12061
|
currentResult = this.currentResult,
|
12146
12062
|
remainderData = this.remainderData;
|
12147
|
-
if (aesMode !== DecrypterAesMode.cbc || key.byteLength !== 16) {
|
12148
|
-
logger.warn('SoftwareDecrypt: can only handle AES-128-CBC');
|
12149
|
-
return null;
|
12150
|
-
}
|
12151
12063
|
this.logOnce('JS AES decrypt');
|
12152
12064
|
// The output is staggered during progressive parsing - the current result is cached, and emitted on the next call
|
12153
12065
|
// This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached
|
@@ -12180,12 +12092,12 @@
|
|
12180
12092
|
}
|
12181
12093
|
return result;
|
12182
12094
|
};
|
12183
|
-
_proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv
|
12095
|
+
_proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv) {
|
12184
12096
|
var _this2 = this;
|
12185
12097
|
var subtle = this.subtle;
|
12186
12098
|
if (this.key !== key || !this.fastAesKey) {
|
12187
12099
|
this.key = key;
|
12188
|
-
this.fastAesKey = new FastAESKey(subtle, key
|
12100
|
+
this.fastAesKey = new FastAESKey(subtle, key);
|
12189
12101
|
}
|
12190
12102
|
return this.fastAesKey.expandKey().then(function (aesKey) {
|
12191
12103
|
// decrypt using web crypto
|
@@ -12193,25 +12105,22 @@
|
|
12193
12105
|
return Promise.reject(new Error('web crypto not initialized'));
|
12194
12106
|
}
|
12195
12107
|
_this2.logOnce('WebCrypto AES decrypt');
|
12196
|
-
var crypto = new AESCrypto(subtle, new Uint8Array(iv)
|
12108
|
+
var crypto = new AESCrypto(subtle, new Uint8Array(iv));
|
12197
12109
|
return crypto.decrypt(data.buffer, aesKey);
|
12198
12110
|
}).catch(function (err) {
|
12199
12111
|
logger.warn("[decrypter]: WebCrypto Error, disable WebCrypto API, " + err.name + ": " + err.message);
|
12200
|
-
return _this2.onWebCryptoError(data, key, iv
|
12112
|
+
return _this2.onWebCryptoError(data, key, iv);
|
12201
12113
|
});
|
12202
12114
|
};
|
12203
|
-
_proto.onWebCryptoError = function onWebCryptoError(data, key, iv
|
12204
|
-
|
12205
|
-
|
12206
|
-
|
12207
|
-
|
12208
|
-
|
12209
|
-
|
12210
|
-
if (decryptResult) {
|
12211
|
-
return decryptResult.buffer;
|
12212
|
-
}
|
12115
|
+
_proto.onWebCryptoError = function onWebCryptoError(data, key, iv) {
|
12116
|
+
this.useSoftware = true;
|
12117
|
+
this.logEnabled = true;
|
12118
|
+
this.softwareDecrypt(data, key, iv);
|
12119
|
+
var decryptResult = this.flush();
|
12120
|
+
if (decryptResult) {
|
12121
|
+
return decryptResult.buffer;
|
12213
12122
|
}
|
12214
|
-
throw new Error('WebCrypto
|
12123
|
+
throw new Error('WebCrypto and softwareDecrypt: failed to decrypt data');
|
12215
12124
|
};
|
12216
12125
|
_proto.getValidChunk = function getValidChunk(data) {
|
12217
12126
|
var currentChunk = data;
|
@@ -12265,7 +12174,7 @@
|
|
12265
12174
|
_inheritsLoose(BaseStreamController, _TaskLoop);
|
12266
12175
|
function BaseStreamController(hls, fragmentTracker, keyLoader, logPrefix, playlistType) {
|
12267
12176
|
var _this;
|
12268
|
-
_this = _TaskLoop.call(this
|
12177
|
+
_this = _TaskLoop.call(this) || this;
|
12269
12178
|
_this.hls = void 0;
|
12270
12179
|
_this.fragPrevious = null;
|
12271
12180
|
_this.fragCurrent = null;
|
@@ -12290,86 +12199,25 @@
|
|
12290
12199
|
_this.startFragRequested = false;
|
12291
12200
|
_this.decrypter = void 0;
|
12292
12201
|
_this.initPTS = [];
|
12293
|
-
_this.
|
12294
|
-
|
12295
|
-
|
12296
|
-
|
12297
|
-
|
12298
|
-
mediaBuffer = _assertThisInitialize.mediaBuffer,
|
12299
|
-
state = _assertThisInitialize.state;
|
12300
|
-
var currentTime = media ? media.currentTime : 0;
|
12301
|
-
var bufferInfo = BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
|
12302
|
-
_this.log("media seeking to " + (isFiniteNumber(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
|
12303
|
-
if (_this.state === State.ENDED) {
|
12304
|
-
_this.resetLoadingState();
|
12305
|
-
} else if (fragCurrent) {
|
12306
|
-
// Seeking while frag load is in progress
|
12307
|
-
var tolerance = config.maxFragLookUpTolerance;
|
12308
|
-
var fragStartOffset = fragCurrent.start - tolerance;
|
12309
|
-
var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
|
12310
|
-
// if seeking out of buffered range or into new one
|
12311
|
-
if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
|
12312
|
-
var pastFragment = currentTime > fragEndOffset;
|
12313
|
-
// if the seek position is outside the current fragment range
|
12314
|
-
if (currentTime < fragStartOffset || pastFragment) {
|
12315
|
-
if (pastFragment && fragCurrent.loader) {
|
12316
|
-
_this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
|
12317
|
-
fragCurrent.abortRequests();
|
12318
|
-
_this.resetLoadingState();
|
12319
|
-
}
|
12320
|
-
_this.fragPrevious = null;
|
12321
|
-
}
|
12322
|
-
}
|
12323
|
-
}
|
12324
|
-
if (media) {
|
12325
|
-
// Remove gap fragments
|
12326
|
-
_this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, _this.playlistType, true);
|
12327
|
-
_this.lastCurrentTime = currentTime;
|
12328
|
-
}
|
12329
|
-
|
12330
|
-
// in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
|
12331
|
-
if (!_this.loadedmetadata && !bufferInfo.len) {
|
12332
|
-
_this.nextLoadPosition = _this.startPosition = currentTime;
|
12333
|
-
}
|
12334
|
-
|
12335
|
-
// Async tick to speed up processing
|
12336
|
-
_this.tickImmediate();
|
12337
|
-
};
|
12338
|
-
_this.onMediaEnded = function () {
|
12339
|
-
// reset startPosition and lastCurrentTime to restart playback @ stream beginning
|
12340
|
-
_this.startPosition = _this.lastCurrentTime = 0;
|
12341
|
-
if (_this.playlistType === PlaylistLevelType.MAIN) {
|
12342
|
-
_this.hls.trigger(Events.MEDIA_ENDED, {
|
12343
|
-
stalled: false
|
12344
|
-
});
|
12345
|
-
}
|
12346
|
-
};
|
12202
|
+
_this.onvseeking = null;
|
12203
|
+
_this.onvended = null;
|
12204
|
+
_this.logPrefix = '';
|
12205
|
+
_this.log = void 0;
|
12206
|
+
_this.warn = void 0;
|
12347
12207
|
_this.playlistType = playlistType;
|
12208
|
+
_this.logPrefix = logPrefix;
|
12209
|
+
_this.log = logger.log.bind(logger, logPrefix + ":");
|
12210
|
+
_this.warn = logger.warn.bind(logger, logPrefix + ":");
|
12348
12211
|
_this.hls = hls;
|
12349
12212
|
_this.fragmentLoader = new FragmentLoader(hls.config);
|
12350
12213
|
_this.keyLoader = keyLoader;
|
12351
12214
|
_this.fragmentTracker = fragmentTracker;
|
12352
12215
|
_this.config = hls.config;
|
12353
12216
|
_this.decrypter = new Decrypter(hls.config);
|
12217
|
+
hls.on(Events.MANIFEST_LOADED, _this.onManifestLoaded, _assertThisInitialized(_this));
|
12354
12218
|
return _this;
|
12355
12219
|
}
|
12356
12220
|
var _proto = BaseStreamController.prototype;
|
12357
|
-
_proto.registerListeners = function registerListeners() {
|
12358
|
-
var hls = this.hls;
|
12359
|
-
hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
12360
|
-
hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
12361
|
-
hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
12362
|
-
hls.on(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
|
12363
|
-
hls.on(Events.ERROR, this.onError, this);
|
12364
|
-
};
|
12365
|
-
_proto.unregisterListeners = function unregisterListeners() {
|
12366
|
-
var hls = this.hls;
|
12367
|
-
hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
12368
|
-
hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
12369
|
-
hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
12370
|
-
hls.off(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
|
12371
|
-
hls.off(Events.ERROR, this.onError, this);
|
12372
|
-
};
|
12373
12221
|
_proto.doTick = function doTick() {
|
12374
12222
|
this.onTickEnd();
|
12375
12223
|
};
|
@@ -12423,8 +12271,10 @@
|
|
12423
12271
|
};
|
12424
12272
|
_proto.onMediaAttached = function onMediaAttached(event, data) {
|
12425
12273
|
var media = this.media = this.mediaBuffer = data.media;
|
12426
|
-
|
12427
|
-
|
12274
|
+
this.onvseeking = this.onMediaSeeking.bind(this);
|
12275
|
+
this.onvended = this.onMediaEnded.bind(this);
|
12276
|
+
media.addEventListener('seeking', this.onvseeking);
|
12277
|
+
media.addEventListener('ended', this.onvended);
|
12428
12278
|
var config = this.config;
|
12429
12279
|
if (this.levels && config.autoStartLoad && this.state === State.STOPPED) {
|
12430
12280
|
this.startLoad(config.startPosition);
|
@@ -12438,9 +12288,10 @@
|
|
12438
12288
|
}
|
12439
12289
|
|
12440
12290
|
// remove video listeners
|
12441
|
-
if (media) {
|
12442
|
-
media.removeEventListener('seeking', this.
|
12443
|
-
media.removeEventListener('ended', this.
|
12291
|
+
if (media && this.onvseeking && this.onvended) {
|
12292
|
+
media.removeEventListener('seeking', this.onvseeking);
|
12293
|
+
media.removeEventListener('ended', this.onvended);
|
12294
|
+
this.onvseeking = this.onvended = null;
|
12444
12295
|
}
|
12445
12296
|
if (this.keyLoader) {
|
12446
12297
|
this.keyLoader.detach();
|
@@ -12450,8 +12301,54 @@
|
|
12450
12301
|
this.fragmentTracker.removeAllFragments();
|
12451
12302
|
this.stopLoad();
|
12452
12303
|
};
|
12453
|
-
_proto.
|
12454
|
-
|
12304
|
+
_proto.onMediaSeeking = function onMediaSeeking() {
|
12305
|
+
var config = this.config,
|
12306
|
+
fragCurrent = this.fragCurrent,
|
12307
|
+
media = this.media,
|
12308
|
+
mediaBuffer = this.mediaBuffer,
|
12309
|
+
state = this.state;
|
12310
|
+
var currentTime = media ? media.currentTime : 0;
|
12311
|
+
var bufferInfo = BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
|
12312
|
+
this.log("media seeking to " + (isFiniteNumber(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
|
12313
|
+
if (this.state === State.ENDED) {
|
12314
|
+
this.resetLoadingState();
|
12315
|
+
} else if (fragCurrent) {
|
12316
|
+
// Seeking while frag load is in progress
|
12317
|
+
var tolerance = config.maxFragLookUpTolerance;
|
12318
|
+
var fragStartOffset = fragCurrent.start - tolerance;
|
12319
|
+
var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
|
12320
|
+
// if seeking out of buffered range or into new one
|
12321
|
+
if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
|
12322
|
+
var pastFragment = currentTime > fragEndOffset;
|
12323
|
+
// if the seek position is outside the current fragment range
|
12324
|
+
if (currentTime < fragStartOffset || pastFragment) {
|
12325
|
+
if (pastFragment && fragCurrent.loader) {
|
12326
|
+
this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
|
12327
|
+
fragCurrent.abortRequests();
|
12328
|
+
this.resetLoadingState();
|
12329
|
+
}
|
12330
|
+
this.fragPrevious = null;
|
12331
|
+
}
|
12332
|
+
}
|
12333
|
+
}
|
12334
|
+
if (media) {
|
12335
|
+
// Remove gap fragments
|
12336
|
+
this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, this.playlistType, true);
|
12337
|
+
this.lastCurrentTime = currentTime;
|
12338
|
+
}
|
12339
|
+
|
12340
|
+
// in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
|
12341
|
+
if (!this.loadedmetadata && !bufferInfo.len) {
|
12342
|
+
this.nextLoadPosition = this.startPosition = currentTime;
|
12343
|
+
}
|
12344
|
+
|
12345
|
+
// Async tick to speed up processing
|
12346
|
+
this.tickImmediate();
|
12347
|
+
};
|
12348
|
+
_proto.onMediaEnded = function onMediaEnded() {
|
12349
|
+
// reset startPosition and lastCurrentTime to restart playback @ stream beginning
|
12350
|
+
this.startPosition = this.lastCurrentTime = 0;
|
12351
|
+
};
|
12455
12352
|
_proto.onManifestLoaded = function onManifestLoaded(event, data) {
|
12456
12353
|
this.startTimeOffset = data.startTimeOffset;
|
12457
12354
|
this.initPTS = [];
|
@@ -12461,7 +12358,7 @@
|
|
12461
12358
|
this.stopLoad();
|
12462
12359
|
_TaskLoop.prototype.onHandlerDestroying.call(this);
|
12463
12360
|
// @ts-ignore
|
12464
|
-
this.hls =
|
12361
|
+
this.hls = null;
|
12465
12362
|
};
|
12466
12363
|
_proto.onHandlerDestroyed = function onHandlerDestroyed() {
|
12467
12364
|
this.state = State.STOPPED;
|
@@ -12591,10 +12488,10 @@
|
|
12591
12488
|
var decryptData = frag.decryptdata;
|
12592
12489
|
|
12593
12490
|
// check to see if the payload needs to be decrypted
|
12594
|
-
if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv &&
|
12491
|
+
if (payload && payload.byteLength > 0 && decryptData != null && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') {
|
12595
12492
|
var startTime = self.performance.now();
|
12596
12493
|
// decrypt init segment data
|
12597
|
-
return _this3.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer
|
12494
|
+
return _this3.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).catch(function (err) {
|
12598
12495
|
hls.trigger(Events.ERROR, {
|
12599
12496
|
type: ErrorTypes.MEDIA_ERROR,
|
12600
12497
|
details: ErrorDetails.FRAG_DECRYPT_ERROR,
|
@@ -12707,7 +12604,7 @@
|
|
12707
12604
|
}
|
12708
12605
|
var keyLoadingPromise = null;
|
12709
12606
|
if (frag.encrypted && !((_frag$decryptdata = frag.decryptdata) != null && _frag$decryptdata.key)) {
|
12710
|
-
this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.
|
12607
|
+
this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + " " + frag.level);
|
12711
12608
|
this.state = State.KEY_LOADING;
|
12712
12609
|
this.fragCurrent = frag;
|
12713
12610
|
keyLoadingPromise = this.keyLoader.load(frag).then(function (keyLoadedData) {
|
@@ -12738,7 +12635,7 @@
|
|
12738
12635
|
var partIndex = this.getNextPart(partList, frag, targetBufferTime);
|
12739
12636
|
if (partIndex > -1) {
|
12740
12637
|
var part = partList[partIndex];
|
12741
|
-
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.
|
12638
|
+
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)));
|
12742
12639
|
this.nextLoadPosition = part.start + part.duration;
|
12743
12640
|
this.state = State.FRAG_LOADING;
|
12744
12641
|
var _result;
|
@@ -12771,7 +12668,7 @@
|
|
12771
12668
|
}
|
12772
12669
|
}
|
12773
12670
|
}
|
12774
|
-
this.log("Loading fragment " + frag.sn + " cc: " + frag.cc + " " + (details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : '') + (this.
|
12671
|
+
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)));
|
12775
12672
|
// Don't update nextLoadPosition for fragments which are not buffered
|
12776
12673
|
if (isFiniteNumber(frag.sn) && !this.bitrateTest) {
|
12777
12674
|
this.nextLoadPosition = frag.start + frag.duration;
|
@@ -13332,7 +13229,7 @@
|
|
13332
13229
|
errorAction.resolved = true;
|
13333
13230
|
}
|
13334
13231
|
} else {
|
13335
|
-
|
13232
|
+
logger.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
|
13336
13233
|
return;
|
13337
13234
|
}
|
13338
13235
|
} else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
|
@@ -13722,7 +13619,6 @@
|
|
13722
13619
|
*/
|
13723
13620
|
function getAudioConfig(observer, data, offset, audioCodec) {
|
13724
13621
|
var adtsObjectType;
|
13725
|
-
var originalAdtsObjectType;
|
13726
13622
|
var adtsExtensionSamplingIndex;
|
13727
13623
|
var adtsChannelConfig;
|
13728
13624
|
var config;
|
@@ -13730,7 +13626,7 @@
|
|
13730
13626
|
var manifestCodec = audioCodec;
|
13731
13627
|
var adtsSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
|
13732
13628
|
// byte 2
|
13733
|
-
adtsObjectType =
|
13629
|
+
adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;
|
13734
13630
|
var adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2;
|
13735
13631
|
if (adtsSamplingIndex > adtsSamplingRates.length - 1) {
|
13736
13632
|
var error = new Error("invalid ADTS sampling index:" + adtsSamplingIndex);
|
@@ -13747,8 +13643,8 @@
|
|
13747
13643
|
// byte 3
|
13748
13644
|
adtsChannelConfig |= (data[offset + 3] & 0xc0) >>> 6;
|
13749
13645
|
logger.log("manifest codec:" + audioCodec + ", ADTS type:" + adtsObjectType + ", samplingIndex:" + adtsSamplingIndex);
|
13750
|
-
//
|
13751
|
-
if (/firefox
|
13646
|
+
// firefox: freq less than 24kHz = AAC SBR (HE-AAC)
|
13647
|
+
if (/firefox/i.test(userAgent)) {
|
13752
13648
|
if (adtsSamplingIndex >= 6) {
|
13753
13649
|
adtsObjectType = 5;
|
13754
13650
|
config = new Array(4);
|
@@ -13842,7 +13738,6 @@
|
|
13842
13738
|
samplerate: adtsSamplingRates[adtsSamplingIndex],
|
13843
13739
|
channelCount: adtsChannelConfig,
|
13844
13740
|
codec: 'mp4a.40.' + adtsObjectType,
|
13845
|
-
parsedCodec: 'mp4a.40.' + originalAdtsObjectType,
|
13846
13741
|
manifestCodec: manifestCodec
|
13847
13742
|
};
|
13848
13743
|
}
|
@@ -13897,8 +13792,7 @@
|
|
13897
13792
|
track.channelCount = config.channelCount;
|
13898
13793
|
track.codec = config.codec;
|
13899
13794
|
track.manifestCodec = config.manifestCodec;
|
13900
|
-
track.
|
13901
|
-
logger.log("parsed codec:" + track.parsedCodec + ", codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount);
|
13795
|
+
logger.log("parsed codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount);
|
13902
13796
|
}
|
13903
13797
|
}
|
13904
13798
|
function getFrameDuration(samplerate) {
|
@@ -14985,7 +14879,7 @@
|
|
14985
14879
|
}
|
14986
14880
|
var _proto = SampleAesDecrypter.prototype;
|
14987
14881
|
_proto.decryptBuffer = function decryptBuffer(encryptedData) {
|
14988
|
-
return this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer
|
14882
|
+
return this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer);
|
14989
14883
|
}
|
14990
14884
|
|
14991
14885
|
// AAC - encrypt all full 16 bytes blocks starting from offset 16
|
@@ -16926,24 +16820,12 @@
|
|
16926
16820
|
inputSamples[0].dts = firstDTS;
|
16927
16821
|
inputSamples[0].pts = firstPTS;
|
16928
16822
|
} else {
|
16929
|
-
var isPTSOrderRetained = true;
|
16930
16823
|
for (var _i = 0; _i < inputSamples.length; _i++) {
|
16931
|
-
if (inputSamples[_i].dts > firstPTS
|
16824
|
+
if (inputSamples[_i].dts > firstPTS) {
|
16932
16825
|
break;
|
16933
16826
|
}
|
16934
|
-
var prevPTS = inputSamples[_i].pts;
|
16935
16827
|
inputSamples[_i].dts -= delta;
|
16936
16828
|
inputSamples[_i].pts -= delta;
|
16937
|
-
|
16938
|
-
// check to see if this sample's PTS order has changed
|
16939
|
-
// relative to the next one
|
16940
|
-
if (_i < inputSamples.length - 1) {
|
16941
|
-
var nextSamplePTS = inputSamples[_i + 1].pts;
|
16942
|
-
var currentSamplePTS = inputSamples[_i].pts;
|
16943
|
-
var currentOrder = nextSamplePTS <= currentSamplePTS;
|
16944
|
-
var prevOrder = nextSamplePTS <= prevPTS;
|
16945
|
-
isPTSOrderRetained = currentOrder == prevOrder;
|
16946
|
-
}
|
16947
16829
|
}
|
16948
16830
|
}
|
16949
16831
|
logger.log("Video: Initial PTS/DTS adjusted: " + toMsFromMpegTsClock(firstPTS, true) + "/" + toMsFromMpegTsClock(firstDTS, true) + ", delta: " + toMsFromMpegTsClock(delta, true) + " ms");
|
@@ -17226,7 +17108,7 @@
|
|
17226
17108
|
logger.warn("[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round(1000 * delta / inputTimeScale) + " ms gap.");
|
17227
17109
|
for (var j = 0; j < missing; j++) {
|
17228
17110
|
var newStamp = Math.max(nextPts, 0);
|
17229
|
-
var fillFrame = AAC.getSilentFrame(track.
|
17111
|
+
var fillFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
|
17230
17112
|
if (!fillFrame) {
|
17231
17113
|
logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
|
17232
17114
|
fillFrame = sample.unit.subarray();
|
@@ -17354,7 +17236,7 @@
|
|
17354
17236
|
// samples count of this segment's duration
|
17355
17237
|
var nbSamples = Math.ceil((endDTS - startDTS) / frameDuration);
|
17356
17238
|
// silent frame
|
17357
|
-
var silentFrame = AAC.getSilentFrame(track.
|
17239
|
+
var silentFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
|
17358
17240
|
logger.warn('[mp4-remuxer]: remux empty Audio');
|
17359
17241
|
// Can't remux if we can't generate a silent frame...
|
17360
17242
|
if (!silentFrame) {
|
@@ -17741,15 +17623,13 @@
|
|
17741
17623
|
duration = transmuxConfig.duration,
|
17742
17624
|
initSegmentData = transmuxConfig.initSegmentData;
|
17743
17625
|
var keyData = getEncryptionType(uintData, decryptdata);
|
17744
|
-
if (keyData &&
|
17626
|
+
if (keyData && keyData.method === 'AES-128') {
|
17745
17627
|
var decrypter = this.getDecrypter();
|
17746
|
-
var aesMode = getAesModeFromFullSegmentMethod(keyData.method);
|
17747
|
-
|
17748
17628
|
// Software decryption is synchronous; webCrypto is not
|
17749
17629
|
if (decrypter.isSync()) {
|
17750
17630
|
// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
|
17751
17631
|
// data is handled in the flush() call
|
17752
|
-
var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer
|
17632
|
+
var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer);
|
17753
17633
|
// For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
|
17754
17634
|
var loadingParts = chunkMeta.part > -1;
|
17755
17635
|
if (loadingParts) {
|
@@ -17761,7 +17641,7 @@
|
|
17761
17641
|
}
|
17762
17642
|
uintData = new Uint8Array(decryptedData);
|
17763
17643
|
} else {
|
17764
|
-
this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer
|
17644
|
+
this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer).then(function (decryptedData) {
|
17765
17645
|
// Calling push here is important; if flush() is called while this is still resolving, this ensures that
|
17766
17646
|
// the decrypted data has been transmuxed
|
17767
17647
|
var result = _this.push(decryptedData, null, chunkMeta);
|
@@ -18382,7 +18262,7 @@
|
|
18382
18262
|
observer.on(Events.ERROR, forwardMessage);
|
18383
18263
|
|
18384
18264
|
// forward logger events to main thread
|
18385
|
-
var forwardWorkerLogs = function forwardWorkerLogs(
|
18265
|
+
var forwardWorkerLogs = function forwardWorkerLogs() {
|
18386
18266
|
var _loop = function _loop(logFn) {
|
18387
18267
|
var func = function func(message) {
|
18388
18268
|
forwardMessage('workerLog', {
|
@@ -18403,8 +18283,8 @@
|
|
18403
18283
|
{
|
18404
18284
|
var config = JSON.parse(data.config);
|
18405
18285
|
self.transmuxer = new Transmuxer(observer, data.typeSupported, config, data.vendor, data.id);
|
18406
|
-
|
18407
|
-
forwardWorkerLogs(
|
18286
|
+
enableLogs(config.debug, data.id);
|
18287
|
+
forwardWorkerLogs();
|
18408
18288
|
forwardMessage('init', null);
|
18409
18289
|
break;
|
18410
18290
|
}
|
@@ -18578,7 +18458,16 @@
|
|
18578
18458
|
this.observer = new EventEmitter();
|
18579
18459
|
this.observer.on(Events.FRAG_DECRYPTED, forwardMessage);
|
18580
18460
|
this.observer.on(Events.ERROR, forwardMessage);
|
18581
|
-
var
|
18461
|
+
var MediaSource = getMediaSource(config.preferManagedMediaSource) || {
|
18462
|
+
isTypeSupported: function isTypeSupported() {
|
18463
|
+
return false;
|
18464
|
+
}
|
18465
|
+
};
|
18466
|
+
var m2tsTypeSupported = {
|
18467
|
+
mpeg: MediaSource.isTypeSupported('audio/mpeg'),
|
18468
|
+
mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'),
|
18469
|
+
ac3: false
|
18470
|
+
};
|
18582
18471
|
|
18583
18472
|
// navigator.vendor is not always available in Web Worker
|
18584
18473
|
// refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
|
@@ -18835,26 +18724,21 @@
|
|
18835
18724
|
var MAX_START_GAP_JUMP = 2.0;
|
18836
18725
|
var SKIP_BUFFER_HOLE_STEP_SECONDS = 0.1;
|
18837
18726
|
var SKIP_BUFFER_RANGE_START = 0.05;
|
18838
|
-
var GapController = /*#__PURE__*/function (
|
18839
|
-
_inheritsLoose(GapController, _Logger);
|
18727
|
+
var GapController = /*#__PURE__*/function () {
|
18840
18728
|
function GapController(config, media, fragmentTracker, hls) {
|
18841
|
-
|
18842
|
-
|
18843
|
-
|
18844
|
-
|
18845
|
-
|
18846
|
-
|
18847
|
-
|
18848
|
-
|
18849
|
-
|
18850
|
-
|
18851
|
-
|
18852
|
-
|
18853
|
-
|
18854
|
-
_this.media = media;
|
18855
|
-
_this.fragmentTracker = fragmentTracker;
|
18856
|
-
_this.hls = hls;
|
18857
|
-
return _this;
|
18729
|
+
this.config = void 0;
|
18730
|
+
this.media = null;
|
18731
|
+
this.fragmentTracker = void 0;
|
18732
|
+
this.hls = void 0;
|
18733
|
+
this.nudgeRetry = 0;
|
18734
|
+
this.stallReported = false;
|
18735
|
+
this.stalled = null;
|
18736
|
+
this.moved = false;
|
18737
|
+
this.seeking = false;
|
18738
|
+
this.config = config;
|
18739
|
+
this.media = media;
|
18740
|
+
this.fragmentTracker = fragmentTracker;
|
18741
|
+
this.hls = hls;
|
18858
18742
|
}
|
18859
18743
|
var _proto = GapController.prototype;
|
18860
18744
|
_proto.destroy = function destroy() {
|
@@ -18869,7 +18753,7 @@
|
|
18869
18753
|
*
|
18870
18754
|
* @param lastCurrentTime - Previously read playhead position
|
18871
18755
|
*/;
|
18872
|
-
_proto.poll = function poll(lastCurrentTime, activeFrag
|
18756
|
+
_proto.poll = function poll(lastCurrentTime, activeFrag) {
|
18873
18757
|
var config = this.config,
|
18874
18758
|
media = this.media,
|
18875
18759
|
stalled = this.stalled;
|
@@ -18884,7 +18768,6 @@
|
|
18884
18768
|
|
18885
18769
|
// The playhead is moving, no-op
|
18886
18770
|
if (currentTime !== lastCurrentTime) {
|
18887
|
-
this.ended = 0;
|
18888
18771
|
this.moved = true;
|
18889
18772
|
if (!seeking) {
|
18890
18773
|
this.nudgeRetry = 0;
|
@@ -18893,7 +18776,7 @@
|
|
18893
18776
|
// The playhead is now moving, but was previously stalled
|
18894
18777
|
if (this.stallReported) {
|
18895
18778
|
var _stalledDuration = self.performance.now() - stalled;
|
18896
|
-
|
18779
|
+
logger.warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms");
|
18897
18780
|
this.stallReported = false;
|
18898
18781
|
}
|
18899
18782
|
this.stalled = null;
|
@@ -18929,6 +18812,7 @@
|
|
18929
18812
|
// Skip start gaps if we haven't played, but the last poll detected the start of a stall
|
18930
18813
|
// The addition poll gives the browser a chance to jump the gap for us
|
18931
18814
|
if (!this.moved && this.stalled !== null) {
|
18815
|
+
var _level$details;
|
18932
18816
|
// There is no playable buffer (seeked, waiting for buffer)
|
18933
18817
|
var isBuffered = bufferInfo.len > 0;
|
18934
18818
|
if (!isBuffered && !nextStart) {
|
@@ -18940,8 +18824,9 @@
|
|
18940
18824
|
// When joining a live stream with audio tracks, account for live playlist window sliding by allowing
|
18941
18825
|
// a larger jump over start gaps caused by the audio-stream-controller buffering a start fragment
|
18942
18826
|
// that begins over 1 target duration after the video start position.
|
18943
|
-
var
|
18944
|
-
var
|
18827
|
+
var level = this.hls.levels ? this.hls.levels[this.hls.currentLevel] : null;
|
18828
|
+
var isLive = level == null ? void 0 : (_level$details = level.details) == null ? void 0 : _level$details.live;
|
18829
|
+
var maxStartGapJump = isLive ? level.details.targetduration * 2 : MAX_START_GAP_JUMP;
|
18945
18830
|
var partialOrGap = this.fragmentTracker.getPartialFragment(currentTime);
|
18946
18831
|
if (startJump > 0 && (startJump <= maxStartGapJump || partialOrGap)) {
|
18947
18832
|
if (!media.paused) {
|
@@ -18959,17 +18844,6 @@
|
|
18959
18844
|
}
|
18960
18845
|
var stalledDuration = tnow - stalled;
|
18961
18846
|
if (!seeking && stalledDuration >= STALL_MINIMUM_DURATION_MS) {
|
18962
|
-
// Dispatch MEDIA_ENDED when media.ended/ended event is not signalled at end of stream
|
18963
|
-
if (state === State.ENDED && !(levelDetails && levelDetails.live) && Math.abs(currentTime - ((levelDetails == null ? void 0 : levelDetails.edge) || 0)) < 1) {
|
18964
|
-
if (stalledDuration < 1000 || this.ended) {
|
18965
|
-
return;
|
18966
|
-
}
|
18967
|
-
this.ended = currentTime;
|
18968
|
-
this.hls.trigger(Events.MEDIA_ENDED, {
|
18969
|
-
stalled: true
|
18970
|
-
});
|
18971
|
-
return;
|
18972
|
-
}
|
18973
18847
|
// Report stalling after trying to fix
|
18974
18848
|
this._reportStall(bufferInfo);
|
18975
18849
|
if (!this.media) {
|
@@ -19011,7 +18885,7 @@
|
|
19011
18885
|
// needs to cross some sort of threshold covering all source-buffers content
|
19012
18886
|
// to start playing properly.
|
19013
18887
|
if ((bufferInfo.len > config.maxBufferHole || bufferInfo.nextStart && bufferInfo.nextStart - currentTime < config.maxBufferHole) && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) {
|
19014
|
-
|
18888
|
+
logger.warn('Trying to nudge playhead over buffer-hole');
|
19015
18889
|
// Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds
|
19016
18890
|
// We only try to jump the hole if it's under the configured size
|
19017
18891
|
// Reset stalled so to rearm watchdog timer
|
@@ -19033,7 +18907,7 @@
|
|
19033
18907
|
// Report stalled error once
|
19034
18908
|
this.stallReported = true;
|
19035
18909
|
var error = new Error("Playback stalling at @" + media.currentTime + " due to low buffer (" + JSON.stringify(bufferInfo) + ")");
|
19036
|
-
|
18910
|
+
logger.warn(error.message);
|
19037
18911
|
hls.trigger(Events.ERROR, {
|
19038
18912
|
type: ErrorTypes.MEDIA_ERROR,
|
19039
18913
|
details: ErrorDetails.BUFFER_STALLED_ERROR,
|
@@ -19097,7 +18971,7 @@
|
|
19097
18971
|
}
|
19098
18972
|
}
|
19099
18973
|
var targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS);
|
19100
|
-
|
18974
|
+
logger.warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime);
|
19101
18975
|
this.moved = true;
|
19102
18976
|
this.stalled = null;
|
19103
18977
|
media.currentTime = targetTime;
|
@@ -19136,7 +19010,7 @@
|
|
19136
19010
|
var targetTime = currentTime + (nudgeRetry + 1) * config.nudgeOffset;
|
19137
19011
|
// playback stalled in buffered area ... let's nudge currentTime to try to overcome this
|
19138
19012
|
var error = new Error("Nudging 'currentTime' from " + currentTime + " to " + targetTime);
|
19139
|
-
|
19013
|
+
logger.warn(error.message);
|
19140
19014
|
media.currentTime = targetTime;
|
19141
19015
|
hls.trigger(Events.ERROR, {
|
19142
19016
|
type: ErrorTypes.MEDIA_ERROR,
|
@@ -19146,7 +19020,7 @@
|
|
19146
19020
|
});
|
19147
19021
|
} else {
|
19148
19022
|
var _error = new Error("Playhead still not moving while enough data buffered @" + currentTime + " after " + config.nudgeMaxRetry + " nudges");
|
19149
|
-
|
19023
|
+
logger.error(_error.message);
|
19150
19024
|
hls.trigger(Events.ERROR, {
|
19151
19025
|
type: ErrorTypes.MEDIA_ERROR,
|
19152
19026
|
details: ErrorDetails.BUFFER_STALLED_ERROR,
|
@@ -19156,14 +19030,14 @@
|
|
19156
19030
|
}
|
19157
19031
|
};
|
19158
19032
|
return GapController;
|
19159
|
-
}(
|
19033
|
+
}();
|
19160
19034
|
|
19161
19035
|
var TICK_INTERVAL = 100; // how often to tick in ms
|
19162
19036
|
var StreamController = /*#__PURE__*/function (_BaseStreamController) {
|
19163
19037
|
_inheritsLoose(StreamController, _BaseStreamController);
|
19164
19038
|
function StreamController(hls, fragmentTracker, keyLoader) {
|
19165
19039
|
var _this;
|
19166
|
-
_this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, 'stream-controller', PlaylistLevelType.MAIN) || this;
|
19040
|
+
_this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[stream-controller]', PlaylistLevelType.MAIN) || this;
|
19167
19041
|
_this.audioCodecSwap = false;
|
19168
19042
|
_this.gapController = null;
|
19169
19043
|
_this.level = -1;
|
@@ -19171,43 +19045,27 @@
|
|
19171
19045
|
_this.altAudio = false;
|
19172
19046
|
_this.audioOnly = false;
|
19173
19047
|
_this.fragPlaying = null;
|
19048
|
+
_this.onvplaying = null;
|
19049
|
+
_this.onvseeked = null;
|
19174
19050
|
_this.fragLastKbps = 0;
|
19175
19051
|
_this.couldBacktrack = false;
|
19176
19052
|
_this.backtrackFragment = null;
|
19177
19053
|
_this.audioCodecSwitch = false;
|
19178
19054
|
_this.videoBuffer = null;
|
19179
|
-
_this.
|
19180
|
-
// tick to speed up FRAG_CHANGED triggering
|
19181
|
-
_this.tick();
|
19182
|
-
};
|
19183
|
-
_this.onMediaSeeked = function () {
|
19184
|
-
var media = _this.media;
|
19185
|
-
var currentTime = media ? media.currentTime : null;
|
19186
|
-
if (isFiniteNumber(currentTime)) {
|
19187
|
-
_this.log("Media seeked to " + currentTime.toFixed(3));
|
19188
|
-
}
|
19189
|
-
|
19190
|
-
// If seeked was issued before buffer was appended do not tick immediately
|
19191
|
-
var bufferInfo = _this.getMainFwdBufferInfo();
|
19192
|
-
if (bufferInfo === null || bufferInfo.len === 0) {
|
19193
|
-
_this.warn("Main forward buffer length on \"seeked\" event " + (bufferInfo ? bufferInfo.len : 'empty') + ")");
|
19194
|
-
return;
|
19195
|
-
}
|
19196
|
-
|
19197
|
-
// tick to speed up FRAG_CHANGED triggering
|
19198
|
-
_this.tick();
|
19199
|
-
};
|
19200
|
-
_this.registerListeners();
|
19055
|
+
_this._registerListeners();
|
19201
19056
|
return _this;
|
19202
19057
|
}
|
19203
19058
|
var _proto = StreamController.prototype;
|
19204
|
-
_proto.
|
19205
|
-
_BaseStreamController.prototype.registerListeners.call(this);
|
19059
|
+
_proto._registerListeners = function _registerListeners() {
|
19206
19060
|
var hls = this.hls;
|
19061
|
+
hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
19062
|
+
hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
19063
|
+
hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
19207
19064
|
hls.on(Events.MANIFEST_PARSED, this.onManifestParsed, this);
|
19208
19065
|
hls.on(Events.LEVEL_LOADING, this.onLevelLoading, this);
|
19209
19066
|
hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
19210
19067
|
hls.on(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
|
19068
|
+
hls.on(Events.ERROR, this.onError, this);
|
19211
19069
|
hls.on(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
|
19212
19070
|
hls.on(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
|
19213
19071
|
hls.on(Events.BUFFER_CREATED, this.onBufferCreated, this);
|
@@ -19215,12 +19073,15 @@
|
|
19215
19073
|
hls.on(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
|
19216
19074
|
hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
19217
19075
|
};
|
19218
|
-
_proto.
|
19219
|
-
_BaseStreamController.prototype.unregisterListeners.call(this);
|
19076
|
+
_proto._unregisterListeners = function _unregisterListeners() {
|
19220
19077
|
var hls = this.hls;
|
19078
|
+
hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
19079
|
+
hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
19080
|
+
hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
19221
19081
|
hls.off(Events.MANIFEST_PARSED, this.onManifestParsed, this);
|
19222
19082
|
hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
19223
19083
|
hls.off(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
|
19084
|
+
hls.off(Events.ERROR, this.onError, this);
|
19224
19085
|
hls.off(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
|
19225
19086
|
hls.off(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
|
19226
19087
|
hls.off(Events.BUFFER_CREATED, this.onBufferCreated, this);
|
@@ -19229,9 +19090,7 @@
|
|
19229
19090
|
hls.off(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
19230
19091
|
};
|
19231
19092
|
_proto.onHandlerDestroying = function onHandlerDestroying() {
|
19232
|
-
|
19233
|
-
this.onMediaPlaying = this.onMediaSeeked = null;
|
19234
|
-
this.unregisterListeners();
|
19093
|
+
this._unregisterListeners();
|
19235
19094
|
_BaseStreamController.prototype.onHandlerDestroying.call(this);
|
19236
19095
|
};
|
19237
19096
|
_proto.startLoad = function startLoad(startPosition) {
|
@@ -19546,15 +19405,18 @@
|
|
19546
19405
|
_proto.onMediaAttached = function onMediaAttached(event, data) {
|
19547
19406
|
_BaseStreamController.prototype.onMediaAttached.call(this, event, data);
|
19548
19407
|
var media = data.media;
|
19549
|
-
|
19550
|
-
|
19408
|
+
this.onvplaying = this.onMediaPlaying.bind(this);
|
19409
|
+
this.onvseeked = this.onMediaSeeked.bind(this);
|
19410
|
+
media.addEventListener('playing', this.onvplaying);
|
19411
|
+
media.addEventListener('seeked', this.onvseeked);
|
19551
19412
|
this.gapController = new GapController(this.config, media, this.fragmentTracker, this.hls);
|
19552
19413
|
};
|
19553
19414
|
_proto.onMediaDetaching = function onMediaDetaching() {
|
19554
19415
|
var media = this.media;
|
19555
|
-
if (media) {
|
19556
|
-
media.removeEventListener('playing', this.
|
19557
|
-
media.removeEventListener('seeked', this.
|
19416
|
+
if (media && this.onvplaying && this.onvseeked) {
|
19417
|
+
media.removeEventListener('playing', this.onvplaying);
|
19418
|
+
media.removeEventListener('seeked', this.onvseeked);
|
19419
|
+
this.onvplaying = this.onvseeked = null;
|
19558
19420
|
this.videoBuffer = null;
|
19559
19421
|
}
|
19560
19422
|
this.fragPlaying = null;
|
@@ -19564,6 +19426,27 @@
|
|
19564
19426
|
}
|
19565
19427
|
_BaseStreamController.prototype.onMediaDetaching.call(this);
|
19566
19428
|
};
|
19429
|
+
_proto.onMediaPlaying = function onMediaPlaying() {
|
19430
|
+
// tick to speed up FRAG_CHANGED triggering
|
19431
|
+
this.tick();
|
19432
|
+
};
|
19433
|
+
_proto.onMediaSeeked = function onMediaSeeked() {
|
19434
|
+
var media = this.media;
|
19435
|
+
var currentTime = media ? media.currentTime : null;
|
19436
|
+
if (isFiniteNumber(currentTime)) {
|
19437
|
+
this.log("Media seeked to " + currentTime.toFixed(3));
|
19438
|
+
}
|
19439
|
+
|
19440
|
+
// If seeked was issued before buffer was appended do not tick immediately
|
19441
|
+
var bufferInfo = this.getMainFwdBufferInfo();
|
19442
|
+
if (bufferInfo === null || bufferInfo.len === 0) {
|
19443
|
+
this.warn("Main forward buffer length on \"seeked\" event " + (bufferInfo ? bufferInfo.len : 'empty') + ")");
|
19444
|
+
return;
|
19445
|
+
}
|
19446
|
+
|
19447
|
+
// tick to speed up FRAG_CHANGED triggering
|
19448
|
+
this.tick();
|
19449
|
+
};
|
19567
19450
|
_proto.onManifestLoading = function onManifestLoading() {
|
19568
19451
|
// reset buffer on manifest loading
|
19569
19452
|
this.log('Trigger BUFFER_RESET');
|
@@ -19844,10 +19727,8 @@
|
|
19844
19727
|
}
|
19845
19728
|
if (this.loadedmetadata || !BufferHelper.getBuffered(media).length) {
|
19846
19729
|
// Resolve gaps using the main buffer, whose ranges are the intersections of the A/V sourcebuffers
|
19847
|
-
var
|
19848
|
-
|
19849
|
-
var levelDetails = this.getLevelDetails();
|
19850
|
-
gapController.poll(this.lastCurrentTime, activeFrag, levelDetails, state);
|
19730
|
+
var activeFrag = this.state !== State.IDLE ? this.fragCurrent : null;
|
19731
|
+
gapController.poll(this.lastCurrentTime, activeFrag);
|
19851
19732
|
}
|
19852
19733
|
this.lastCurrentTime = media.currentTime;
|
19853
19734
|
};
|
@@ -20312,10 +20193,6 @@
|
|
20312
20193
|
* The configuration object provided on player instantiation.
|
20313
20194
|
*/
|
20314
20195
|
this.userConfig = void 0;
|
20315
|
-
/**
|
20316
|
-
* The logger functions used by this player instance, configured on player instantiation.
|
20317
|
-
*/
|
20318
|
-
this.logger = void 0;
|
20319
20196
|
this.coreComponents = void 0;
|
20320
20197
|
this.networkControllers = void 0;
|
20321
20198
|
this.started = false;
|
@@ -20335,11 +20212,11 @@
|
|
20335
20212
|
this._media = null;
|
20336
20213
|
this.url = null;
|
20337
20214
|
this.triggeringException = void 0;
|
20338
|
-
|
20339
|
-
var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig
|
20215
|
+
enableLogs(userConfig.debug || false, 'Hls instance');
|
20216
|
+
var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig);
|
20340
20217
|
this.userConfig = userConfig;
|
20341
20218
|
if (config.progressive) {
|
20342
|
-
enableStreamingMode(config
|
20219
|
+
enableStreamingMode(config);
|
20343
20220
|
}
|
20344
20221
|
|
20345
20222
|
// core controllers and network loaders
|
@@ -20447,7 +20324,7 @@
|
|
20447
20324
|
try {
|
20448
20325
|
return this.emit(event, event, eventObject);
|
20449
20326
|
} catch (error) {
|
20450
|
-
|
20327
|
+
logger.error('An internal error happened while handling event ' + event + '. Error message: "' + error.message + '". Here is a stacktrace:', error);
|
20451
20328
|
// Prevent recursion in error event handlers that throw #5497
|
20452
20329
|
if (!this.triggeringException) {
|
20453
20330
|
this.triggeringException = true;
|
@@ -20473,7 +20350,7 @@
|
|
20473
20350
|
* Dispose of the instance
|
20474
20351
|
*/;
|
20475
20352
|
_proto.destroy = function destroy() {
|
20476
|
-
|
20353
|
+
logger.log('destroy');
|
20477
20354
|
this.trigger(Events.DESTROYING, undefined);
|
20478
20355
|
this.detachMedia();
|
20479
20356
|
this.removeAllListeners();
|
@@ -20498,7 +20375,7 @@
|
|
20498
20375
|
* Attaches Hls.js to a media element
|
20499
20376
|
*/;
|
20500
20377
|
_proto.attachMedia = function attachMedia(media) {
|
20501
|
-
|
20378
|
+
logger.log('attachMedia');
|
20502
20379
|
this._media = media;
|
20503
20380
|
this.trigger(Events.MEDIA_ATTACHING, {
|
20504
20381
|
media: media
|
@@ -20509,7 +20386,7 @@
|
|
20509
20386
|
* Detach Hls.js from the media
|
20510
20387
|
*/;
|
20511
20388
|
_proto.detachMedia = function detachMedia() {
|
20512
|
-
|
20389
|
+
logger.log('detachMedia');
|
20513
20390
|
this.trigger(Events.MEDIA_DETACHING, undefined);
|
20514
20391
|
this._media = null;
|
20515
20392
|
}
|
@@ -20526,7 +20403,7 @@
|
|
20526
20403
|
});
|
20527
20404
|
this._autoLevelCapping = -1;
|
20528
20405
|
this._maxHdcpLevel = null;
|
20529
|
-
|
20406
|
+
logger.log("loadSource:" + loadingSource);
|
20530
20407
|
if (media && loadedSource && (loadedSource !== loadingSource || this.bufferController.hasSourceTypes())) {
|
20531
20408
|
this.detachMedia();
|
20532
20409
|
this.attachMedia(media);
|
@@ -20548,7 +20425,7 @@
|
|
20548
20425
|
if (startPosition === void 0) {
|
20549
20426
|
startPosition = -1;
|
20550
20427
|
}
|
20551
|
-
|
20428
|
+
logger.log("startLoad(" + startPosition + ")");
|
20552
20429
|
this.started = true;
|
20553
20430
|
this.networkControllers.forEach(function (controller) {
|
20554
20431
|
controller.startLoad(startPosition);
|
@@ -20559,7 +20436,7 @@
|
|
20559
20436
|
* Stop loading of any stream data.
|
20560
20437
|
*/;
|
20561
20438
|
_proto.stopLoad = function stopLoad() {
|
20562
|
-
|
20439
|
+
logger.log('stopLoad');
|
20563
20440
|
this.started = false;
|
20564
20441
|
this.networkControllers.forEach(function (controller) {
|
20565
20442
|
controller.stopLoad();
|
@@ -20595,7 +20472,7 @@
|
|
20595
20472
|
* Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1)
|
20596
20473
|
*/;
|
20597
20474
|
_proto.swapAudioCodec = function swapAudioCodec() {
|
20598
|
-
|
20475
|
+
logger.log('swapAudioCodec');
|
20599
20476
|
this.streamController.swapAudioCodec();
|
20600
20477
|
}
|
20601
20478
|
|
@@ -20606,7 +20483,7 @@
|
|
20606
20483
|
* Automatic recovery of media-errors by this process is configurable.
|
20607
20484
|
*/;
|
20608
20485
|
_proto.recoverMediaError = function recoverMediaError() {
|
20609
|
-
|
20486
|
+
logger.log('recoverMediaError');
|
20610
20487
|
var media = this._media;
|
20611
20488
|
this.detachMedia();
|
20612
20489
|
if (media) {
|
@@ -20661,7 +20538,7 @@
|
|
20661
20538
|
* 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.
|
20662
20539
|
*/,
|
20663
20540
|
set: function set(newLevel) {
|
20664
|
-
|
20541
|
+
logger.log("set currentLevel:" + newLevel);
|
20665
20542
|
this.levelController.manualLevel = newLevel;
|
20666
20543
|
this.streamController.immediateLevelSwitch();
|
20667
20544
|
}
|
@@ -20682,7 +20559,7 @@
|
|
20682
20559
|
* @param newLevel - Pass -1 for automatic level selection
|
20683
20560
|
*/,
|
20684
20561
|
set: function set(newLevel) {
|
20685
|
-
|
20562
|
+
logger.log("set nextLevel:" + newLevel);
|
20686
20563
|
this.levelController.manualLevel = newLevel;
|
20687
20564
|
this.streamController.nextLevelSwitch();
|
20688
20565
|
}
|
@@ -20703,7 +20580,7 @@
|
|
20703
20580
|
* @param newLevel - Pass -1 for automatic level selection
|
20704
20581
|
*/,
|
20705
20582
|
set: function set(newLevel) {
|
20706
|
-
|
20583
|
+
logger.log("set loadLevel:" + newLevel);
|
20707
20584
|
this.levelController.manualLevel = newLevel;
|
20708
20585
|
}
|
20709
20586
|
|
@@ -20738,7 +20615,7 @@
|
|
20738
20615
|
* Sets "first-level", see getter.
|
20739
20616
|
*/,
|
20740
20617
|
set: function set(newLevel) {
|
20741
|
-
|
20618
|
+
logger.log("set firstLevel:" + newLevel);
|
20742
20619
|
this.levelController.firstLevel = newLevel;
|
20743
20620
|
}
|
20744
20621
|
|
@@ -20765,7 +20642,7 @@
|
|
20765
20642
|
* (determined from download of first segment)
|
20766
20643
|
*/,
|
20767
20644
|
set: function set(newLevel) {
|
20768
|
-
|
20645
|
+
logger.log("set startLevel:" + newLevel);
|
20769
20646
|
// if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
|
20770
20647
|
if (newLevel !== -1) {
|
20771
20648
|
newLevel = Math.max(newLevel, this.minAutoLevel);
|
@@ -20818,7 +20695,7 @@
|
|
20818
20695
|
*/
|
20819
20696
|
function set(newLevel) {
|
20820
20697
|
if (this._autoLevelCapping !== newLevel) {
|
20821
|
-
|
20698
|
+
logger.log("set autoLevelCapping:" + newLevel);
|
20822
20699
|
this._autoLevelCapping = newLevel;
|
20823
20700
|
this.levelController.checkMaxAutoUpdated();
|
20824
20701
|
}
|
@@ -21143,7 +21020,7 @@
|
|
21143
21020
|
* Get the video-dev/hls.js package version.
|
21144
21021
|
*/
|
21145
21022
|
function get() {
|
21146
|
-
return "1.5.
|
21023
|
+
return "1.5.3";
|
21147
21024
|
}
|
21148
21025
|
}, {
|
21149
21026
|
key: "Events",
|