hls.js 1.6.6-0.canary.11352 → 1.6.6-0.canary.11353
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hls.d.mts +1 -0
- package/dist/hls.d.ts +1 -0
- package/dist/hls.js +126 -72
- package/dist/hls.js.d.ts +1 -0
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +135 -89
- 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 +125 -80
- 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 +117 -68
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/package.json +1 -1
- package/src/controller/abr-controller.ts +21 -7
- package/src/utils/mediacapabilities-helper.ts +135 -81
package/dist/hls.d.mts
CHANGED
@@ -20,6 +20,7 @@ export declare class AbrController extends Logger implements AbrComponentAPI {
|
|
20
20
|
private partCurrent;
|
21
21
|
private bitrateTestDelay;
|
22
22
|
private rebufferNotice;
|
23
|
+
private supportedCache;
|
23
24
|
bwEstimator: EwmaBandWidthEstimator;
|
24
25
|
constructor(hls: Hls);
|
25
26
|
resetEstimator(abrEwmaDefaultEstimate?: number): void;
|
package/dist/hls.d.ts
CHANGED
@@ -20,6 +20,7 @@ export declare class AbrController extends Logger implements AbrComponentAPI {
|
|
20
20
|
private partCurrent;
|
21
21
|
private bitrateTestDelay;
|
22
22
|
private rebufferNotice;
|
23
|
+
private supportedCache;
|
23
24
|
bwEstimator: EwmaBandWidthEstimator;
|
24
25
|
constructor(hls: Hls);
|
25
26
|
resetEstimator(abrEwmaDefaultEstimate?: number): void;
|
package/dist/hls.js
CHANGED
@@ -1165,7 +1165,7 @@
|
|
1165
1165
|
// Some browsers don't allow to use bind on console object anyway
|
1166
1166
|
// fallback to default if needed
|
1167
1167
|
try {
|
1168
|
-
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.6-0.canary.
|
1168
|
+
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.6-0.canary.11353");
|
1169
1169
|
} catch (e) {
|
1170
1170
|
/* log fn threw an exception. All logger methods are no-ops. */
|
1171
1171
|
return createLogger();
|
@@ -3163,9 +3163,9 @@
|
|
3163
3163
|
error: error
|
3164
3164
|
};
|
3165
3165
|
}
|
3166
|
-
var SUPPORTED_INFO_CACHE = {};
|
3167
3166
|
function requiresMediaCapabilitiesDecodingInfo(level, audioTracksByGroup, currentVideoRange, currentFrameRate, currentBw, audioPreference) {
|
3168
3167
|
// Only test support when configuration is exceeds minimum options
|
3168
|
+
var videoCodecs = level.videoCodec;
|
3169
3169
|
var audioGroups = level.audioCodec ? level.audioGroups : null;
|
3170
3170
|
var audioCodecPreference = audioPreference == null ? void 0 : audioPreference.audioCodec;
|
3171
3171
|
var channelsPreference = audioPreference == null ? void 0 : audioPreference.channels;
|
@@ -3196,77 +3196,56 @@
|
|
3196
3196
|
return true;
|
3197
3197
|
}
|
3198
3198
|
}
|
3199
|
-
return
|
3199
|
+
return videoCodecs !== undefined && (
|
3200
|
+
// Force media capabilities check for HEVC to avoid failure on Windows
|
3201
|
+
videoCodecs.split(',').some(function (videoCodec) {
|
3202
|
+
return isHEVC(videoCodec);
|
3203
|
+
}) || level.width > 1920 && level.height > 1088 || level.height > 1920 && level.width > 1088 || level.frameRate > Math.max(currentFrameRate, 30) || level.videoRange !== 'SDR' && level.videoRange !== currentVideoRange || level.bitrate > Math.max(currentBw, 8e6)) || !!audioChannels && isFiniteNumber(maxChannels) && Object.keys(audioChannels).some(function (channels) {
|
3200
3204
|
return parseInt(channels) > maxChannels;
|
3201
3205
|
});
|
3202
3206
|
}
|
3203
|
-
function getMediaDecodingInfoPromise(level, audioTracksByGroup, mediaCapabilities) {
|
3207
|
+
function getMediaDecodingInfoPromise(level, audioTracksByGroup, mediaCapabilities, cache) {
|
3208
|
+
if (cache === void 0) {
|
3209
|
+
cache = {};
|
3210
|
+
}
|
3204
3211
|
var videoCodecs = level.videoCodec;
|
3205
|
-
|
3206
|
-
if (!videoCodecs && !audioCodecs || !mediaCapabilities) {
|
3212
|
+
if (!videoCodecs && !level.audioCodec || !mediaCapabilities) {
|
3207
3213
|
return Promise.resolve(SUPPORTED_INFO_DEFAULT);
|
3208
3214
|
}
|
3209
3215
|
var configurations = [];
|
3210
|
-
|
3211
|
-
|
3212
|
-
|
3213
|
-
|
3214
|
-
|
3215
|
-
|
3216
|
-
|
3216
|
+
var videoDecodeList = makeVideoConfigurations(level);
|
3217
|
+
var videoCount = videoDecodeList.length;
|
3218
|
+
var audioDecodeList = makeAudioConfigurations(level, audioTracksByGroup, videoCount > 0);
|
3219
|
+
var audioCount = audioDecodeList.length;
|
3220
|
+
for (var i = videoCount || 1 * audioCount || 1; i--;) {
|
3221
|
+
var configuration = {
|
3222
|
+
type: 'media-source'
|
3217
3223
|
};
|
3218
|
-
|
3219
|
-
|
3220
|
-
baseVideoConfiguration.transferFunction = videoRange.toLowerCase();
|
3224
|
+
if (videoCount) {
|
3225
|
+
configuration.video = videoDecodeList[i % videoCount];
|
3221
3226
|
}
|
3222
|
-
|
3227
|
+
if (audioCount) {
|
3228
|
+
configuration.audio = audioDecodeList[i % audioCount];
|
3229
|
+
var audioBitrate = configuration.audio.bitrate;
|
3230
|
+
if (configuration.video && audioBitrate) {
|
3231
|
+
configuration.video.bitrate -= audioBitrate;
|
3232
|
+
}
|
3233
|
+
}
|
3234
|
+
configurations.push(configuration);
|
3235
|
+
}
|
3236
|
+
if (videoCodecs) {
|
3223
3237
|
// Override Windows Firefox HEVC MediaCapabilities result (https://github.com/video-dev/hls.js/issues/7046)
|
3224
3238
|
var ua = navigator.userAgent;
|
3225
|
-
if (
|
3239
|
+
if (videoCodecs.split(',').some(function (videoCodec) {
|
3226
3240
|
return isHEVC(videoCodec);
|
3227
3241
|
}) && userAgentHevcSupportIsInaccurate()) {
|
3228
|
-
return Promise.resolve(getUnsupportedResult(new Error("Overriding Windows Firefox HEVC MediaCapabilities result based on user-agent
|
3242
|
+
return Promise.resolve(getUnsupportedResult(new Error("Overriding Windows Firefox HEVC MediaCapabilities result based on user-agent string: (" + ua + ")"), configurations));
|
3229
3243
|
}
|
3230
|
-
configurations.push.apply(configurations, videoCodecsArray.map(function (videoCodec) {
|
3231
|
-
return {
|
3232
|
-
type: 'media-source',
|
3233
|
-
video: _objectSpread2(_objectSpread2({}, baseVideoConfiguration), {}, {
|
3234
|
-
contentType: mimeTypeForCodec(fillInMissingAV01Params(videoCodec), 'video')
|
3235
|
-
})
|
3236
|
-
};
|
3237
|
-
}));
|
3238
|
-
}
|
3239
|
-
if (audioCodecs && level.audioGroups) {
|
3240
|
-
level.audioGroups.forEach(function (audioGroupId) {
|
3241
|
-
var _audioTracksByGroup$g;
|
3242
|
-
if (!audioGroupId) {
|
3243
|
-
return;
|
3244
|
-
}
|
3245
|
-
(_audioTracksByGroup$g = audioTracksByGroup.groups[audioGroupId]) == null ? void 0 : _audioTracksByGroup$g.tracks.forEach(function (audioTrack) {
|
3246
|
-
if (audioTrack.groupId === audioGroupId) {
|
3247
|
-
var channels = audioTrack.channels || '';
|
3248
|
-
var channelsNumber = parseFloat(channels);
|
3249
|
-
if (isFiniteNumber(channelsNumber) && channelsNumber > 2) {
|
3250
|
-
configurations.push.apply(configurations, audioCodecs.split(',').map(function (audioCodec) {
|
3251
|
-
return {
|
3252
|
-
type: 'media-source',
|
3253
|
-
audio: {
|
3254
|
-
contentType: mimeTypeForCodec(audioCodec, 'audio'),
|
3255
|
-
channels: '' + channelsNumber
|
3256
|
-
// spatialRendering:
|
3257
|
-
// audioCodec === 'ec-3' && channels.indexOf('JOC'),
|
3258
|
-
}
|
3259
|
-
};
|
3260
|
-
}));
|
3261
|
-
}
|
3262
|
-
}
|
3263
|
-
});
|
3264
|
-
});
|
3265
3244
|
}
|
3266
3245
|
return Promise.all(configurations.map(function (configuration) {
|
3267
3246
|
// Cache MediaCapabilities promises
|
3268
3247
|
var decodingInfoKey = getMediaDecodingInfoKey(configuration);
|
3269
|
-
return
|
3248
|
+
return cache[decodingInfoKey] || (cache[decodingInfoKey] = mediaCapabilities.decodingInfo(configuration));
|
3270
3249
|
})).then(function (decodingInfoResults) {
|
3271
3250
|
return {
|
3272
3251
|
supported: !decodingInfoResults.some(function (info) {
|
@@ -3284,20 +3263,88 @@
|
|
3284
3263
|
};
|
3285
3264
|
});
|
3286
3265
|
}
|
3266
|
+
function makeVideoConfigurations(level) {
|
3267
|
+
var _level$videoCodec;
|
3268
|
+
var videoCodecs = (_level$videoCodec = level.videoCodec) == null ? void 0 : _level$videoCodec.split(',');
|
3269
|
+
var bitrate = getVariantDecodingBitrate(level);
|
3270
|
+
var width = level.width || 640;
|
3271
|
+
var height = level.height || 480;
|
3272
|
+
// Assume a framerate of 30fps since MediaCapabilities will not accept Level default of 0.
|
3273
|
+
var framerate = level.frameRate || 30;
|
3274
|
+
var videoRange = level.videoRange.toLowerCase();
|
3275
|
+
return videoCodecs ? videoCodecs.map(function (videoCodec) {
|
3276
|
+
var videoConfiguration = {
|
3277
|
+
contentType: mimeTypeForCodec(fillInMissingAV01Params(videoCodec), 'video'),
|
3278
|
+
width: width,
|
3279
|
+
height: height,
|
3280
|
+
bitrate: bitrate,
|
3281
|
+
framerate: framerate
|
3282
|
+
};
|
3283
|
+
if (videoRange !== 'sdr') {
|
3284
|
+
videoConfiguration.transferFunction = videoRange;
|
3285
|
+
}
|
3286
|
+
return videoConfiguration;
|
3287
|
+
}) : [];
|
3288
|
+
}
|
3289
|
+
function makeAudioConfigurations(level, audioTracksByGroup, hasVideo) {
|
3290
|
+
var _level$audioCodec;
|
3291
|
+
var audioCodecs = (_level$audioCodec = level.audioCodec) == null ? void 0 : _level$audioCodec.split(',');
|
3292
|
+
var combinedBitrate = getVariantDecodingBitrate(level);
|
3293
|
+
if (audioCodecs && level.audioGroups) {
|
3294
|
+
return level.audioGroups.reduce(function (configurations, audioGroupId) {
|
3295
|
+
var _audioTracksByGroup$g;
|
3296
|
+
var tracks = audioGroupId ? (_audioTracksByGroup$g = audioTracksByGroup.groups[audioGroupId]) == null ? void 0 : _audioTracksByGroup$g.tracks : null;
|
3297
|
+
if (tracks) {
|
3298
|
+
return tracks.reduce(function (configs, audioTrack) {
|
3299
|
+
if (audioTrack.groupId === audioGroupId) {
|
3300
|
+
var channelsNumber = parseFloat(audioTrack.channels || '');
|
3301
|
+
audioCodecs.forEach(function (audioCodec) {
|
3302
|
+
var audioConfiguration = {
|
3303
|
+
contentType: mimeTypeForCodec(audioCodec, 'audio'),
|
3304
|
+
bitrate: hasVideo ? estimatedAudioBitrate(audioCodec, combinedBitrate) : combinedBitrate
|
3305
|
+
};
|
3306
|
+
if (channelsNumber) {
|
3307
|
+
audioConfiguration.channels = '' + channelsNumber;
|
3308
|
+
}
|
3309
|
+
configs.push(audioConfiguration);
|
3310
|
+
});
|
3311
|
+
}
|
3312
|
+
return configs;
|
3313
|
+
}, configurations);
|
3314
|
+
}
|
3315
|
+
return configurations;
|
3316
|
+
}, []);
|
3317
|
+
}
|
3318
|
+
return [];
|
3319
|
+
}
|
3320
|
+
function estimatedAudioBitrate(audioCodec, levelBitrate) {
|
3321
|
+
if (levelBitrate <= 1) {
|
3322
|
+
return 1;
|
3323
|
+
}
|
3324
|
+
var audioBitrate = 128000;
|
3325
|
+
if (audioCodec === 'ec-3') {
|
3326
|
+
audioBitrate = 768000;
|
3327
|
+
} else if (audioCodec === 'ac-3') {
|
3328
|
+
audioBitrate = 640000;
|
3329
|
+
}
|
3330
|
+
return Math.min(levelBitrate / 2, audioBitrate); // Don't exceed some % of level bitrate
|
3331
|
+
}
|
3332
|
+
function getVariantDecodingBitrate(level) {
|
3333
|
+
return Math.ceil(Math.max(level.bitrate * 0.9, level.averageBitrate) / 1000) * 1000 || 1;
|
3334
|
+
}
|
3287
3335
|
function getMediaDecodingInfoKey(config) {
|
3336
|
+
var key = '';
|
3288
3337
|
var audio = config.audio,
|
3289
3338
|
video = config.video;
|
3290
|
-
|
3291
|
-
|
3292
|
-
|
3293
|
-
if (video) {
|
3294
|
-
return "r" + video.height + "x" + video.width + "f" + Math.ceil(video.framerate) + (video.transferFunction || 'sd') + "_" + codec + "_" + Math.ceil(video.bitrate / 1e5);
|
3295
|
-
}
|
3296
|
-
if (audio) {
|
3297
|
-
return "c" + audio.channels + (audio.spatialRendering ? 's' : 'n') + "_" + codec;
|
3298
|
-
}
|
3339
|
+
if (video) {
|
3340
|
+
var codec = getCodecsForMimeType(video.contentType);
|
3341
|
+
key += codec + "_r" + video.height + "x" + video.width + "f" + Math.ceil(video.framerate) + (video.transferFunction || 'sd') + "_" + Math.ceil(video.bitrate / 1e5);
|
3299
3342
|
}
|
3300
|
-
|
3343
|
+
if (audio) {
|
3344
|
+
var _codec = getCodecsForMimeType(audio.contentType);
|
3345
|
+
key += "" + (video ? '_' : '') + _codec + "_c" + audio.channels;
|
3346
|
+
}
|
3347
|
+
return key;
|
3301
3348
|
}
|
3302
3349
|
|
3303
3350
|
var HdcpLevels = ['NONE', 'TYPE-0', 'TYPE-1', null];
|
@@ -3945,6 +3992,7 @@
|
|
3945
3992
|
_this.partCurrent = null;
|
3946
3993
|
_this.bitrateTestDelay = 0;
|
3947
3994
|
_this.rebufferNotice = -1;
|
3995
|
+
_this.supportedCache = {};
|
3948
3996
|
_this.bwEstimator = void 0;
|
3949
3997
|
/*
|
3950
3998
|
This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
|
@@ -4141,13 +4189,14 @@
|
|
4141
4189
|
this.unregisterListeners();
|
4142
4190
|
this.clearTimer();
|
4143
4191
|
// @ts-ignore
|
4144
|
-
this.hls = this._abandonRulesCheck = null;
|
4192
|
+
this.hls = this._abandonRulesCheck = this.supportedCache = null;
|
4145
4193
|
this.fragCurrent = this.partCurrent = null;
|
4146
4194
|
};
|
4147
4195
|
_proto.onManifestLoading = function onManifestLoading(event, data) {
|
4148
4196
|
this.lastLoadedFragLevel = -1;
|
4149
4197
|
this.firstSelection = -1;
|
4150
4198
|
this.lastLevelLoadSec = 0;
|
4199
|
+
this.supportedCache = {};
|
4151
4200
|
this.fragCurrent = this.partCurrent = null;
|
4152
4201
|
this.onLevelsUpdated();
|
4153
4202
|
this.clearTimer();
|
@@ -4441,7 +4490,7 @@
|
|
4441
4490
|
var ttfbEstimateSec = this.bwEstimator.getEstimateTTFB() / 1000;
|
4442
4491
|
var levelsSkipped = [];
|
4443
4492
|
var _loop = function _loop() {
|
4444
|
-
var _levelInfo$supportedR;
|
4493
|
+
var _levelInfo$supportedR, _levelInfo$supportedR2;
|
4445
4494
|
var levelInfo = levels[i];
|
4446
4495
|
var upSwitch = i > selectionBaseLevel;
|
4447
4496
|
if (!levelInfo) {
|
@@ -4449,9 +4498,8 @@
|
|
4449
4498
|
}
|
4450
4499
|
if (config.useMediaCapabilities && !levelInfo.supportedResult && !levelInfo.supportedPromise) {
|
4451
4500
|
var mediaCapabilities = navigator.mediaCapabilities;
|
4452
|
-
if (typeof (mediaCapabilities == null ? void 0 : mediaCapabilities.decodingInfo) === 'function' &&
|
4453
|
-
|
4454
|
-
levelInfo.supportedPromise = getMediaDecodingInfoPromise(levelInfo, audioTracksByGroup, mediaCapabilities);
|
4501
|
+
if (typeof (mediaCapabilities == null ? void 0 : mediaCapabilities.decodingInfo) === 'function' && requiresMediaCapabilitiesDecodingInfo(levelInfo, audioTracksByGroup, currentVideoRange, currentFrameRate, currentBw, audioPreference)) {
|
4502
|
+
levelInfo.supportedPromise = getMediaDecodingInfoPromise(levelInfo, audioTracksByGroup, mediaCapabilities, _this3.supportedCache);
|
4455
4503
|
levelInfo.supportedPromise.then(function (decodingInfo) {
|
4456
4504
|
if (!_this3.hls) {
|
4457
4505
|
return;
|
@@ -4470,6 +4518,10 @@
|
|
4470
4518
|
_this3.hls.nextLoadLevel = 0;
|
4471
4519
|
}
|
4472
4520
|
}
|
4521
|
+
} else if (decodingInfo.decodingInfoResults.some(function (info) {
|
4522
|
+
return info.smooth === false || info.powerEfficient === false;
|
4523
|
+
})) {
|
4524
|
+
_this3.log("MediaCapabilities decodingInfo for level " + index + " not smooth or powerEfficient: " + stringify(decodingInfo));
|
4473
4525
|
}
|
4474
4526
|
});
|
4475
4527
|
} else {
|
@@ -4479,7 +4531,9 @@
|
|
4479
4531
|
|
4480
4532
|
// skip candidates which change codec-family or video-range,
|
4481
4533
|
// and which decrease or increase frame-rate for up and down-switch respectfully
|
4482
|
-
if (currentCodecSet && levelInfo.codecSet !== currentCodecSet || currentVideoRange && levelInfo.videoRange !== currentVideoRange || upSwitch && currentFrameRate > levelInfo.frameRate || !upSwitch && currentFrameRate > 0 && currentFrameRate < levelInfo.frameRate || levelInfo.supportedResult &&
|
4534
|
+
if (currentCodecSet && levelInfo.codecSet !== currentCodecSet || currentVideoRange && levelInfo.videoRange !== currentVideoRange || upSwitch && currentFrameRate > levelInfo.frameRate || !upSwitch && currentFrameRate > 0 && currentFrameRate < levelInfo.frameRate || (_levelInfo$supportedR = levelInfo.supportedResult) != null && (_levelInfo$supportedR2 = _levelInfo$supportedR.decodingInfoResults) != null && _levelInfo$supportedR2.some(function (info) {
|
4535
|
+
return info.smooth === false;
|
4536
|
+
})) {
|
4483
4537
|
if (!firstSelection || i !== minStartIndex) {
|
4484
4538
|
levelsSkipped.push(i);
|
4485
4539
|
return 0; // continue
|
@@ -16671,7 +16725,7 @@
|
|
16671
16725
|
return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
|
16672
16726
|
}
|
16673
16727
|
|
16674
|
-
var version = "1.6.6-0.canary.
|
16728
|
+
var version = "1.6.6-0.canary.11353";
|
16675
16729
|
|
16676
16730
|
// ensure the worker ends up in the bundle
|
16677
16731
|
// If the worker should not be included this gets aliased to empty.js
|
package/dist/hls.js.d.ts
CHANGED
@@ -20,6 +20,7 @@ export declare class AbrController extends Logger implements AbrComponentAPI {
|
|
20
20
|
private partCurrent;
|
21
21
|
private bitrateTestDelay;
|
22
22
|
private rebufferNotice;
|
23
|
+
private supportedCache;
|
23
24
|
bwEstimator: EwmaBandWidthEstimator;
|
24
25
|
constructor(hls: Hls);
|
25
26
|
resetEstimator(abrEwmaDefaultEstimate?: number): void;
|