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 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.11352");
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 level.videoCodec !== undefined && (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) {
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
- var audioCodecs = level.audioCodec;
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
- if (videoCodecs) {
3211
- var baseVideoConfiguration = {
3212
- width: level.width,
3213
- height: level.height,
3214
- bitrate: Math.ceil(Math.max(level.bitrate * 0.9, level.averageBitrate)),
3215
- // Assume a framerate of 30fps since MediaCapabilities will not accept Level default of 0.
3216
- framerate: level.frameRate || 30
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
- var videoRange = level.videoRange;
3219
- if (videoRange !== 'SDR') {
3220
- baseVideoConfiguration.transferFunction = videoRange.toLowerCase();
3224
+ if (videoCount) {
3225
+ configuration.video = videoDecodeList[i % videoCount];
3221
3226
  }
3222
- var videoCodecsArray = videoCodecs.split(',');
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 (videoCodecsArray.some(function (videoCodec) {
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 sting: (" + ua + ")"), configurations));
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 SUPPORTED_INFO_CACHE[decodingInfoKey] || (SUPPORTED_INFO_CACHE[decodingInfoKey] = mediaCapabilities.decodingInfo(configuration));
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
- var mediaConfig = video || audio;
3291
- if (mediaConfig) {
3292
- var codec = getCodecsForMimeType(mediaConfig.contentType);
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
- return '';
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' && (requiresMediaCapabilitiesDecodingInfo(levelInfo, audioTracksByGroup, currentVideoRange, currentFrameRate, currentBw, audioPreference) || isHEVC(levelInfo.videoCodec)) // Force media capabilities check for HEVC to avoid failure on Windows
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 && !((_levelInfo$supportedR = levelInfo.supportedResult.decodingInfoResults) != null && _levelInfo$supportedR[0].smooth)) {
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.11352";
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;