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.
@@ -523,7 +523,7 @@ function enableLogs(debugConfig, context, id) {
523
523
  // Some browsers don't allow to use bind on console object anyway
524
524
  // fallback to default if needed
525
525
  try {
526
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.6-0.canary.11352"}`);
526
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.6.6-0.canary.11353"}`);
527
527
  } catch (e) {
528
528
  /* log fn threw an exception. All logger methods are no-ops. */
529
529
  return createLogger();
@@ -560,6 +560,22 @@ function requireEmptyEs() {
560
560
  var emptyEsExports = requireEmptyEs();
561
561
  var Cues = /*@__PURE__*/getDefaultExportFromCjs(emptyEsExports);
562
562
 
563
+ function getMediaSource(preferManagedMediaSource = true) {
564
+ if (typeof self === 'undefined') return undefined;
565
+ const mms = (preferManagedMediaSource || !self.MediaSource) && self.ManagedMediaSource;
566
+ return mms || self.MediaSource || self.WebKitMediaSource;
567
+ }
568
+ function isManagedMediaSource(source) {
569
+ return typeof self !== 'undefined' && source === self.ManagedMediaSource;
570
+ }
571
+ function isCompatibleTrackChange(currentTracks, requiredTracks) {
572
+ const trackNames = Object.keys(currentTracks);
573
+ const requiredTrackNames = Object.keys(requiredTracks);
574
+ const trackCount = trackNames.length;
575
+ const requiredTrackCount = requiredTrackNames.length;
576
+ return !trackCount || !requiredTrackCount || trackCount === requiredTrackCount && !trackNames.some(name => requiredTrackNames.indexOf(name) === -1);
577
+ }
578
+
563
579
  // http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197
564
580
  // http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt
565
581
  /* utf.js - UTF-8 <=> UTF-16 convertion
@@ -2252,22 +2268,6 @@ function parseEmsg(data) {
2252
2268
  };
2253
2269
  }
2254
2270
 
2255
- function getMediaSource(preferManagedMediaSource = true) {
2256
- if (typeof self === 'undefined') return undefined;
2257
- const mms = (preferManagedMediaSource || !self.MediaSource) && self.ManagedMediaSource;
2258
- return mms || self.MediaSource || self.WebKitMediaSource;
2259
- }
2260
- function isManagedMediaSource(source) {
2261
- return typeof self !== 'undefined' && source === self.ManagedMediaSource;
2262
- }
2263
- function isCompatibleTrackChange(currentTracks, requiredTracks) {
2264
- const trackNames = Object.keys(currentTracks);
2265
- const requiredTrackNames = Object.keys(requiredTracks);
2266
- const trackCount = trackNames.length;
2267
- const requiredTrackCount = requiredTrackNames.length;
2268
- return !trackCount || !requiredTrackCount || trackCount === requiredTrackCount && !trackNames.some(name => requiredTrackNames.indexOf(name) === -1);
2269
- }
2270
-
2271
2271
  const userAgentHevcSupportIsInaccurate = () => {
2272
2272
  return /\(Windows.+Firefox\//i.test(navigator.userAgent);
2273
2273
  };
@@ -2958,6 +2958,7 @@ class AbrController extends Logger {
2958
2958
  this.partCurrent = null;
2959
2959
  this.bitrateTestDelay = 0;
2960
2960
  this.rebufferNotice = -1;
2961
+ this.supportedCache = {};
2961
2962
  this.bwEstimator = void 0;
2962
2963
  /*
2963
2964
  This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
@@ -3168,13 +3169,14 @@ class AbrController extends Logger {
3168
3169
  this.unregisterListeners();
3169
3170
  this.clearTimer();
3170
3171
  // @ts-ignore
3171
- this.hls = this._abandonRulesCheck = null;
3172
+ this.hls = this._abandonRulesCheck = this.supportedCache = null;
3172
3173
  this.fragCurrent = this.partCurrent = null;
3173
3174
  }
3174
3175
  onManifestLoading(event, data) {
3175
3176
  this.lastLoadedFragLevel = -1;
3176
3177
  this.firstSelection = -1;
3177
3178
  this.lastLevelLoadSec = 0;
3179
+ this.supportedCache = {};
3178
3180
  this.fragCurrent = this.partCurrent = null;
3179
3181
  this.onLevelsUpdated();
3180
3182
  this.clearTimer();
@@ -3535,7 +3537,7 @@ class AbrController extends Logger {
3535
3537
  const ttfbEstimateSec = this.bwEstimator.getEstimateTTFB() / 1000;
3536
3538
  const levelsSkipped = [];
3537
3539
  for (let i = maxAutoLevel; i >= minAutoLevel; i--) {
3538
- var _levelInfo$supportedR;
3540
+ var _levelInfo$supportedR, _levelInfo$supportedR2;
3539
3541
  const levelInfo = levels[i];
3540
3542
  const upSwitch = i > selectionBaseLevel;
3541
3543
  if (!levelInfo) {
@@ -3544,7 +3546,7 @@ class AbrController extends Logger {
3544
3546
 
3545
3547
  // skip candidates which change codec-family or video-range,
3546
3548
  // and which decrease or increase frame-rate for up and down-switch respectfully
3547
- 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)) {
3549
+ 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(info => info.smooth === false)) {
3548
3550
  if (!firstSelection || i !== minStartIndex) {
3549
3551
  levelsSkipped.push(i);
3550
3552
  continue;
@@ -19889,7 +19891,7 @@ function assignTrackIdsByGroup(tracks) {
19889
19891
  });
19890
19892
  }
19891
19893
 
19892
- const version = "1.6.6-0.canary.11352";
19894
+ const version = "1.6.6-0.canary.11353";
19893
19895
 
19894
19896
  // ensure the worker ends up in the bundle
19895
19897
  // If the worker should not be included this gets aliased to empty.js
@@ -22442,68 +22444,43 @@ function getUnsupportedResult(error, configurations) {
22442
22444
  error
22443
22445
  };
22444
22446
  }
22445
- const SUPPORTED_INFO_CACHE = {};
22446
- function getMediaDecodingInfoPromise(level, audioTracksByGroup, mediaCapabilities) {
22447
+ function getMediaDecodingInfoPromise(level, audioTracksByGroup, mediaCapabilities, cache = {}) {
22447
22448
  const videoCodecs = level.videoCodec;
22448
- const audioCodecs = level.audioCodec;
22449
- if (!videoCodecs && !audioCodecs || !mediaCapabilities) {
22449
+ if (!videoCodecs && !level.audioCodec || !mediaCapabilities) {
22450
22450
  return Promise.resolve(SUPPORTED_INFO_DEFAULT);
22451
22451
  }
22452
22452
  const configurations = [];
22453
- if (videoCodecs) {
22454
- const baseVideoConfiguration = {
22455
- width: level.width,
22456
- height: level.height,
22457
- bitrate: Math.ceil(Math.max(level.bitrate * 0.9, level.averageBitrate)),
22458
- // Assume a framerate of 30fps since MediaCapabilities will not accept Level default of 0.
22459
- framerate: level.frameRate || 30
22453
+ const videoDecodeList = makeVideoConfigurations(level);
22454
+ const videoCount = videoDecodeList.length;
22455
+ const audioDecodeList = makeAudioConfigurations(level, audioTracksByGroup, videoCount > 0);
22456
+ const audioCount = audioDecodeList.length;
22457
+ for (let i = videoCount || 1 * audioCount || 1; i--;) {
22458
+ const configuration = {
22459
+ type: 'media-source'
22460
22460
  };
22461
- const videoRange = level.videoRange;
22462
- if (videoRange !== 'SDR') {
22463
- baseVideoConfiguration.transferFunction = videoRange.toLowerCase();
22461
+ if (videoCount) {
22462
+ configuration.video = videoDecodeList[i % videoCount];
22463
+ }
22464
+ if (audioCount) {
22465
+ configuration.audio = audioDecodeList[i % audioCount];
22466
+ const audioBitrate = configuration.audio.bitrate;
22467
+ if (configuration.video && audioBitrate) {
22468
+ configuration.video.bitrate -= audioBitrate;
22469
+ }
22464
22470
  }
22465
- const videoCodecsArray = videoCodecs.split(',');
22471
+ configurations.push(configuration);
22472
+ }
22473
+ if (videoCodecs) {
22466
22474
  // Override Windows Firefox HEVC MediaCapabilities result (https://github.com/video-dev/hls.js/issues/7046)
22467
22475
  const ua = navigator.userAgent;
22468
- if (videoCodecsArray.some(videoCodec => isHEVC(videoCodec)) && userAgentHevcSupportIsInaccurate()) {
22469
- return Promise.resolve(getUnsupportedResult(new Error(`Overriding Windows Firefox HEVC MediaCapabilities result based on user-agent sting: (${ua})`), configurations));
22476
+ if (videoCodecs.split(',').some(videoCodec => isHEVC(videoCodec)) && userAgentHevcSupportIsInaccurate()) {
22477
+ return Promise.resolve(getUnsupportedResult(new Error(`Overriding Windows Firefox HEVC MediaCapabilities result based on user-agent string: (${ua})`), configurations));
22470
22478
  }
22471
- configurations.push.apply(configurations, videoCodecsArray.map(videoCodec => ({
22472
- type: 'media-source',
22473
- video: _objectSpread2(_objectSpread2({}, baseVideoConfiguration), {}, {
22474
- contentType: mimeTypeForCodec(fillInMissingAV01Params(videoCodec), 'video')
22475
- })
22476
- })));
22477
- }
22478
- if (audioCodecs && level.audioGroups) {
22479
- level.audioGroups.forEach(audioGroupId => {
22480
- var _audioTracksByGroup$g;
22481
- if (!audioGroupId) {
22482
- return;
22483
- }
22484
- (_audioTracksByGroup$g = audioTracksByGroup.groups[audioGroupId]) == null ? void 0 : _audioTracksByGroup$g.tracks.forEach(audioTrack => {
22485
- if (audioTrack.groupId === audioGroupId) {
22486
- const channels = audioTrack.channels || '';
22487
- const channelsNumber = parseFloat(channels);
22488
- if (isFiniteNumber(channelsNumber) && channelsNumber > 2) {
22489
- configurations.push.apply(configurations, audioCodecs.split(',').map(audioCodec => ({
22490
- type: 'media-source',
22491
- audio: {
22492
- contentType: mimeTypeForCodec(audioCodec, 'audio'),
22493
- channels: '' + channelsNumber
22494
- // spatialRendering:
22495
- // audioCodec === 'ec-3' && channels.indexOf('JOC'),
22496
- }
22497
- })));
22498
- }
22499
- }
22500
- });
22501
- });
22502
22479
  }
22503
22480
  return Promise.all(configurations.map(configuration => {
22504
22481
  // Cache MediaCapabilities promises
22505
22482
  const decodingInfoKey = getMediaDecodingInfoKey(configuration);
22506
- return SUPPORTED_INFO_CACHE[decodingInfoKey] || (SUPPORTED_INFO_CACHE[decodingInfoKey] = mediaCapabilities.decodingInfo(configuration));
22483
+ return cache[decodingInfoKey] || (cache[decodingInfoKey] = mediaCapabilities.decodingInfo(configuration));
22507
22484
  })).then(decodingInfoResults => ({
22508
22485
  supported: !decodingInfoResults.some(info => !info.supported),
22509
22486
  configurations,
@@ -22515,22 +22492,90 @@ function getMediaDecodingInfoPromise(level, audioTracksByGroup, mediaCapabilitie
22515
22492
  error
22516
22493
  }));
22517
22494
  }
22495
+ function makeVideoConfigurations(level) {
22496
+ var _level$videoCodec;
22497
+ const videoCodecs = (_level$videoCodec = level.videoCodec) == null ? void 0 : _level$videoCodec.split(',');
22498
+ const bitrate = getVariantDecodingBitrate(level);
22499
+ const width = level.width || 640;
22500
+ const height = level.height || 480;
22501
+ // Assume a framerate of 30fps since MediaCapabilities will not accept Level default of 0.
22502
+ const framerate = level.frameRate || 30;
22503
+ const videoRange = level.videoRange.toLowerCase();
22504
+ return videoCodecs ? videoCodecs.map(videoCodec => {
22505
+ const videoConfiguration = {
22506
+ contentType: mimeTypeForCodec(fillInMissingAV01Params(videoCodec), 'video'),
22507
+ width,
22508
+ height,
22509
+ bitrate,
22510
+ framerate
22511
+ };
22512
+ if (videoRange !== 'sdr') {
22513
+ videoConfiguration.transferFunction = videoRange;
22514
+ }
22515
+ return videoConfiguration;
22516
+ }) : [];
22517
+ }
22518
+ function makeAudioConfigurations(level, audioTracksByGroup, hasVideo) {
22519
+ var _level$audioCodec;
22520
+ const audioCodecs = (_level$audioCodec = level.audioCodec) == null ? void 0 : _level$audioCodec.split(',');
22521
+ const combinedBitrate = getVariantDecodingBitrate(level);
22522
+ if (audioCodecs && level.audioGroups) {
22523
+ return level.audioGroups.reduce((configurations, audioGroupId) => {
22524
+ var _audioTracksByGroup$g;
22525
+ const tracks = audioGroupId ? (_audioTracksByGroup$g = audioTracksByGroup.groups[audioGroupId]) == null ? void 0 : _audioTracksByGroup$g.tracks : null;
22526
+ if (tracks) {
22527
+ return tracks.reduce((configs, audioTrack) => {
22528
+ if (audioTrack.groupId === audioGroupId) {
22529
+ const channelsNumber = parseFloat(audioTrack.channels || '');
22530
+ audioCodecs.forEach(audioCodec => {
22531
+ const audioConfiguration = {
22532
+ contentType: mimeTypeForCodec(audioCodec, 'audio'),
22533
+ bitrate: hasVideo ? estimatedAudioBitrate(audioCodec, combinedBitrate) : combinedBitrate
22534
+ };
22535
+ if (channelsNumber) {
22536
+ audioConfiguration.channels = '' + channelsNumber;
22537
+ }
22538
+ configs.push(audioConfiguration);
22539
+ });
22540
+ }
22541
+ return configs;
22542
+ }, configurations);
22543
+ }
22544
+ return configurations;
22545
+ }, []);
22546
+ }
22547
+ return [];
22548
+ }
22549
+ function estimatedAudioBitrate(audioCodec, levelBitrate) {
22550
+ if (levelBitrate <= 1) {
22551
+ return 1;
22552
+ }
22553
+ let audioBitrate = 128000;
22554
+ if (audioCodec === 'ec-3') {
22555
+ audioBitrate = 768000;
22556
+ } else if (audioCodec === 'ac-3') {
22557
+ audioBitrate = 640000;
22558
+ }
22559
+ return Math.min(levelBitrate / 2, audioBitrate); // Don't exceed some % of level bitrate
22560
+ }
22561
+ function getVariantDecodingBitrate(level) {
22562
+ return Math.ceil(Math.max(level.bitrate * 0.9, level.averageBitrate) / 1000) * 1000 || 1;
22563
+ }
22518
22564
  function getMediaDecodingInfoKey(config) {
22565
+ let key = '';
22519
22566
  const {
22520
22567
  audio,
22521
22568
  video
22522
22569
  } = config;
22523
- const mediaConfig = video || audio;
22524
- if (mediaConfig) {
22525
- const codec = getCodecsForMimeType(mediaConfig.contentType);
22526
- if (video) {
22527
- return `r${video.height}x${video.width}f${Math.ceil(video.framerate)}${video.transferFunction || 'sd'}_${codec}_${Math.ceil(video.bitrate / 1e5)}`;
22528
- }
22529
- if (audio) {
22530
- return `c${audio.channels}${audio.spatialRendering ? 's' : 'n'}_${codec}`;
22531
- }
22570
+ if (video) {
22571
+ const codec = getCodecsForMimeType(video.contentType);
22572
+ key += `${codec}_r${video.height}x${video.width}f${Math.ceil(video.framerate)}${video.transferFunction || 'sd'}_${Math.ceil(video.bitrate / 1e5)}`;
22573
+ }
22574
+ if (audio) {
22575
+ const codec = getCodecsForMimeType(audio.contentType);
22576
+ key += `${video ? '_' : ''}${codec}_c${audio.channels}`;
22532
22577
  }
22533
- return '';
22578
+ return key;
22534
22579
  }
22535
22580
 
22536
22581
  /**