hls.js 1.5.2-0.canary.9924 → 1.5.2
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 +686 -762
- package/dist/hls.js.d.ts +47 -49
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +471 -563
- 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 +329 -409
- 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 +500 -559
- 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 +9 -9
- package/src/config.ts +2 -3
- package/src/controller/abr-controller.ts +22 -23
- 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 -42
- package/src/controller/buffer-controller.ts +11 -10
- package/src/controller/cap-level-controller.ts +2 -1
- 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 +10 -16
- package/src/controller/latency-controller.ts +11 -9
- package/src/controller/level-controller.ts +19 -8
- package/src/controller/stream-controller.ts +29 -20
- 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/hls.ts +20 -32
- 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 +3 -4
- package/src/task-loop.ts +2 -5
- package/src/types/demuxer.ts +0 -1
- 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
@@ -476,21 +476,6 @@
|
|
476
476
|
return ErrorDetails;
|
477
477
|
}({});
|
478
478
|
|
479
|
-
var Logger = function Logger(label, logger) {
|
480
|
-
this.trace = void 0;
|
481
|
-
this.debug = void 0;
|
482
|
-
this.log = void 0;
|
483
|
-
this.warn = void 0;
|
484
|
-
this.info = void 0;
|
485
|
-
this.error = void 0;
|
486
|
-
var lb = "[" + label + "]:";
|
487
|
-
this.trace = noop;
|
488
|
-
this.debug = logger.debug.bind(null, lb);
|
489
|
-
this.log = logger.log.bind(null, lb);
|
490
|
-
this.warn = logger.warn.bind(null, lb);
|
491
|
-
this.info = logger.info.bind(null, lb);
|
492
|
-
this.error = logger.error.bind(null, lb);
|
493
|
-
};
|
494
479
|
var noop = function noop() {};
|
495
480
|
var fakeLogger = {
|
496
481
|
trace: noop,
|
@@ -500,9 +485,7 @@
|
|
500
485
|
info: noop,
|
501
486
|
error: noop
|
502
487
|
};
|
503
|
-
|
504
|
-
return _extends({}, fakeLogger);
|
505
|
-
}
|
488
|
+
var exportedLogger = fakeLogger;
|
506
489
|
|
507
490
|
// let lastCallTime;
|
508
491
|
// function formatMsgWithTimeInfo(type, msg) {
|
@@ -513,36 +496,38 @@
|
|
513
496
|
// return msg;
|
514
497
|
// }
|
515
498
|
|
516
|
-
function consolePrintFn(type
|
499
|
+
function consolePrintFn(type) {
|
517
500
|
var func = self.console[type];
|
518
|
-
|
501
|
+
if (func) {
|
502
|
+
return func.bind(self.console, "[" + type + "] >");
|
503
|
+
}
|
504
|
+
return noop;
|
519
505
|
}
|
520
|
-
function
|
521
|
-
|
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
|
+
});
|
522
513
|
}
|
523
|
-
|
524
|
-
function enableLogs(debugConfig, context, id) {
|
514
|
+
function enableLogs(debugConfig, id) {
|
525
515
|
// check that console is available
|
526
|
-
var newLogger = createLogger();
|
527
516
|
if (typeof console === 'object' && debugConfig === true || typeof debugConfig === 'object') {
|
528
|
-
|
517
|
+
exportLoggerFunctions(debugConfig,
|
529
518
|
// Remove out from list here to hard-disable a log-level
|
530
519
|
// 'trace',
|
531
|
-
'debug', 'log', 'info', 'warn', 'error'
|
532
|
-
keys.forEach(function (key) {
|
533
|
-
newLogger[key] = getLoggerFn(key, debugConfig, id);
|
534
|
-
});
|
520
|
+
'debug', 'log', 'info', 'warn', 'error');
|
535
521
|
// Some browsers don't allow to use bind on console object anyway
|
536
522
|
// fallback to default if needed
|
537
523
|
try {
|
538
|
-
|
524
|
+
exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.5.2");
|
539
525
|
} catch (e) {
|
540
|
-
|
541
|
-
return createLogger();
|
526
|
+
exportedLogger = fakeLogger;
|
542
527
|
}
|
528
|
+
} else {
|
529
|
+
exportedLogger = fakeLogger;
|
543
530
|
}
|
544
|
-
exportedLogger = newLogger;
|
545
|
-
return newLogger;
|
546
531
|
}
|
547
532
|
var logger = exportedLogger;
|
548
533
|
|
@@ -1188,26 +1173,6 @@
|
|
1188
1173
|
return LevelDetails;
|
1189
1174
|
}();
|
1190
1175
|
|
1191
|
-
var DecrypterAesMode = {
|
1192
|
-
cbc: 0,
|
1193
|
-
ctr: 1
|
1194
|
-
};
|
1195
|
-
|
1196
|
-
function isFullSegmentEncryption(method) {
|
1197
|
-
return method === 'AES-128' || method === 'AES-256' || method === 'AES-256-CTR';
|
1198
|
-
}
|
1199
|
-
function getAesModeFromFullSegmentMethod(method) {
|
1200
|
-
switch (method) {
|
1201
|
-
case 'AES-128':
|
1202
|
-
case 'AES-256':
|
1203
|
-
return DecrypterAesMode.cbc;
|
1204
|
-
case 'AES-256-CTR':
|
1205
|
-
return DecrypterAesMode.ctr;
|
1206
|
-
default:
|
1207
|
-
throw new Error("invalid full segment method " + method);
|
1208
|
-
}
|
1209
|
-
}
|
1210
|
-
|
1211
1176
|
// This file is inserted as a shim for modules which we do not want to include into the distro.
|
1212
1177
|
// This replacement is done in the "alias" plugin of the rollup config.
|
1213
1178
|
var empty = undefined;
|
@@ -2649,13 +2614,13 @@
|
|
2649
2614
|
this.keyFormatVersions = formatversions;
|
2650
2615
|
this.iv = iv;
|
2651
2616
|
this.encrypted = method ? method !== 'NONE' : false;
|
2652
|
-
this.isCommonEncryption = this.encrypted &&
|
2617
|
+
this.isCommonEncryption = this.encrypted && method !== 'AES-128';
|
2653
2618
|
}
|
2654
2619
|
var _proto = LevelKey.prototype;
|
2655
2620
|
_proto.isSupported = function isSupported() {
|
2656
2621
|
// If it's Segment encryption or No encryption, just select that key system
|
2657
2622
|
if (this.method) {
|
2658
|
-
if (
|
2623
|
+
if (this.method === 'AES-128' || this.method === 'NONE') {
|
2659
2624
|
return true;
|
2660
2625
|
}
|
2661
2626
|
if (this.keyFormat === 'identity') {
|
@@ -2669,13 +2634,14 @@
|
|
2669
2634
|
if (!this.encrypted || !this.uri) {
|
2670
2635
|
return null;
|
2671
2636
|
}
|
2672
|
-
if (
|
2637
|
+
if (this.method === 'AES-128' && this.uri && !this.iv) {
|
2673
2638
|
if (typeof sn !== 'number') {
|
2674
2639
|
// We are fetching decryption data for a initialization segment
|
2675
|
-
// If the segment was encrypted with AES-128
|
2640
|
+
// If the segment was encrypted with AES-128
|
2676
2641
|
// It must have an IV defined. We cannot substitute the Segment Number in.
|
2677
|
-
|
2678
|
-
|
2642
|
+
if (this.method === 'AES-128' && !this.iv) {
|
2643
|
+
logger.warn("missing IV for initialization segment with method=\"" + this.method + "\" - compliance issue");
|
2644
|
+
}
|
2679
2645
|
// Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
|
2680
2646
|
sn = 0;
|
2681
2647
|
}
|
@@ -2837,28 +2803,23 @@
|
|
2837
2803
|
if (CODEC_COMPATIBLE_NAMES[lowerCaseCodec]) {
|
2838
2804
|
return CODEC_COMPATIBLE_NAMES[lowerCaseCodec];
|
2839
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
|
2840
2810
|
var codecsToCheck = {
|
2841
|
-
// Idealy fLaC and Opus would be first (spec-compliant) but
|
2842
|
-
// some browsers will report that fLaC is supported then fail.
|
2843
|
-
// see: https://bugs.chromium.org/p/chromium/issues/detail?id=1422728
|
2844
2811
|
flac: ['flac', 'fLaC', 'FLAC'],
|
2845
|
-
opus: ['opus', 'Opus']
|
2846
|
-
// Replace audio codec info if browser does not support mp4a.40.34,
|
2847
|
-
// and demuxer can fallback to 'audio/mpeg' or 'audio/mp4;codecs="mp3"'
|
2848
|
-
'mp4a.40.34': ['mp3']
|
2812
|
+
opus: ['opus', 'Opus']
|
2849
2813
|
}[lowerCaseCodec];
|
2850
2814
|
for (var i = 0; i < codecsToCheck.length; i++) {
|
2851
|
-
var _getMediaSource;
|
2852
2815
|
if (isCodecMediaSourceSupported(codecsToCheck[i], 'audio', preferManagedMediaSource)) {
|
2853
2816
|
CODEC_COMPATIBLE_NAMES[lowerCaseCodec] = codecsToCheck[i];
|
2854
2817
|
return codecsToCheck[i];
|
2855
|
-
} else if (codecsToCheck[i] === 'mp3' && (_getMediaSource = getMediaSource(preferManagedMediaSource)) != null && _getMediaSource.isTypeSupported('audio/mpeg')) {
|
2856
|
-
return '';
|
2857
2818
|
}
|
2858
2819
|
}
|
2859
2820
|
return lowerCaseCodec;
|
2860
2821
|
}
|
2861
|
-
var AUDIO_CODEC_REGEXP = /flac|opus
|
2822
|
+
var AUDIO_CODEC_REGEXP = /flac|opus/i;
|
2862
2823
|
function getCodecCompatibleName(codec, preferManagedMediaSource) {
|
2863
2824
|
if (preferManagedMediaSource === void 0) {
|
2864
2825
|
preferManagedMediaSource = true;
|
@@ -2886,18 +2847,6 @@
|
|
2886
2847
|
}
|
2887
2848
|
return codec;
|
2888
2849
|
}
|
2889
|
-
function getM2TSSupportedAudioTypes(preferManagedMediaSource) {
|
2890
|
-
var MediaSource = getMediaSource(preferManagedMediaSource) || {
|
2891
|
-
isTypeSupported: function isTypeSupported() {
|
2892
|
-
return false;
|
2893
|
-
}
|
2894
|
-
};
|
2895
|
-
return {
|
2896
|
-
mpeg: MediaSource.isTypeSupported('audio/mpeg'),
|
2897
|
-
mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"'),
|
2898
|
-
ac3: false
|
2899
|
-
};
|
2900
|
-
}
|
2901
2850
|
|
2902
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;
|
2903
2852
|
var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g;
|
@@ -4472,43 +4421,8 @@
|
|
4472
4421
|
this.currentTime = 0;
|
4473
4422
|
this.stallCount = 0;
|
4474
4423
|
this._latency = null;
|
4475
|
-
this.
|
4476
|
-
|
4477
|
-
levelDetails = _this.levelDetails;
|
4478
|
-
if (!media || !levelDetails) {
|
4479
|
-
return;
|
4480
|
-
}
|
4481
|
-
_this.currentTime = media.currentTime;
|
4482
|
-
var latency = _this.computeLatency();
|
4483
|
-
if (latency === null) {
|
4484
|
-
return;
|
4485
|
-
}
|
4486
|
-
_this._latency = latency;
|
4487
|
-
|
4488
|
-
// Adapt playbackRate to meet target latency in low-latency mode
|
4489
|
-
var _this$config = _this.config,
|
4490
|
-
lowLatencyMode = _this$config.lowLatencyMode,
|
4491
|
-
maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
|
4492
|
-
if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1 || !levelDetails.live) {
|
4493
|
-
return;
|
4494
|
-
}
|
4495
|
-
var targetLatency = _this.targetLatency;
|
4496
|
-
if (targetLatency === null) {
|
4497
|
-
return;
|
4498
|
-
}
|
4499
|
-
var distanceFromTarget = latency - targetLatency;
|
4500
|
-
// Only adjust playbackRate when within one target duration of targetLatency
|
4501
|
-
// and more than one second from under-buffering.
|
4502
|
-
// Playback further than one target duration from target can be considered DVR playback.
|
4503
|
-
var liveMinLatencyDuration = Math.min(_this.maxLatency, targetLatency + levelDetails.targetduration);
|
4504
|
-
var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
|
4505
|
-
if (inLiveRange && distanceFromTarget > 0.05 && _this.forwardBufferLength > 1) {
|
4506
|
-
var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
|
4507
|
-
var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - _this.edgeStalled)) * 20) / 20;
|
4508
|
-
media.playbackRate = Math.min(max, Math.max(1, rate));
|
4509
|
-
} else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
|
4510
|
-
media.playbackRate = 1;
|
4511
|
-
}
|
4424
|
+
this.timeupdateHandler = function () {
|
4425
|
+
return _this.timeupdate();
|
4512
4426
|
};
|
4513
4427
|
this.hls = hls;
|
4514
4428
|
this.config = hls.config;
|
@@ -4520,7 +4434,7 @@
|
|
4520
4434
|
this.onMediaDetaching();
|
4521
4435
|
this.levelDetails = null;
|
4522
4436
|
// @ts-ignore
|
4523
|
-
this.hls = null;
|
4437
|
+
this.hls = this.timeupdateHandler = null;
|
4524
4438
|
};
|
4525
4439
|
_proto.registerListeners = function registerListeners() {
|
4526
4440
|
this.hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
@@ -4538,11 +4452,11 @@
|
|
4538
4452
|
};
|
4539
4453
|
_proto.onMediaAttached = function onMediaAttached(event, data) {
|
4540
4454
|
this.media = data.media;
|
4541
|
-
this.media.addEventListener('timeupdate', this.
|
4455
|
+
this.media.addEventListener('timeupdate', this.timeupdateHandler);
|
4542
4456
|
};
|
4543
4457
|
_proto.onMediaDetaching = function onMediaDetaching() {
|
4544
4458
|
if (this.media) {
|
4545
|
-
this.media.removeEventListener('timeupdate', this.
|
4459
|
+
this.media.removeEventListener('timeupdate', this.timeupdateHandler);
|
4546
4460
|
this.media = null;
|
4547
4461
|
}
|
4548
4462
|
};
|
@@ -4555,10 +4469,10 @@
|
|
4555
4469
|
var details = _ref.details;
|
4556
4470
|
this.levelDetails = details;
|
4557
4471
|
if (details.advanced) {
|
4558
|
-
this.
|
4472
|
+
this.timeupdate();
|
4559
4473
|
}
|
4560
4474
|
if (!details.live && this.media) {
|
4561
|
-
this.media.removeEventListener('timeupdate', this.
|
4475
|
+
this.media.removeEventListener('timeupdate', this.timeupdateHandler);
|
4562
4476
|
}
|
4563
4477
|
};
|
4564
4478
|
_proto.onError = function onError(event, data) {
|
@@ -4568,7 +4482,45 @@
|
|
4568
4482
|
}
|
4569
4483
|
this.stallCount++;
|
4570
4484
|
if ((_this$levelDetails = this.levelDetails) != null && _this$levelDetails.live) {
|
4571
|
-
|
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;
|
4572
4524
|
}
|
4573
4525
|
};
|
4574
4526
|
_proto.estimateLiveEdge = function estimateLiveEdge() {
|
@@ -5476,17 +5428,19 @@
|
|
5476
5428
|
MoveAllAlternatesMatchingHDCP: 2,
|
5477
5429
|
SwitchToSDR: 4
|
5478
5430
|
}; // Reserved for future use
|
5479
|
-
var ErrorController = /*#__PURE__*/function (
|
5480
|
-
_inheritsLoose(ErrorController, _Logger);
|
5431
|
+
var ErrorController = /*#__PURE__*/function () {
|
5481
5432
|
function ErrorController(hls) {
|
5482
|
-
|
5483
|
-
|
5484
|
-
|
5485
|
-
|
5486
|
-
|
5487
|
-
|
5488
|
-
|
5489
|
-
|
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();
|
5490
5444
|
}
|
5491
5445
|
var _proto = ErrorController.prototype;
|
5492
5446
|
_proto.registerListeners = function registerListeners() {
|
@@ -5842,19 +5796,19 @@
|
|
5842
5796
|
}
|
5843
5797
|
};
|
5844
5798
|
return ErrorController;
|
5845
|
-
}(
|
5799
|
+
}();
|
5846
5800
|
|
5847
|
-
var BasePlaylistController = /*#__PURE__*/function (
|
5848
|
-
_inheritsLoose(BasePlaylistController, _Logger);
|
5801
|
+
var BasePlaylistController = /*#__PURE__*/function () {
|
5849
5802
|
function BasePlaylistController(hls, logPrefix) {
|
5850
|
-
|
5851
|
-
|
5852
|
-
|
5853
|
-
|
5854
|
-
|
5855
|
-
|
5856
|
-
|
5857
|
-
|
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;
|
5858
5812
|
}
|
5859
5813
|
var _proto = BasePlaylistController.prototype;
|
5860
5814
|
_proto.destroy = function destroy() {
|
@@ -5887,7 +5841,7 @@
|
|
5887
5841
|
try {
|
5888
5842
|
uri = new self.URL(attr.URI, previous.url).href;
|
5889
5843
|
} catch (error) {
|
5890
|
-
|
5844
|
+
logger.warn("Could not construct new URL for Rendition Report: " + error);
|
5891
5845
|
uri = attr.URI || '';
|
5892
5846
|
}
|
5893
5847
|
// Use exact match. Otherwise, the last partial match, if any, will be used
|
@@ -5926,7 +5880,7 @@
|
|
5926
5880
|
return this.timer === -1 && this.requestScheduled === -1 && this.shouldLoadPlaylist(playlist);
|
5927
5881
|
};
|
5928
5882
|
_proto.playlistLoaded = function playlistLoaded(index, data, previousDetails) {
|
5929
|
-
var
|
5883
|
+
var _this = this;
|
5930
5884
|
var details = data.details,
|
5931
5885
|
stats = data.stats;
|
5932
5886
|
|
@@ -6031,7 +5985,7 @@
|
|
6031
5985
|
// );
|
6032
5986
|
|
6033
5987
|
this.timer = self.setTimeout(function () {
|
6034
|
-
return
|
5988
|
+
return _this.loadPlaylist(deliveryDirectives);
|
6035
5989
|
}, estimatedTimeUntilUpdate);
|
6036
5990
|
} else {
|
6037
5991
|
this.clearTimer();
|
@@ -6047,7 +6001,7 @@
|
|
6047
6001
|
return new HlsUrlParameters(msn, part, skip);
|
6048
6002
|
};
|
6049
6003
|
_proto.checkRetry = function checkRetry(errorEvent) {
|
6050
|
-
var
|
6004
|
+
var _this2 = this;
|
6051
6005
|
var errorDetails = errorEvent.details;
|
6052
6006
|
var isTimeout = isTimeoutError(errorEvent);
|
6053
6007
|
var errorAction = errorEvent.errorAction;
|
@@ -6071,7 +6025,7 @@
|
|
6071
6025
|
var delay = getRetryDelay(retryConfig, retryCount);
|
6072
6026
|
// Schedule level/track reload
|
6073
6027
|
this.timer = self.setTimeout(function () {
|
6074
|
-
return
|
6028
|
+
return _this2.loadPlaylist();
|
6075
6029
|
}, delay);
|
6076
6030
|
this.warn("Retrying playlist loading " + (retryCount + 1) + "/" + retryConfig.maxNumRetry + " after \"" + errorDetails + "\" in " + delay + "ms");
|
6077
6031
|
}
|
@@ -6082,7 +6036,7 @@
|
|
6082
6036
|
return retry;
|
6083
6037
|
};
|
6084
6038
|
return BasePlaylistController;
|
6085
|
-
}(
|
6039
|
+
}();
|
6086
6040
|
|
6087
6041
|
/*
|
6088
6042
|
* compute an Exponential Weighted moving average
|
@@ -6456,33 +6410,30 @@
|
|
6456
6410
|
}, {});
|
6457
6411
|
}
|
6458
6412
|
|
6459
|
-
var AbrController = /*#__PURE__*/function (
|
6460
|
-
_inheritsLoose(AbrController, _Logger);
|
6413
|
+
var AbrController = /*#__PURE__*/function () {
|
6461
6414
|
function AbrController(_hls) {
|
6462
|
-
var _this;
|
6463
|
-
|
6464
|
-
|
6465
|
-
|
6466
|
-
|
6467
|
-
|
6468
|
-
|
6469
|
-
|
6470
|
-
|
6471
|
-
|
6472
|
-
|
6473
|
-
|
6474
|
-
|
6475
|
-
|
6476
|
-
_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;
|
6477
6429
|
/*
|
6478
6430
|
This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
|
6479
6431
|
quickly enough to prevent underbuffering
|
6480
6432
|
*/
|
6481
|
-
|
6482
|
-
var
|
6483
|
-
|
6484
|
-
|
6485
|
-
hls = _assertThisInitialize.hls;
|
6433
|
+
this._abandonRulesCheck = function () {
|
6434
|
+
var frag = _this.fragCurrent,
|
6435
|
+
part = _this.partCurrent,
|
6436
|
+
hls = _this.hls;
|
6486
6437
|
var autoLevelEnabled = hls.autoLevelEnabled,
|
6487
6438
|
media = hls.media;
|
6488
6439
|
if (!frag || !media) {
|
@@ -6523,7 +6474,7 @@
|
|
6523
6474
|
var bwEstimate = _this.getBwEstimate();
|
6524
6475
|
var levels = hls.levels;
|
6525
6476
|
var level = levels[frag.level];
|
6526
|
-
var expectedLen = stats.total || Math.max(stats.loaded, Math.round(duration * level.
|
6477
|
+
var expectedLen = stats.total || Math.max(stats.loaded, Math.round(duration * level.averageBitrate / 8));
|
6527
6478
|
var timeStreaming = loadedFirstByte ? timeLoading - ttfb : timeLoading;
|
6528
6479
|
if (timeStreaming < 1 && loadedFirstByte) {
|
6529
6480
|
timeStreaming = Math.min(timeLoading, stats.loaded * 8 / bwEstimate);
|
@@ -6566,27 +6517,26 @@
|
|
6566
6517
|
// If there has been no loading progress, sample TTFB
|
6567
6518
|
_this.bwEstimator.sampleTTFB(timeLoading);
|
6568
6519
|
}
|
6569
|
-
var nextLoadLevelBitrate = levels[nextLoadLevel].
|
6520
|
+
var nextLoadLevelBitrate = levels[nextLoadLevel].maxBitrate;
|
6570
6521
|
if (_this.getBwEstimate() * _this.hls.config.abrBandWidthUpFactor > nextLoadLevelBitrate) {
|
6571
6522
|
_this.resetEstimator(nextLoadLevelBitrate);
|
6572
6523
|
}
|
6573
6524
|
_this.clearTimer();
|
6574
|
-
|
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");
|
6575
6526
|
hls.trigger(Events.FRAG_LOAD_EMERGENCY_ABORTED, {
|
6576
6527
|
frag: frag,
|
6577
6528
|
part: part,
|
6578
6529
|
stats: stats
|
6579
6530
|
});
|
6580
6531
|
};
|
6581
|
-
|
6582
|
-
|
6583
|
-
|
6584
|
-
return _this;
|
6532
|
+
this.hls = _hls;
|
6533
|
+
this.bwEstimator = this.initEstimator();
|
6534
|
+
this.registerListeners();
|
6585
6535
|
}
|
6586
6536
|
var _proto = AbrController.prototype;
|
6587
6537
|
_proto.resetEstimator = function resetEstimator(abrEwmaDefaultEstimate) {
|
6588
6538
|
if (abrEwmaDefaultEstimate) {
|
6589
|
-
|
6539
|
+
logger.log("setting initial bwe to " + abrEwmaDefaultEstimate);
|
6590
6540
|
this.hls.config.abrEwmaDefaultEstimate = abrEwmaDefaultEstimate;
|
6591
6541
|
}
|
6592
6542
|
this.firstSelection = -1;
|
@@ -6838,13 +6788,13 @@
|
|
6838
6788
|
// cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
|
6839
6789
|
var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay;
|
6840
6790
|
maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
|
6841
|
-
|
6791
|
+
logger.info("[abr] bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms");
|
6842
6792
|
// don't use conservative factor on bitrate test
|
6843
6793
|
bwFactor = bwUpFactor = 1;
|
6844
6794
|
}
|
6845
6795
|
}
|
6846
6796
|
var bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, maxStarvationDelay, bwFactor, bwUpFactor);
|
6847
|
-
|
6797
|
+
logger.info("[abr] " + (bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty') + ", optimal quality level " + bestLevel);
|
6848
6798
|
if (bestLevel > -1) {
|
6849
6799
|
return bestLevel;
|
6850
6800
|
}
|
@@ -6900,7 +6850,7 @@
|
|
6900
6850
|
currentVideoRange = preferHDR ? videoRanges[videoRanges.length - 1] : videoRanges[0];
|
6901
6851
|
currentFrameRate = minFramerate;
|
6902
6852
|
currentBw = Math.max(currentBw, minBitrate);
|
6903
|
-
|
6853
|
+
logger.log("[abr] picked start tier " + JSON.stringify(startTier));
|
6904
6854
|
} else {
|
6905
6855
|
currentCodecSet = level == null ? void 0 : level.codecSet;
|
6906
6856
|
currentVideoRange = level == null ? void 0 : level.videoRange;
|
@@ -6953,9 +6903,9 @@
|
|
6953
6903
|
var forcedAutoLevel = _this2.forcedAutoLevel;
|
6954
6904
|
if (i !== loadLevel && (forcedAutoLevel === -1 || forcedAutoLevel !== loadLevel)) {
|
6955
6905
|
if (levelsSkipped.length) {
|
6956
|
-
|
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);
|
6957
6907
|
}
|
6958
|
-
|
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);
|
6959
6909
|
}
|
6960
6910
|
if (firstSelection) {
|
6961
6911
|
_this2.firstSelection = i;
|
@@ -6989,7 +6939,7 @@
|
|
6989
6939
|
}
|
6990
6940
|
var firstLevel = this.hls.firstLevel;
|
6991
6941
|
var clamped = Math.min(Math.max(firstLevel, minAutoLevel), maxAutoLevel);
|
6992
|
-
|
6942
|
+
logger.warn("[abr] Could not find best starting auto level. Defaulting to first in playlist " + firstLevel + " clamped to " + clamped);
|
6993
6943
|
return clamped;
|
6994
6944
|
}
|
6995
6945
|
}, {
|
@@ -7039,7 +6989,7 @@
|
|
7039
6989
|
}
|
7040
6990
|
}]);
|
7041
6991
|
return AbrController;
|
7042
|
-
}(
|
6992
|
+
}();
|
7043
6993
|
|
7044
6994
|
/**
|
7045
6995
|
* Provides methods dealing with buffer length retrieval for example.
|
@@ -7260,57 +7210,57 @@
|
|
7260
7210
|
}();
|
7261
7211
|
|
7262
7212
|
var VIDEO_CODEC_PROFILE_REPLACE = /(avc[1234]|hvc1|hev1|dvh[1e]|vp09|av01)(?:\.[^.,]+)+/;
|
7263
|
-
var BufferController = /*#__PURE__*/function (
|
7264
|
-
_inheritsLoose(BufferController, _Logger);
|
7213
|
+
var BufferController = /*#__PURE__*/function () {
|
7265
7214
|
function BufferController(hls) {
|
7266
|
-
var _this;
|
7267
|
-
_this = _Logger.call(this, 'buffer-controller', hls.logger) || this;
|
7215
|
+
var _this = this;
|
7268
7216
|
// The level details used to determine duration, target-duration and live
|
7269
|
-
|
7217
|
+
this.details = null;
|
7270
7218
|
// cache the self generated object url to detect hijack of video tag
|
7271
|
-
|
7219
|
+
this._objectUrl = null;
|
7272
7220
|
// A queue of buffer operations which require the SourceBuffer to not be updating upon execution
|
7273
|
-
|
7221
|
+
this.operationQueue = void 0;
|
7274
7222
|
// References to event listeners for each SourceBuffer, so that they can be referenced for event removal
|
7275
|
-
|
7276
|
-
|
7223
|
+
this.listeners = void 0;
|
7224
|
+
this.hls = void 0;
|
7277
7225
|
// The number of BUFFER_CODEC events received before any sourceBuffers are created
|
7278
|
-
|
7226
|
+
this.bufferCodecEventsExpected = 0;
|
7279
7227
|
// The total number of BUFFER_CODEC events received
|
7280
|
-
|
7228
|
+
this._bufferCodecEventsTotal = 0;
|
7281
7229
|
// A reference to the attached media element
|
7282
|
-
|
7230
|
+
this.media = null;
|
7283
7231
|
// A reference to the active media source
|
7284
|
-
|
7232
|
+
this.mediaSource = null;
|
7285
7233
|
// Last MP3 audio chunk appended
|
7286
|
-
|
7287
|
-
|
7234
|
+
this.lastMpegAudioChunk = null;
|
7235
|
+
this.appendSource = void 0;
|
7288
7236
|
// counters
|
7289
|
-
|
7237
|
+
this.appendErrors = {
|
7290
7238
|
audio: 0,
|
7291
7239
|
video: 0,
|
7292
7240
|
audiovideo: 0
|
7293
7241
|
};
|
7294
|
-
|
7295
|
-
|
7296
|
-
|
7297
|
-
|
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) {
|
7298
7249
|
if (!_this.hls) {
|
7299
7250
|
return;
|
7300
7251
|
}
|
7301
7252
|
_this.hls.pauseBuffering();
|
7302
7253
|
};
|
7303
|
-
|
7254
|
+
this._onStartStreaming = function (event) {
|
7304
7255
|
if (!_this.hls) {
|
7305
7256
|
return;
|
7306
7257
|
}
|
7307
7258
|
_this.hls.resumeBuffering();
|
7308
7259
|
};
|
7309
7260
|
// Keep as arrow functions so that we can directly reference these functions directly as event listeners
|
7310
|
-
|
7311
|
-
var
|
7312
|
-
|
7313
|
-
mediaSource = _assertThisInitialize.mediaSource;
|
7261
|
+
this._onMediaSourceOpen = function () {
|
7262
|
+
var media = _this.media,
|
7263
|
+
mediaSource = _this.mediaSource;
|
7314
7264
|
_this.log('Media source opened');
|
7315
7265
|
if (media) {
|
7316
7266
|
media.removeEventListener('emptied', _this._onMediaEmptied);
|
@@ -7326,25 +7276,27 @@
|
|
7326
7276
|
}
|
7327
7277
|
_this.checkPendingTracks();
|
7328
7278
|
};
|
7329
|
-
|
7279
|
+
this._onMediaSourceClose = function () {
|
7330
7280
|
_this.log('Media source closed');
|
7331
7281
|
};
|
7332
|
-
|
7282
|
+
this._onMediaSourceEnded = function () {
|
7333
7283
|
_this.log('Media source ended');
|
7334
7284
|
};
|
7335
|
-
|
7336
|
-
var
|
7337
|
-
|
7338
|
-
_objectUrl = _assertThisInitialize2._objectUrl;
|
7285
|
+
this._onMediaEmptied = function () {
|
7286
|
+
var mediaSrc = _this.mediaSrc,
|
7287
|
+
_objectUrl = _this._objectUrl;
|
7339
7288
|
if (mediaSrc !== _objectUrl) {
|
7340
|
-
|
7289
|
+
logger.error("Media element src was set while attaching MediaSource (" + _objectUrl + " > " + mediaSrc + ")");
|
7341
7290
|
}
|
7342
7291
|
};
|
7343
|
-
|
7344
|
-
|
7345
|
-
|
7346
|
-
|
7347
|
-
|
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();
|
7348
7300
|
}
|
7349
7301
|
var _proto = BufferController.prototype;
|
7350
7302
|
_proto.hasSourceTypes = function hasSourceTypes() {
|
@@ -7356,12 +7308,6 @@
|
|
7356
7308
|
this.lastMpegAudioChunk = null;
|
7357
7309
|
// @ts-ignore
|
7358
7310
|
this.hls = null;
|
7359
|
-
// @ts-ignore
|
7360
|
-
this._onMediaSourceOpen = this._onMediaSourceClose = null;
|
7361
|
-
// @ts-ignore
|
7362
|
-
this._onMediaSourceEnded = null;
|
7363
|
-
// @ts-ignore
|
7364
|
-
this._onStartStreaming = this._onEndStreaming = null;
|
7365
7311
|
};
|
7366
7312
|
_proto.registerListeners = function registerListeners() {
|
7367
7313
|
var hls = this.hls;
|
@@ -8222,7 +8168,7 @@
|
|
8222
8168
|
}
|
8223
8169
|
}]);
|
8224
8170
|
return BufferController;
|
8225
|
-
}(
|
8171
|
+
}();
|
8226
8172
|
function removeSourceChildren(node) {
|
8227
8173
|
var sourceChildren = node.querySelectorAll('source');
|
8228
8174
|
[].slice.call(sourceChildren).forEach(function (source) {
|
@@ -8346,7 +8292,7 @@
|
|
8346
8292
|
var hls = this.hls;
|
8347
8293
|
var maxLevel = this.getMaxLevel(levels.length - 1);
|
8348
8294
|
if (maxLevel !== this.autoLevelCapping) {
|
8349
|
-
|
8295
|
+
logger.log("Setting autoLevelCapping to " + maxLevel + ": " + levels[maxLevel].height + "p@" + levels[maxLevel].bitrate + " for media " + this.mediaWidth + "x" + this.mediaHeight);
|
8350
8296
|
}
|
8351
8297
|
hls.autoLevelCapping = maxLevel;
|
8352
8298
|
if (hls.autoLevelCapping > this.autoLevelCapping && this.streamController) {
|
@@ -8536,10 +8482,10 @@
|
|
8536
8482
|
totalDroppedFrames: droppedFrames
|
8537
8483
|
});
|
8538
8484
|
if (droppedFPS > 0) {
|
8539
|
-
//
|
8485
|
+
// logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
|
8540
8486
|
if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
|
8541
8487
|
var currentLevel = hls.currentLevel;
|
8542
|
-
|
8488
|
+
logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
|
8543
8489
|
if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
|
8544
8490
|
currentLevel = currentLevel - 1;
|
8545
8491
|
hls.trigger(Events.FPS_DROP_LEVEL_CAPPING, {
|
@@ -8573,28 +8519,26 @@
|
|
8573
8519
|
}();
|
8574
8520
|
|
8575
8521
|
var PATHWAY_PENALTY_DURATION_MS = 300000;
|
8576
|
-
var ContentSteeringController = /*#__PURE__*/function (
|
8577
|
-
_inheritsLoose(ContentSteeringController, _Logger);
|
8522
|
+
var ContentSteeringController = /*#__PURE__*/function () {
|
8578
8523
|
function ContentSteeringController(hls) {
|
8579
|
-
|
8580
|
-
|
8581
|
-
|
8582
|
-
|
8583
|
-
|
8584
|
-
|
8585
|
-
|
8586
|
-
|
8587
|
-
|
8588
|
-
|
8589
|
-
|
8590
|
-
|
8591
|
-
|
8592
|
-
|
8593
|
-
|
8594
|
-
|
8595
|
-
|
8596
|
-
|
8597
|
-
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();
|
8598
8542
|
}
|
8599
8543
|
var _proto = ContentSteeringController.prototype;
|
8600
8544
|
_proto.registerListeners = function registerListeners() {
|
@@ -8715,7 +8659,7 @@
|
|
8715
8659
|
errorAction.resolved = this.pathwayId !== errorPathway;
|
8716
8660
|
}
|
8717
8661
|
if (!errorAction.resolved) {
|
8718
|
-
|
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));
|
8719
8663
|
}
|
8720
8664
|
}
|
8721
8665
|
};
|
@@ -8795,7 +8739,7 @@
|
|
8795
8739
|
return defaultPathway;
|
8796
8740
|
};
|
8797
8741
|
_proto.clonePathways = function clonePathways(pathwayClones) {
|
8798
|
-
var
|
8742
|
+
var _this = this;
|
8799
8743
|
var levels = this.levels;
|
8800
8744
|
if (!levels) {
|
8801
8745
|
return;
|
@@ -8811,7 +8755,7 @@
|
|
8811
8755
|
})) {
|
8812
8756
|
return;
|
8813
8757
|
}
|
8814
|
-
var clonedVariants =
|
8758
|
+
var clonedVariants = _this.getLevelsForPathway(baseId).map(function (baseLevel) {
|
8815
8759
|
var attributes = new AttrList(baseLevel.attrs);
|
8816
8760
|
attributes['PATHWAY-ID'] = cloneId;
|
8817
8761
|
var clonedAudioGroupId = attributes.AUDIO && attributes.AUDIO + "_clone_" + cloneId;
|
@@ -8848,12 +8792,12 @@
|
|
8848
8792
|
return clonedLevel;
|
8849
8793
|
});
|
8850
8794
|
levels.push.apply(levels, clonedVariants);
|
8851
|
-
cloneRenditionGroups(
|
8852
|
-
cloneRenditionGroups(
|
8795
|
+
cloneRenditionGroups(_this.audioTracks, audioGroupCloneMap, uriReplacement, cloneId);
|
8796
|
+
cloneRenditionGroups(_this.subtitleTracks, subtitleGroupCloneMap, uriReplacement, cloneId);
|
8853
8797
|
});
|
8854
8798
|
};
|
8855
8799
|
_proto.loadSteeringManifest = function loadSteeringManifest(uri) {
|
8856
|
-
var
|
8800
|
+
var _this2 = this;
|
8857
8801
|
var config = this.hls.config;
|
8858
8802
|
var Loader = config.loader;
|
8859
8803
|
if (this.loader) {
|
@@ -8888,87 +8832,87 @@
|
|
8888
8832
|
};
|
8889
8833
|
var callbacks = {
|
8890
8834
|
onSuccess: function onSuccess(response, stats, context, networkDetails) {
|
8891
|
-
|
8835
|
+
_this2.log("Loaded steering manifest: \"" + url + "\"");
|
8892
8836
|
var steeringData = response.data;
|
8893
|
-
if (
|
8894
|
-
|
8837
|
+
if (steeringData.VERSION !== 1) {
|
8838
|
+
_this2.log("Steering VERSION " + steeringData.VERSION + " not supported!");
|
8895
8839
|
return;
|
8896
8840
|
}
|
8897
|
-
|
8898
|
-
|
8841
|
+
_this2.updated = performance.now();
|
8842
|
+
_this2.timeToLoad = steeringData.TTL;
|
8899
8843
|
var reloadUri = steeringData['RELOAD-URI'],
|
8900
8844
|
pathwayClones = steeringData['PATHWAY-CLONES'],
|
8901
8845
|
pathwayPriority = steeringData['PATHWAY-PRIORITY'];
|
8902
8846
|
if (reloadUri) {
|
8903
8847
|
try {
|
8904
|
-
|
8848
|
+
_this2.uri = new self.URL(reloadUri, url).href;
|
8905
8849
|
} catch (error) {
|
8906
|
-
|
8907
|
-
|
8850
|
+
_this2.enabled = false;
|
8851
|
+
_this2.log("Failed to parse Steering Manifest RELOAD-URI: " + reloadUri);
|
8908
8852
|
return;
|
8909
8853
|
}
|
8910
8854
|
}
|
8911
|
-
|
8855
|
+
_this2.scheduleRefresh(_this2.uri || context.url);
|
8912
8856
|
if (pathwayClones) {
|
8913
|
-
|
8857
|
+
_this2.clonePathways(pathwayClones);
|
8914
8858
|
}
|
8915
8859
|
var loadedSteeringData = {
|
8916
8860
|
steeringManifest: steeringData,
|
8917
8861
|
url: url.toString()
|
8918
8862
|
};
|
8919
|
-
|
8863
|
+
_this2.hls.trigger(Events.STEERING_MANIFEST_LOADED, loadedSteeringData);
|
8920
8864
|
if (pathwayPriority) {
|
8921
|
-
|
8865
|
+
_this2.updatePathwayPriority(pathwayPriority);
|
8922
8866
|
}
|
8923
8867
|
},
|
8924
8868
|
onError: function onError(error, context, networkDetails, stats) {
|
8925
|
-
|
8926
|
-
|
8869
|
+
_this2.log("Error loading steering manifest: " + error.code + " " + error.text + " (" + context.url + ")");
|
8870
|
+
_this2.stopLoad();
|
8927
8871
|
if (error.code === 410) {
|
8928
|
-
|
8929
|
-
|
8872
|
+
_this2.enabled = false;
|
8873
|
+
_this2.log("Steering manifest " + context.url + " no longer available");
|
8930
8874
|
return;
|
8931
8875
|
}
|
8932
|
-
var ttl =
|
8876
|
+
var ttl = _this2.timeToLoad * 1000;
|
8933
8877
|
if (error.code === 429) {
|
8934
|
-
var loader =
|
8878
|
+
var loader = _this2.loader;
|
8935
8879
|
if (typeof (loader == null ? void 0 : loader.getResponseHeader) === 'function') {
|
8936
8880
|
var retryAfter = loader.getResponseHeader('Retry-After');
|
8937
8881
|
if (retryAfter) {
|
8938
8882
|
ttl = parseFloat(retryAfter) * 1000;
|
8939
8883
|
}
|
8940
8884
|
}
|
8941
|
-
|
8885
|
+
_this2.log("Steering manifest " + context.url + " rate limited");
|
8942
8886
|
return;
|
8943
8887
|
}
|
8944
|
-
|
8888
|
+
_this2.scheduleRefresh(_this2.uri || context.url, ttl);
|
8945
8889
|
},
|
8946
8890
|
onTimeout: function onTimeout(stats, context, networkDetails) {
|
8947
|
-
|
8948
|
-
|
8891
|
+
_this2.log("Timeout loading steering manifest (" + context.url + ")");
|
8892
|
+
_this2.scheduleRefresh(_this2.uri || context.url);
|
8949
8893
|
}
|
8950
8894
|
};
|
8951
8895
|
this.log("Requesting steering manifest: " + url);
|
8952
8896
|
this.loader.load(context, loaderConfig, callbacks);
|
8953
8897
|
};
|
8954
8898
|
_proto.scheduleRefresh = function scheduleRefresh(uri, ttlMs) {
|
8955
|
-
var
|
8899
|
+
var _this3 = this;
|
8956
8900
|
if (ttlMs === void 0) {
|
8957
8901
|
ttlMs = this.timeToLoad * 1000;
|
8958
8902
|
}
|
8959
8903
|
this.clearTimeout();
|
8960
8904
|
this.reloadTimer = self.setTimeout(function () {
|
8961
|
-
var
|
8962
|
-
var media = (
|
8905
|
+
var _this3$hls;
|
8906
|
+
var media = (_this3$hls = _this3.hls) == null ? void 0 : _this3$hls.media;
|
8963
8907
|
if (media && !media.ended) {
|
8964
|
-
|
8908
|
+
_this3.loadSteeringManifest(uri);
|
8965
8909
|
return;
|
8966
8910
|
}
|
8967
|
-
|
8911
|
+
_this3.scheduleRefresh(uri, _this3.timeToLoad * 1000);
|
8968
8912
|
}, ttlMs);
|
8969
8913
|
};
|
8970
8914
|
return ContentSteeringController;
|
8971
|
-
}(
|
8915
|
+
}();
|
8972
8916
|
function cloneRenditionGroups(tracks, groupCloneMap, uriReplacement, cloneId) {
|
8973
8917
|
if (!tracks) {
|
8974
8918
|
return;
|
@@ -9835,7 +9779,7 @@
|
|
9835
9779
|
/**
|
9836
9780
|
* @ignore
|
9837
9781
|
*/
|
9838
|
-
function mergeConfig(defaultConfig, userConfig
|
9782
|
+
function mergeConfig(defaultConfig, userConfig) {
|
9839
9783
|
if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) {
|
9840
9784
|
throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration");
|
9841
9785
|
}
|
@@ -9905,7 +9849,7 @@
|
|
9905
9849
|
/**
|
9906
9850
|
* @ignore
|
9907
9851
|
*/
|
9908
|
-
function enableStreamingMode(config
|
9852
|
+
function enableStreamingMode(config) {
|
9909
9853
|
var currentLoader = config.loader;
|
9910
9854
|
if (currentLoader !== FetchLoader && currentLoader !== XhrLoader) {
|
9911
9855
|
// If a developer has configured their own loader, respect that choice
|
@@ -9922,11 +9866,12 @@
|
|
9922
9866
|
}
|
9923
9867
|
}
|
9924
9868
|
|
9869
|
+
var chromeOrFirefox;
|
9925
9870
|
var LevelController = /*#__PURE__*/function (_BasePlaylistControll) {
|
9926
9871
|
_inheritsLoose(LevelController, _BasePlaylistControll);
|
9927
9872
|
function LevelController(hls, contentSteeringController) {
|
9928
9873
|
var _this;
|
9929
|
-
_this = _BasePlaylistControll.call(this, hls, 'level-controller') || this;
|
9874
|
+
_this = _BasePlaylistControll.call(this, hls, '[level-controller]') || this;
|
9930
9875
|
_this._levels = [];
|
9931
9876
|
_this._firstLevel = -1;
|
9932
9877
|
_this._maxAutoLevel = -1;
|
@@ -9995,13 +9940,21 @@
|
|
9995
9940
|
var videoCodecFound = false;
|
9996
9941
|
var audioCodecFound = false;
|
9997
9942
|
data.levels.forEach(function (levelParsed) {
|
9998
|
-
var _videoCodec;
|
9943
|
+
var _audioCodec, _videoCodec;
|
9999
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
|
10000
9948
|
var audioCodec = levelParsed.audioCodec,
|
10001
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
|
+
}
|
10002
9956
|
if (audioCodec) {
|
10003
|
-
|
10004
|
-
levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource) || undefined;
|
9957
|
+
levelParsed.audioCodec = audioCodec = getCodecCompatibleName(audioCodec, preferManagedMediaSource);
|
10005
9958
|
}
|
10006
9959
|
if (((_videoCodec = videoCodec) == null ? void 0 : _videoCodec.indexOf('avc1')) === 0) {
|
10007
9960
|
videoCodec = levelParsed.videoCodec = convertAVC1ToAVCOTI(videoCodec);
|
@@ -10124,8 +10077,8 @@
|
|
10124
10077
|
return _valueB - _valueA;
|
10125
10078
|
}
|
10126
10079
|
}
|
10127
|
-
if (a.
|
10128
|
-
return a.
|
10080
|
+
if (a.averageBitrate !== b.averageBitrate) {
|
10081
|
+
return a.averageBitrate - b.averageBitrate;
|
10129
10082
|
}
|
10130
10083
|
return 0;
|
10131
10084
|
});
|
@@ -11148,8 +11101,8 @@
|
|
11148
11101
|
var _frag$decryptdata;
|
11149
11102
|
var byteRangeStart = start;
|
11150
11103
|
var byteRangeEnd = end;
|
11151
|
-
if (frag.sn === 'initSegment' &&
|
11152
|
-
// 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,
|
11153
11106
|
// has the unencrypted size specified in the range.
|
11154
11107
|
// Ref: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-6.3.6
|
11155
11108
|
var fragmentLen = end - start;
|
@@ -11182,9 +11135,6 @@
|
|
11182
11135
|
(part ? part : frag).stats.aborted = true;
|
11183
11136
|
return new LoadError(errorData);
|
11184
11137
|
}
|
11185
|
-
function isMethodFullSegmentAesCbc(method) {
|
11186
|
-
return method === 'AES-128' || method === 'AES-256';
|
11187
|
-
}
|
11188
11138
|
var LoadError = /*#__PURE__*/function (_Error) {
|
11189
11139
|
_inheritsLoose(LoadError, _Error);
|
11190
11140
|
function LoadError(data) {
|
@@ -11341,8 +11291,6 @@
|
|
11341
11291
|
}
|
11342
11292
|
return this.loadKeyEME(keyInfo, frag);
|
11343
11293
|
case 'AES-128':
|
11344
|
-
case 'AES-256':
|
11345
|
-
case 'AES-256-CTR':
|
11346
11294
|
return this.loadKeyHTTP(keyInfo, frag);
|
11347
11295
|
default:
|
11348
11296
|
return Promise.reject(this.createKeyLoadError(frag, ErrorDetails.KEY_LOAD_ERROR, new Error("Key supplied with unsupported METHOD: \"" + decryptdata.method + "\"")));
|
@@ -11476,17 +11424,13 @@
|
|
11476
11424
|
* we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further
|
11477
11425
|
* task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo).
|
11478
11426
|
*/
|
11479
|
-
var TaskLoop = /*#__PURE__*/function (
|
11480
|
-
|
11481
|
-
|
11482
|
-
|
11483
|
-
|
11484
|
-
|
11485
|
-
|
11486
|
-
_this._tickInterval = null;
|
11487
|
-
_this._tickCallCount = 0;
|
11488
|
-
_this._boundTick = _this.tick.bind(_assertThisInitialized(_this));
|
11489
|
-
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);
|
11490
11434
|
}
|
11491
11435
|
var _proto = TaskLoop.prototype;
|
11492
11436
|
_proto.destroy = function destroy() {
|
@@ -11572,7 +11516,7 @@
|
|
11572
11516
|
*/;
|
11573
11517
|
_proto.doTick = function doTick() {};
|
11574
11518
|
return TaskLoop;
|
11575
|
-
}(
|
11519
|
+
}();
|
11576
11520
|
|
11577
11521
|
var ChunkMetadata = function ChunkMetadata(level, sn, id, size, part, partial) {
|
11578
11522
|
if (size === void 0) {
|
@@ -11758,65 +11702,37 @@
|
|
11758
11702
|
}
|
11759
11703
|
|
11760
11704
|
var AESCrypto = /*#__PURE__*/function () {
|
11761
|
-
function AESCrypto(subtle, iv
|
11705
|
+
function AESCrypto(subtle, iv) {
|
11762
11706
|
this.subtle = void 0;
|
11763
11707
|
this.aesIV = void 0;
|
11764
|
-
this.aesMode = void 0;
|
11765
11708
|
this.subtle = subtle;
|
11766
11709
|
this.aesIV = iv;
|
11767
|
-
this.aesMode = aesMode;
|
11768
11710
|
}
|
11769
11711
|
var _proto = AESCrypto.prototype;
|
11770
11712
|
_proto.decrypt = function decrypt(data, key) {
|
11771
|
-
|
11772
|
-
|
11773
|
-
|
11774
|
-
|
11775
|
-
iv: this.aesIV
|
11776
|
-
}, key, data);
|
11777
|
-
case DecrypterAesMode.ctr:
|
11778
|
-
return this.subtle.decrypt({
|
11779
|
-
name: 'AES-CTR',
|
11780
|
-
counter: this.aesIV,
|
11781
|
-
length: 64
|
11782
|
-
},
|
11783
|
-
//64 : NIST SP800-38A standard suggests that the counter should occupy half of the counter block
|
11784
|
-
key, data);
|
11785
|
-
default:
|
11786
|
-
throw new Error("[AESCrypto] invalid aes mode " + this.aesMode);
|
11787
|
-
}
|
11713
|
+
return this.subtle.decrypt({
|
11714
|
+
name: 'AES-CBC',
|
11715
|
+
iv: this.aesIV
|
11716
|
+
}, key, data);
|
11788
11717
|
};
|
11789
11718
|
return AESCrypto;
|
11790
11719
|
}();
|
11791
11720
|
|
11792
11721
|
var FastAESKey = /*#__PURE__*/function () {
|
11793
|
-
function FastAESKey(subtle, key
|
11722
|
+
function FastAESKey(subtle, key) {
|
11794
11723
|
this.subtle = void 0;
|
11795
11724
|
this.key = void 0;
|
11796
|
-
this.aesMode = void 0;
|
11797
11725
|
this.subtle = subtle;
|
11798
11726
|
this.key = key;
|
11799
|
-
this.aesMode = aesMode;
|
11800
11727
|
}
|
11801
11728
|
var _proto = FastAESKey.prototype;
|
11802
11729
|
_proto.expandKey = function expandKey() {
|
11803
|
-
var subtleAlgoName = getSubtleAlgoName(this.aesMode);
|
11804
11730
|
return this.subtle.importKey('raw', this.key, {
|
11805
|
-
name:
|
11731
|
+
name: 'AES-CBC'
|
11806
11732
|
}, false, ['encrypt', 'decrypt']);
|
11807
11733
|
};
|
11808
11734
|
return FastAESKey;
|
11809
11735
|
}();
|
11810
|
-
function getSubtleAlgoName(aesMode) {
|
11811
|
-
switch (aesMode) {
|
11812
|
-
case DecrypterAesMode.cbc:
|
11813
|
-
return 'AES-CBC';
|
11814
|
-
case DecrypterAesMode.ctr:
|
11815
|
-
return 'AES-CTR';
|
11816
|
-
default:
|
11817
|
-
throw new Error("[FastAESKey] invalid aes mode " + aesMode);
|
11818
|
-
}
|
11819
|
-
}
|
11820
11736
|
|
11821
11737
|
// PKCS7
|
11822
11738
|
function removePadding(array) {
|
@@ -12069,8 +11985,7 @@
|
|
12069
11985
|
this.currentIV = null;
|
12070
11986
|
this.currentResult = null;
|
12071
11987
|
this.useSoftware = void 0;
|
12072
|
-
this.
|
12073
|
-
this.enableSoftwareAES = config.enableSoftwareAES;
|
11988
|
+
this.useSoftware = config.enableSoftwareAES;
|
12074
11989
|
this.removePKCS7Padding = removePKCS7Padding;
|
12075
11990
|
// built in decryptor expects PKCS7 padding
|
12076
11991
|
if (removePKCS7Padding) {
|
@@ -12083,7 +11998,9 @@
|
|
12083
11998
|
/* no-op */
|
12084
11999
|
}
|
12085
12000
|
}
|
12086
|
-
|
12001
|
+
if (this.subtle === null) {
|
12002
|
+
this.useSoftware = true;
|
12003
|
+
}
|
12087
12004
|
}
|
12088
12005
|
var _proto = Decrypter.prototype;
|
12089
12006
|
_proto.destroy = function destroy() {
|
@@ -12120,11 +12037,11 @@
|
|
12120
12037
|
this.softwareDecrypter = null;
|
12121
12038
|
}
|
12122
12039
|
};
|
12123
|
-
_proto.decrypt = function decrypt(data, key, iv
|
12040
|
+
_proto.decrypt = function decrypt(data, key, iv) {
|
12124
12041
|
var _this = this;
|
12125
12042
|
if (this.useSoftware) {
|
12126
12043
|
return new Promise(function (resolve, reject) {
|
12127
|
-
_this.softwareDecrypt(new Uint8Array(data), key, iv
|
12044
|
+
_this.softwareDecrypt(new Uint8Array(data), key, iv);
|
12128
12045
|
var decryptResult = _this.flush();
|
12129
12046
|
if (decryptResult) {
|
12130
12047
|
resolve(decryptResult.buffer);
|
@@ -12133,20 +12050,16 @@
|
|
12133
12050
|
}
|
12134
12051
|
});
|
12135
12052
|
}
|
12136
|
-
return this.webCryptoDecrypt(new Uint8Array(data), key, iv
|
12053
|
+
return this.webCryptoDecrypt(new Uint8Array(data), key, iv);
|
12137
12054
|
}
|
12138
12055
|
|
12139
12056
|
// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
|
12140
12057
|
// data is handled in the flush() call
|
12141
12058
|
;
|
12142
|
-
_proto.softwareDecrypt = function softwareDecrypt(data, key, iv
|
12059
|
+
_proto.softwareDecrypt = function softwareDecrypt(data, key, iv) {
|
12143
12060
|
var currentIV = this.currentIV,
|
12144
12061
|
currentResult = this.currentResult,
|
12145
12062
|
remainderData = this.remainderData;
|
12146
|
-
if (aesMode !== DecrypterAesMode.cbc || key.byteLength !== 16) {
|
12147
|
-
logger.warn('SoftwareDecrypt: can only handle AES-128-CBC');
|
12148
|
-
return null;
|
12149
|
-
}
|
12150
12063
|
this.logOnce('JS AES decrypt');
|
12151
12064
|
// The output is staggered during progressive parsing - the current result is cached, and emitted on the next call
|
12152
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
|
@@ -12179,12 +12092,12 @@
|
|
12179
12092
|
}
|
12180
12093
|
return result;
|
12181
12094
|
};
|
12182
|
-
_proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv
|
12095
|
+
_proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv) {
|
12183
12096
|
var _this2 = this;
|
12184
12097
|
var subtle = this.subtle;
|
12185
12098
|
if (this.key !== key || !this.fastAesKey) {
|
12186
12099
|
this.key = key;
|
12187
|
-
this.fastAesKey = new FastAESKey(subtle, key
|
12100
|
+
this.fastAesKey = new FastAESKey(subtle, key);
|
12188
12101
|
}
|
12189
12102
|
return this.fastAesKey.expandKey().then(function (aesKey) {
|
12190
12103
|
// decrypt using web crypto
|
@@ -12192,25 +12105,22 @@
|
|
12192
12105
|
return Promise.reject(new Error('web crypto not initialized'));
|
12193
12106
|
}
|
12194
12107
|
_this2.logOnce('WebCrypto AES decrypt');
|
12195
|
-
var crypto = new AESCrypto(subtle, new Uint8Array(iv)
|
12108
|
+
var crypto = new AESCrypto(subtle, new Uint8Array(iv));
|
12196
12109
|
return crypto.decrypt(data.buffer, aesKey);
|
12197
12110
|
}).catch(function (err) {
|
12198
12111
|
logger.warn("[decrypter]: WebCrypto Error, disable WebCrypto API, " + err.name + ": " + err.message);
|
12199
|
-
return _this2.onWebCryptoError(data, key, iv
|
12112
|
+
return _this2.onWebCryptoError(data, key, iv);
|
12200
12113
|
});
|
12201
12114
|
};
|
12202
|
-
_proto.onWebCryptoError = function onWebCryptoError(data, key, iv
|
12203
|
-
|
12204
|
-
|
12205
|
-
|
12206
|
-
|
12207
|
-
|
12208
|
-
|
12209
|
-
if (decryptResult) {
|
12210
|
-
return decryptResult.buffer;
|
12211
|
-
}
|
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;
|
12212
12122
|
}
|
12213
|
-
throw new Error('WebCrypto
|
12123
|
+
throw new Error('WebCrypto and softwareDecrypt: failed to decrypt data');
|
12214
12124
|
};
|
12215
12125
|
_proto.getValidChunk = function getValidChunk(data) {
|
12216
12126
|
var currentChunk = data;
|
@@ -12264,7 +12174,7 @@
|
|
12264
12174
|
_inheritsLoose(BaseStreamController, _TaskLoop);
|
12265
12175
|
function BaseStreamController(hls, fragmentTracker, keyLoader, logPrefix, playlistType) {
|
12266
12176
|
var _this;
|
12267
|
-
_this = _TaskLoop.call(this
|
12177
|
+
_this = _TaskLoop.call(this) || this;
|
12268
12178
|
_this.hls = void 0;
|
12269
12179
|
_this.fragPrevious = null;
|
12270
12180
|
_this.fragCurrent = null;
|
@@ -12289,81 +12199,25 @@
|
|
12289
12199
|
_this.startFragRequested = false;
|
12290
12200
|
_this.decrypter = void 0;
|
12291
12201
|
_this.initPTS = [];
|
12292
|
-
_this.
|
12293
|
-
|
12294
|
-
|
12295
|
-
|
12296
|
-
|
12297
|
-
mediaBuffer = _assertThisInitialize.mediaBuffer,
|
12298
|
-
state = _assertThisInitialize.state;
|
12299
|
-
var currentTime = media ? media.currentTime : 0;
|
12300
|
-
var bufferInfo = BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
|
12301
|
-
_this.log("media seeking to " + (isFiniteNumber(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
|
12302
|
-
if (_this.state === State.ENDED) {
|
12303
|
-
_this.resetLoadingState();
|
12304
|
-
} else if (fragCurrent) {
|
12305
|
-
// Seeking while frag load is in progress
|
12306
|
-
var tolerance = config.maxFragLookUpTolerance;
|
12307
|
-
var fragStartOffset = fragCurrent.start - tolerance;
|
12308
|
-
var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
|
12309
|
-
// if seeking out of buffered range or into new one
|
12310
|
-
if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
|
12311
|
-
var pastFragment = currentTime > fragEndOffset;
|
12312
|
-
// if the seek position is outside the current fragment range
|
12313
|
-
if (currentTime < fragStartOffset || pastFragment) {
|
12314
|
-
if (pastFragment && fragCurrent.loader) {
|
12315
|
-
_this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
|
12316
|
-
fragCurrent.abortRequests();
|
12317
|
-
_this.resetLoadingState();
|
12318
|
-
}
|
12319
|
-
_this.fragPrevious = null;
|
12320
|
-
}
|
12321
|
-
}
|
12322
|
-
}
|
12323
|
-
if (media) {
|
12324
|
-
// Remove gap fragments
|
12325
|
-
_this.fragmentTracker.removeFragmentsInRange(currentTime, Infinity, _this.playlistType, true);
|
12326
|
-
_this.lastCurrentTime = currentTime;
|
12327
|
-
}
|
12328
|
-
|
12329
|
-
// in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
|
12330
|
-
if (!_this.loadedmetadata && !bufferInfo.len) {
|
12331
|
-
_this.nextLoadPosition = _this.startPosition = currentTime;
|
12332
|
-
}
|
12333
|
-
|
12334
|
-
// Async tick to speed up processing
|
12335
|
-
_this.tickImmediate();
|
12336
|
-
};
|
12337
|
-
_this.onMediaEnded = function () {
|
12338
|
-
// reset startPosition and lastCurrentTime to restart playback @ stream beginning
|
12339
|
-
_this.startPosition = _this.lastCurrentTime = 0;
|
12340
|
-
};
|
12202
|
+
_this.onvseeking = null;
|
12203
|
+
_this.onvended = null;
|
12204
|
+
_this.logPrefix = '';
|
12205
|
+
_this.log = void 0;
|
12206
|
+
_this.warn = void 0;
|
12341
12207
|
_this.playlistType = playlistType;
|
12208
|
+
_this.logPrefix = logPrefix;
|
12209
|
+
_this.log = logger.log.bind(logger, logPrefix + ":");
|
12210
|
+
_this.warn = logger.warn.bind(logger, logPrefix + ":");
|
12342
12211
|
_this.hls = hls;
|
12343
12212
|
_this.fragmentLoader = new FragmentLoader(hls.config);
|
12344
12213
|
_this.keyLoader = keyLoader;
|
12345
12214
|
_this.fragmentTracker = fragmentTracker;
|
12346
12215
|
_this.config = hls.config;
|
12347
12216
|
_this.decrypter = new Decrypter(hls.config);
|
12217
|
+
hls.on(Events.MANIFEST_LOADED, _this.onManifestLoaded, _assertThisInitialized(_this));
|
12348
12218
|
return _this;
|
12349
12219
|
}
|
12350
12220
|
var _proto = BaseStreamController.prototype;
|
12351
|
-
_proto.registerListeners = function registerListeners() {
|
12352
|
-
var hls = this.hls;
|
12353
|
-
hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
12354
|
-
hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
12355
|
-
hls.on(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
12356
|
-
hls.on(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
|
12357
|
-
hls.on(Events.ERROR, this.onError, this);
|
12358
|
-
};
|
12359
|
-
_proto.unregisterListeners = function unregisterListeners() {
|
12360
|
-
var hls = this.hls;
|
12361
|
-
hls.off(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
|
12362
|
-
hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
12363
|
-
hls.off(Events.MANIFEST_LOADING, this.onManifestLoading, this);
|
12364
|
-
hls.off(Events.MANIFEST_LOADED, this.onManifestLoaded, this);
|
12365
|
-
hls.off(Events.ERROR, this.onError, this);
|
12366
|
-
};
|
12367
12221
|
_proto.doTick = function doTick() {
|
12368
12222
|
this.onTickEnd();
|
12369
12223
|
};
|
@@ -12417,8 +12271,10 @@
|
|
12417
12271
|
};
|
12418
12272
|
_proto.onMediaAttached = function onMediaAttached(event, data) {
|
12419
12273
|
var media = this.media = this.mediaBuffer = data.media;
|
12420
|
-
|
12421
|
-
|
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);
|
12422
12278
|
var config = this.config;
|
12423
12279
|
if (this.levels && config.autoStartLoad && this.state === State.STOPPED) {
|
12424
12280
|
this.startLoad(config.startPosition);
|
@@ -12432,9 +12288,10 @@
|
|
12432
12288
|
}
|
12433
12289
|
|
12434
12290
|
// remove video listeners
|
12435
|
-
if (media) {
|
12436
|
-
media.removeEventListener('seeking', this.
|
12437
|
-
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;
|
12438
12295
|
}
|
12439
12296
|
if (this.keyLoader) {
|
12440
12297
|
this.keyLoader.detach();
|
@@ -12444,8 +12301,54 @@
|
|
12444
12301
|
this.fragmentTracker.removeAllFragments();
|
12445
12302
|
this.stopLoad();
|
12446
12303
|
};
|
12447
|
-
_proto.
|
12448
|
-
|
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
|
+
};
|
12449
12352
|
_proto.onManifestLoaded = function onManifestLoaded(event, data) {
|
12450
12353
|
this.startTimeOffset = data.startTimeOffset;
|
12451
12354
|
this.initPTS = [];
|
@@ -12455,7 +12358,7 @@
|
|
12455
12358
|
this.stopLoad();
|
12456
12359
|
_TaskLoop.prototype.onHandlerDestroying.call(this);
|
12457
12360
|
// @ts-ignore
|
12458
|
-
this.hls =
|
12361
|
+
this.hls = null;
|
12459
12362
|
};
|
12460
12363
|
_proto.onHandlerDestroyed = function onHandlerDestroyed() {
|
12461
12364
|
this.state = State.STOPPED;
|
@@ -12585,10 +12488,10 @@
|
|
12585
12488
|
var decryptData = frag.decryptdata;
|
12586
12489
|
|
12587
12490
|
// check to see if the payload needs to be decrypted
|
12588
|
-
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') {
|
12589
12492
|
var startTime = self.performance.now();
|
12590
12493
|
// decrypt init segment data
|
12591
|
-
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) {
|
12592
12495
|
hls.trigger(Events.ERROR, {
|
12593
12496
|
type: ErrorTypes.MEDIA_ERROR,
|
12594
12497
|
details: ErrorDetails.FRAG_DECRYPT_ERROR,
|
@@ -12701,7 +12604,7 @@
|
|
12701
12604
|
}
|
12702
12605
|
var keyLoadingPromise = null;
|
12703
12606
|
if (frag.encrypted && !((_frag$decryptdata = frag.decryptdata) != null && _frag$decryptdata.key)) {
|
12704
|
-
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);
|
12705
12608
|
this.state = State.KEY_LOADING;
|
12706
12609
|
this.fragCurrent = frag;
|
12707
12610
|
keyLoadingPromise = this.keyLoader.load(frag).then(function (keyLoadedData) {
|
@@ -12732,7 +12635,7 @@
|
|
12732
12635
|
var partIndex = this.getNextPart(partList, frag, targetBufferTime);
|
12733
12636
|
if (partIndex > -1) {
|
12734
12637
|
var part = partList[partIndex];
|
12735
|
-
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)));
|
12736
12639
|
this.nextLoadPosition = part.start + part.duration;
|
12737
12640
|
this.state = State.FRAG_LOADING;
|
12738
12641
|
var _result;
|
@@ -12765,7 +12668,7 @@
|
|
12765
12668
|
}
|
12766
12669
|
}
|
12767
12670
|
}
|
12768
|
-
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)));
|
12769
12672
|
// Don't update nextLoadPosition for fragments which are not buffered
|
12770
12673
|
if (isFiniteNumber(frag.sn) && !this.bitrateTest) {
|
12771
12674
|
this.nextLoadPosition = frag.start + frag.duration;
|
@@ -13326,7 +13229,7 @@
|
|
13326
13229
|
errorAction.resolved = true;
|
13327
13230
|
}
|
13328
13231
|
} else {
|
13329
|
-
|
13232
|
+
logger.warn(data.details + " reached or exceeded max retry (" + retryCount + ")");
|
13330
13233
|
return;
|
13331
13234
|
}
|
13332
13235
|
} else if ((errorAction == null ? void 0 : errorAction.action) === NetworkErrorAction.SendAlternateToPenaltyBox) {
|
@@ -13716,7 +13619,6 @@
|
|
13716
13619
|
*/
|
13717
13620
|
function getAudioConfig(observer, data, offset, audioCodec) {
|
13718
13621
|
var adtsObjectType;
|
13719
|
-
var originalAdtsObjectType;
|
13720
13622
|
var adtsExtensionSamplingIndex;
|
13721
13623
|
var adtsChannelConfig;
|
13722
13624
|
var config;
|
@@ -13724,7 +13626,7 @@
|
|
13724
13626
|
var manifestCodec = audioCodec;
|
13725
13627
|
var adtsSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
|
13726
13628
|
// byte 2
|
13727
|
-
adtsObjectType =
|
13629
|
+
adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;
|
13728
13630
|
var adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2;
|
13729
13631
|
if (adtsSamplingIndex > adtsSamplingRates.length - 1) {
|
13730
13632
|
var error = new Error("invalid ADTS sampling index:" + adtsSamplingIndex);
|
@@ -13741,8 +13643,8 @@
|
|
13741
13643
|
// byte 3
|
13742
13644
|
adtsChannelConfig |= (data[offset + 3] & 0xc0) >>> 6;
|
13743
13645
|
logger.log("manifest codec:" + audioCodec + ", ADTS type:" + adtsObjectType + ", samplingIndex:" + adtsSamplingIndex);
|
13744
|
-
//
|
13745
|
-
if (/firefox
|
13646
|
+
// firefox: freq less than 24kHz = AAC SBR (HE-AAC)
|
13647
|
+
if (/firefox/i.test(userAgent)) {
|
13746
13648
|
if (adtsSamplingIndex >= 6) {
|
13747
13649
|
adtsObjectType = 5;
|
13748
13650
|
config = new Array(4);
|
@@ -13836,7 +13738,6 @@
|
|
13836
13738
|
samplerate: adtsSamplingRates[adtsSamplingIndex],
|
13837
13739
|
channelCount: adtsChannelConfig,
|
13838
13740
|
codec: 'mp4a.40.' + adtsObjectType,
|
13839
|
-
parsedCodec: 'mp4a.40.' + originalAdtsObjectType,
|
13840
13741
|
manifestCodec: manifestCodec
|
13841
13742
|
};
|
13842
13743
|
}
|
@@ -13891,8 +13792,7 @@
|
|
13891
13792
|
track.channelCount = config.channelCount;
|
13892
13793
|
track.codec = config.codec;
|
13893
13794
|
track.manifestCodec = config.manifestCodec;
|
13894
|
-
track.
|
13895
|
-
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);
|
13896
13796
|
}
|
13897
13797
|
}
|
13898
13798
|
function getFrameDuration(samplerate) {
|
@@ -14979,7 +14879,7 @@
|
|
14979
14879
|
}
|
14980
14880
|
var _proto = SampleAesDecrypter.prototype;
|
14981
14881
|
_proto.decryptBuffer = function decryptBuffer(encryptedData) {
|
14982
|
-
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);
|
14983
14883
|
}
|
14984
14884
|
|
14985
14885
|
// AAC - encrypt all full 16 bytes blocks starting from offset 16
|
@@ -17208,7 +17108,7 @@
|
|
17208
17108
|
logger.warn("[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round(1000 * delta / inputTimeScale) + " ms gap.");
|
17209
17109
|
for (var j = 0; j < missing; j++) {
|
17210
17110
|
var newStamp = Math.max(nextPts, 0);
|
17211
|
-
var fillFrame = AAC.getSilentFrame(track.
|
17111
|
+
var fillFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
|
17212
17112
|
if (!fillFrame) {
|
17213
17113
|
logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
|
17214
17114
|
fillFrame = sample.unit.subarray();
|
@@ -17336,7 +17236,7 @@
|
|
17336
17236
|
// samples count of this segment's duration
|
17337
17237
|
var nbSamples = Math.ceil((endDTS - startDTS) / frameDuration);
|
17338
17238
|
// silent frame
|
17339
|
-
var silentFrame = AAC.getSilentFrame(track.
|
17239
|
+
var silentFrame = AAC.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
|
17340
17240
|
logger.warn('[mp4-remuxer]: remux empty Audio');
|
17341
17241
|
// Can't remux if we can't generate a silent frame...
|
17342
17242
|
if (!silentFrame) {
|
@@ -17723,15 +17623,13 @@
|
|
17723
17623
|
duration = transmuxConfig.duration,
|
17724
17624
|
initSegmentData = transmuxConfig.initSegmentData;
|
17725
17625
|
var keyData = getEncryptionType(uintData, decryptdata);
|
17726
|
-
if (keyData &&
|
17626
|
+
if (keyData && keyData.method === 'AES-128') {
|
17727
17627
|
var decrypter = this.getDecrypter();
|
17728
|
-
var aesMode = getAesModeFromFullSegmentMethod(keyData.method);
|
17729
|
-
|
17730
17628
|
// Software decryption is synchronous; webCrypto is not
|
17731
17629
|
if (decrypter.isSync()) {
|
17732
17630
|
// Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
|
17733
17631
|
// data is handled in the flush() call
|
17734
|
-
var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer
|
17632
|
+
var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer);
|
17735
17633
|
// For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
|
17736
17634
|
var loadingParts = chunkMeta.part > -1;
|
17737
17635
|
if (loadingParts) {
|
@@ -17743,7 +17641,7 @@
|
|
17743
17641
|
}
|
17744
17642
|
uintData = new Uint8Array(decryptedData);
|
17745
17643
|
} else {
|
17746
|
-
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) {
|
17747
17645
|
// Calling push here is important; if flush() is called while this is still resolving, this ensures that
|
17748
17646
|
// the decrypted data has been transmuxed
|
17749
17647
|
var result = _this.push(decryptedData, null, chunkMeta);
|
@@ -18364,7 +18262,7 @@
|
|
18364
18262
|
observer.on(Events.ERROR, forwardMessage);
|
18365
18263
|
|
18366
18264
|
// forward logger events to main thread
|
18367
|
-
var forwardWorkerLogs = function forwardWorkerLogs(
|
18265
|
+
var forwardWorkerLogs = function forwardWorkerLogs() {
|
18368
18266
|
var _loop = function _loop(logFn) {
|
18369
18267
|
var func = function func(message) {
|
18370
18268
|
forwardMessage('workerLog', {
|
@@ -18385,8 +18283,8 @@
|
|
18385
18283
|
{
|
18386
18284
|
var config = JSON.parse(data.config);
|
18387
18285
|
self.transmuxer = new Transmuxer(observer, data.typeSupported, config, data.vendor, data.id);
|
18388
|
-
|
18389
|
-
forwardWorkerLogs(
|
18286
|
+
enableLogs(config.debug, data.id);
|
18287
|
+
forwardWorkerLogs();
|
18390
18288
|
forwardMessage('init', null);
|
18391
18289
|
break;
|
18392
18290
|
}
|
@@ -18560,7 +18458,16 @@
|
|
18560
18458
|
this.observer = new EventEmitter();
|
18561
18459
|
this.observer.on(Events.FRAG_DECRYPTED, forwardMessage);
|
18562
18460
|
this.observer.on(Events.ERROR, forwardMessage);
|
18563
|
-
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
|
+
};
|
18564
18471
|
|
18565
18472
|
// navigator.vendor is not always available in Web Worker
|
18566
18473
|
// refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
|
@@ -18817,25 +18724,21 @@
|
|
18817
18724
|
var MAX_START_GAP_JUMP = 2.0;
|
18818
18725
|
var SKIP_BUFFER_HOLE_STEP_SECONDS = 0.1;
|
18819
18726
|
var SKIP_BUFFER_RANGE_START = 0.05;
|
18820
|
-
var GapController = /*#__PURE__*/function (
|
18821
|
-
_inheritsLoose(GapController, _Logger);
|
18727
|
+
var GapController = /*#__PURE__*/function () {
|
18822
18728
|
function GapController(config, media, fragmentTracker, hls) {
|
18823
|
-
|
18824
|
-
|
18825
|
-
|
18826
|
-
|
18827
|
-
|
18828
|
-
|
18829
|
-
|
18830
|
-
|
18831
|
-
|
18832
|
-
|
18833
|
-
|
18834
|
-
|
18835
|
-
|
18836
|
-
_this.fragmentTracker = fragmentTracker;
|
18837
|
-
_this.hls = hls;
|
18838
|
-
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;
|
18839
18742
|
}
|
18840
18743
|
var _proto = GapController.prototype;
|
18841
18744
|
_proto.destroy = function destroy() {
|
@@ -18873,7 +18776,7 @@
|
|
18873
18776
|
// The playhead is now moving, but was previously stalled
|
18874
18777
|
if (this.stallReported) {
|
18875
18778
|
var _stalledDuration = self.performance.now() - stalled;
|
18876
|
-
|
18779
|
+
logger.warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms");
|
18877
18780
|
this.stallReported = false;
|
18878
18781
|
}
|
18879
18782
|
this.stalled = null;
|
@@ -18982,7 +18885,7 @@
|
|
18982
18885
|
// needs to cross some sort of threshold covering all source-buffers content
|
18983
18886
|
// to start playing properly.
|
18984
18887
|
if ((bufferInfo.len > config.maxBufferHole || bufferInfo.nextStart && bufferInfo.nextStart - currentTime < config.maxBufferHole) && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) {
|
18985
|
-
|
18888
|
+
logger.warn('Trying to nudge playhead over buffer-hole');
|
18986
18889
|
// Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds
|
18987
18890
|
// We only try to jump the hole if it's under the configured size
|
18988
18891
|
// Reset stalled so to rearm watchdog timer
|
@@ -19004,7 +18907,7 @@
|
|
19004
18907
|
// Report stalled error once
|
19005
18908
|
this.stallReported = true;
|
19006
18909
|
var error = new Error("Playback stalling at @" + media.currentTime + " due to low buffer (" + JSON.stringify(bufferInfo) + ")");
|
19007
|
-
|
18910
|
+
logger.warn(error.message);
|
19008
18911
|
hls.trigger(Events.ERROR, {
|
19009
18912
|
type: ErrorTypes.MEDIA_ERROR,
|
19010
18913
|
details: ErrorDetails.BUFFER_STALLED_ERROR,
|
@@ -19068,7 +18971,7 @@
|
|
19068
18971
|
}
|
19069
18972
|
}
|
19070
18973
|
var targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS);
|
19071
|
-
|
18974
|
+
logger.warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime);
|
19072
18975
|
this.moved = true;
|
19073
18976
|
this.stalled = null;
|
19074
18977
|
media.currentTime = targetTime;
|
@@ -19107,7 +19010,7 @@
|
|
19107
19010
|
var targetTime = currentTime + (nudgeRetry + 1) * config.nudgeOffset;
|
19108
19011
|
// playback stalled in buffered area ... let's nudge currentTime to try to overcome this
|
19109
19012
|
var error = new Error("Nudging 'currentTime' from " + currentTime + " to " + targetTime);
|
19110
|
-
|
19013
|
+
logger.warn(error.message);
|
19111
19014
|
media.currentTime = targetTime;
|
19112
19015
|
hls.trigger(Events.ERROR, {
|
19113
19016
|
type: ErrorTypes.MEDIA_ERROR,
|
@@ -19117,7 +19020,7 @@
|
|
19117
19020
|
});
|
19118
19021
|
} else {
|
19119
19022
|
var _error = new Error("Playhead still not moving while enough data buffered @" + currentTime + " after " + config.nudgeMaxRetry + " nudges");
|
19120
|
-
|
19023
|
+
logger.error(_error.message);
|
19121
19024
|
hls.trigger(Events.ERROR, {
|
19122
19025
|
type: ErrorTypes.MEDIA_ERROR,
|
19123
19026
|
details: ErrorDetails.BUFFER_STALLED_ERROR,
|
@@ -19127,14 +19030,14 @@
|
|
19127
19030
|
}
|
19128
19031
|
};
|
19129
19032
|
return GapController;
|
19130
|
-
}(
|
19033
|
+
}();
|
19131
19034
|
|
19132
19035
|
var TICK_INTERVAL = 100; // how often to tick in ms
|
19133
19036
|
var StreamController = /*#__PURE__*/function (_BaseStreamController) {
|
19134
19037
|
_inheritsLoose(StreamController, _BaseStreamController);
|
19135
19038
|
function StreamController(hls, fragmentTracker, keyLoader) {
|
19136
19039
|
var _this;
|
19137
|
-
_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;
|
19138
19041
|
_this.audioCodecSwap = false;
|
19139
19042
|
_this.gapController = null;
|
19140
19043
|
_this.level = -1;
|
@@ -19142,43 +19045,27 @@
|
|
19142
19045
|
_this.altAudio = false;
|
19143
19046
|
_this.audioOnly = false;
|
19144
19047
|
_this.fragPlaying = null;
|
19048
|
+
_this.onvplaying = null;
|
19049
|
+
_this.onvseeked = null;
|
19145
19050
|
_this.fragLastKbps = 0;
|
19146
19051
|
_this.couldBacktrack = false;
|
19147
19052
|
_this.backtrackFragment = null;
|
19148
19053
|
_this.audioCodecSwitch = false;
|
19149
19054
|
_this.videoBuffer = null;
|
19150
|
-
_this.
|
19151
|
-
// tick to speed up FRAG_CHANGED triggering
|
19152
|
-
_this.tick();
|
19153
|
-
};
|
19154
|
-
_this.onMediaSeeked = function () {
|
19155
|
-
var media = _this.media;
|
19156
|
-
var currentTime = media ? media.currentTime : null;
|
19157
|
-
if (isFiniteNumber(currentTime)) {
|
19158
|
-
_this.log("Media seeked to " + currentTime.toFixed(3));
|
19159
|
-
}
|
19160
|
-
|
19161
|
-
// If seeked was issued before buffer was appended do not tick immediately
|
19162
|
-
var bufferInfo = _this.getMainFwdBufferInfo();
|
19163
|
-
if (bufferInfo === null || bufferInfo.len === 0) {
|
19164
|
-
_this.warn("Main forward buffer length on \"seeked\" event " + (bufferInfo ? bufferInfo.len : 'empty') + ")");
|
19165
|
-
return;
|
19166
|
-
}
|
19167
|
-
|
19168
|
-
// tick to speed up FRAG_CHANGED triggering
|
19169
|
-
_this.tick();
|
19170
|
-
};
|
19171
|
-
_this.registerListeners();
|
19055
|
+
_this._registerListeners();
|
19172
19056
|
return _this;
|
19173
19057
|
}
|
19174
19058
|
var _proto = StreamController.prototype;
|
19175
|
-
_proto.
|
19176
|
-
_BaseStreamController.prototype.registerListeners.call(this);
|
19059
|
+
_proto._registerListeners = function _registerListeners() {
|
19177
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);
|
19178
19064
|
hls.on(Events.MANIFEST_PARSED, this.onManifestParsed, this);
|
19179
19065
|
hls.on(Events.LEVEL_LOADING, this.onLevelLoading, this);
|
19180
19066
|
hls.on(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
19181
19067
|
hls.on(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
|
19068
|
+
hls.on(Events.ERROR, this.onError, this);
|
19182
19069
|
hls.on(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
|
19183
19070
|
hls.on(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
|
19184
19071
|
hls.on(Events.BUFFER_CREATED, this.onBufferCreated, this);
|
@@ -19186,12 +19073,15 @@
|
|
19186
19073
|
hls.on(Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
|
19187
19074
|
hls.on(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
19188
19075
|
};
|
19189
|
-
_proto.
|
19190
|
-
_BaseStreamController.prototype.unregisterListeners.call(this);
|
19076
|
+
_proto._unregisterListeners = function _unregisterListeners() {
|
19191
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);
|
19192
19081
|
hls.off(Events.MANIFEST_PARSED, this.onManifestParsed, this);
|
19193
19082
|
hls.off(Events.LEVEL_LOADED, this.onLevelLoaded, this);
|
19194
19083
|
hls.off(Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
|
19084
|
+
hls.off(Events.ERROR, this.onError, this);
|
19195
19085
|
hls.off(Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
|
19196
19086
|
hls.off(Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
|
19197
19087
|
hls.off(Events.BUFFER_CREATED, this.onBufferCreated, this);
|
@@ -19200,9 +19090,7 @@
|
|
19200
19090
|
hls.off(Events.FRAG_BUFFERED, this.onFragBuffered, this);
|
19201
19091
|
};
|
19202
19092
|
_proto.onHandlerDestroying = function onHandlerDestroying() {
|
19203
|
-
|
19204
|
-
this.onMediaPlaying = this.onMediaSeeked = null;
|
19205
|
-
this.unregisterListeners();
|
19093
|
+
this._unregisterListeners();
|
19206
19094
|
_BaseStreamController.prototype.onHandlerDestroying.call(this);
|
19207
19095
|
};
|
19208
19096
|
_proto.startLoad = function startLoad(startPosition) {
|
@@ -19517,15 +19405,18 @@
|
|
19517
19405
|
_proto.onMediaAttached = function onMediaAttached(event, data) {
|
19518
19406
|
_BaseStreamController.prototype.onMediaAttached.call(this, event, data);
|
19519
19407
|
var media = data.media;
|
19520
|
-
|
19521
|
-
|
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);
|
19522
19412
|
this.gapController = new GapController(this.config, media, this.fragmentTracker, this.hls);
|
19523
19413
|
};
|
19524
19414
|
_proto.onMediaDetaching = function onMediaDetaching() {
|
19525
19415
|
var media = this.media;
|
19526
|
-
if (media) {
|
19527
|
-
media.removeEventListener('playing', this.
|
19528
|
-
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;
|
19529
19420
|
this.videoBuffer = null;
|
19530
19421
|
}
|
19531
19422
|
this.fragPlaying = null;
|
@@ -19535,6 +19426,27 @@
|
|
19535
19426
|
}
|
19536
19427
|
_BaseStreamController.prototype.onMediaDetaching.call(this);
|
19537
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
|
+
};
|
19538
19450
|
_proto.onManifestLoading = function onManifestLoading() {
|
19539
19451
|
// reset buffer on manifest loading
|
19540
19452
|
this.log('Trigger BUFFER_RESET');
|
@@ -20281,10 +20193,6 @@
|
|
20281
20193
|
* The configuration object provided on player instantiation.
|
20282
20194
|
*/
|
20283
20195
|
this.userConfig = void 0;
|
20284
|
-
/**
|
20285
|
-
* The logger functions used by this player instance, configured on player instantiation.
|
20286
|
-
*/
|
20287
|
-
this.logger = void 0;
|
20288
20196
|
this.coreComponents = void 0;
|
20289
20197
|
this.networkControllers = void 0;
|
20290
20198
|
this.started = false;
|
@@ -20304,11 +20212,11 @@
|
|
20304
20212
|
this._media = null;
|
20305
20213
|
this.url = null;
|
20306
20214
|
this.triggeringException = void 0;
|
20307
|
-
|
20308
|
-
var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig
|
20215
|
+
enableLogs(userConfig.debug || false, 'Hls instance');
|
20216
|
+
var config = this.config = mergeConfig(Hls.DefaultConfig, userConfig);
|
20309
20217
|
this.userConfig = userConfig;
|
20310
20218
|
if (config.progressive) {
|
20311
|
-
enableStreamingMode(config
|
20219
|
+
enableStreamingMode(config);
|
20312
20220
|
}
|
20313
20221
|
|
20314
20222
|
// core controllers and network loaders
|
@@ -20416,7 +20324,7 @@
|
|
20416
20324
|
try {
|
20417
20325
|
return this.emit(event, event, eventObject);
|
20418
20326
|
} catch (error) {
|
20419
|
-
|
20327
|
+
logger.error('An internal error happened while handling event ' + event + '. Error message: "' + error.message + '". Here is a stacktrace:', error);
|
20420
20328
|
// Prevent recursion in error event handlers that throw #5497
|
20421
20329
|
if (!this.triggeringException) {
|
20422
20330
|
this.triggeringException = true;
|
@@ -20442,7 +20350,7 @@
|
|
20442
20350
|
* Dispose of the instance
|
20443
20351
|
*/;
|
20444
20352
|
_proto.destroy = function destroy() {
|
20445
|
-
|
20353
|
+
logger.log('destroy');
|
20446
20354
|
this.trigger(Events.DESTROYING, undefined);
|
20447
20355
|
this.detachMedia();
|
20448
20356
|
this.removeAllListeners();
|
@@ -20467,7 +20375,7 @@
|
|
20467
20375
|
* Attaches Hls.js to a media element
|
20468
20376
|
*/;
|
20469
20377
|
_proto.attachMedia = function attachMedia(media) {
|
20470
|
-
|
20378
|
+
logger.log('attachMedia');
|
20471
20379
|
this._media = media;
|
20472
20380
|
this.trigger(Events.MEDIA_ATTACHING, {
|
20473
20381
|
media: media
|
@@ -20478,7 +20386,7 @@
|
|
20478
20386
|
* Detach Hls.js from the media
|
20479
20387
|
*/;
|
20480
20388
|
_proto.detachMedia = function detachMedia() {
|
20481
|
-
|
20389
|
+
logger.log('detachMedia');
|
20482
20390
|
this.trigger(Events.MEDIA_DETACHING, undefined);
|
20483
20391
|
this._media = null;
|
20484
20392
|
}
|
@@ -20495,7 +20403,7 @@
|
|
20495
20403
|
});
|
20496
20404
|
this._autoLevelCapping = -1;
|
20497
20405
|
this._maxHdcpLevel = null;
|
20498
|
-
|
20406
|
+
logger.log("loadSource:" + loadingSource);
|
20499
20407
|
if (media && loadedSource && (loadedSource !== loadingSource || this.bufferController.hasSourceTypes())) {
|
20500
20408
|
this.detachMedia();
|
20501
20409
|
this.attachMedia(media);
|
@@ -20517,7 +20425,7 @@
|
|
20517
20425
|
if (startPosition === void 0) {
|
20518
20426
|
startPosition = -1;
|
20519
20427
|
}
|
20520
|
-
|
20428
|
+
logger.log("startLoad(" + startPosition + ")");
|
20521
20429
|
this.started = true;
|
20522
20430
|
this.networkControllers.forEach(function (controller) {
|
20523
20431
|
controller.startLoad(startPosition);
|
@@ -20528,7 +20436,7 @@
|
|
20528
20436
|
* Stop loading of any stream data.
|
20529
20437
|
*/;
|
20530
20438
|
_proto.stopLoad = function stopLoad() {
|
20531
|
-
|
20439
|
+
logger.log('stopLoad');
|
20532
20440
|
this.started = false;
|
20533
20441
|
this.networkControllers.forEach(function (controller) {
|
20534
20442
|
controller.stopLoad();
|
@@ -20564,7 +20472,7 @@
|
|
20564
20472
|
* Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1)
|
20565
20473
|
*/;
|
20566
20474
|
_proto.swapAudioCodec = function swapAudioCodec() {
|
20567
|
-
|
20475
|
+
logger.log('swapAudioCodec');
|
20568
20476
|
this.streamController.swapAudioCodec();
|
20569
20477
|
}
|
20570
20478
|
|
@@ -20575,7 +20483,7 @@
|
|
20575
20483
|
* Automatic recovery of media-errors by this process is configurable.
|
20576
20484
|
*/;
|
20577
20485
|
_proto.recoverMediaError = function recoverMediaError() {
|
20578
|
-
|
20486
|
+
logger.log('recoverMediaError');
|
20579
20487
|
var media = this._media;
|
20580
20488
|
this.detachMedia();
|
20581
20489
|
if (media) {
|
@@ -20630,7 +20538,7 @@
|
|
20630
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.
|
20631
20539
|
*/,
|
20632
20540
|
set: function set(newLevel) {
|
20633
|
-
|
20541
|
+
logger.log("set currentLevel:" + newLevel);
|
20634
20542
|
this.levelController.manualLevel = newLevel;
|
20635
20543
|
this.streamController.immediateLevelSwitch();
|
20636
20544
|
}
|
@@ -20651,7 +20559,7 @@
|
|
20651
20559
|
* @param newLevel - Pass -1 for automatic level selection
|
20652
20560
|
*/,
|
20653
20561
|
set: function set(newLevel) {
|
20654
|
-
|
20562
|
+
logger.log("set nextLevel:" + newLevel);
|
20655
20563
|
this.levelController.manualLevel = newLevel;
|
20656
20564
|
this.streamController.nextLevelSwitch();
|
20657
20565
|
}
|
@@ -20672,7 +20580,7 @@
|
|
20672
20580
|
* @param newLevel - Pass -1 for automatic level selection
|
20673
20581
|
*/,
|
20674
20582
|
set: function set(newLevel) {
|
20675
|
-
|
20583
|
+
logger.log("set loadLevel:" + newLevel);
|
20676
20584
|
this.levelController.manualLevel = newLevel;
|
20677
20585
|
}
|
20678
20586
|
|
@@ -20707,7 +20615,7 @@
|
|
20707
20615
|
* Sets "first-level", see getter.
|
20708
20616
|
*/,
|
20709
20617
|
set: function set(newLevel) {
|
20710
|
-
|
20618
|
+
logger.log("set firstLevel:" + newLevel);
|
20711
20619
|
this.levelController.firstLevel = newLevel;
|
20712
20620
|
}
|
20713
20621
|
|
@@ -20734,7 +20642,7 @@
|
|
20734
20642
|
* (determined from download of first segment)
|
20735
20643
|
*/,
|
20736
20644
|
set: function set(newLevel) {
|
20737
|
-
|
20645
|
+
logger.log("set startLevel:" + newLevel);
|
20738
20646
|
// if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
|
20739
20647
|
if (newLevel !== -1) {
|
20740
20648
|
newLevel = Math.max(newLevel, this.minAutoLevel);
|
@@ -20787,7 +20695,7 @@
|
|
20787
20695
|
*/
|
20788
20696
|
function set(newLevel) {
|
20789
20697
|
if (this._autoLevelCapping !== newLevel) {
|
20790
|
-
|
20698
|
+
logger.log("set autoLevelCapping:" + newLevel);
|
20791
20699
|
this._autoLevelCapping = newLevel;
|
20792
20700
|
this.levelController.checkMaxAutoUpdated();
|
20793
20701
|
}
|
@@ -21112,7 +21020,7 @@
|
|
21112
21020
|
* Get the video-dev/hls.js package version.
|
21113
21021
|
*/
|
21114
21022
|
function get() {
|
21115
|
-
return "1.5.2
|
21023
|
+
return "1.5.2";
|
21116
21024
|
}
|
21117
21025
|
}, {
|
21118
21026
|
key: "Events",
|