hls.js 1.5.12-0.canary.10349 → 1.5.12-0.canary.10352

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.mjs CHANGED
@@ -420,7 +420,7 @@ function enableLogs(debugConfig, context, id) {
420
420
  // Some browsers don't allow to use bind on console object anyway
421
421
  // fallback to default if needed
422
422
  try {
423
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.12-0.canary.10349"}`);
423
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.12-0.canary.10352"}`);
424
424
  } catch (e) {
425
425
  /* log fn threw an exception. All logger methods are no-ops. */
426
426
  return createLogger();
@@ -6990,10 +6990,9 @@ function getVideoSelectionOptions(currentVideoRange, videoPreference) {
6990
6990
  }
6991
6991
  if (videoPreference) {
6992
6992
  allowedVideoRanges = videoPreference.allowedVideoRanges || VideoRangeValues.slice(0);
6993
- preferHDR = videoPreference.preferHDR !== undefined ? videoPreference.preferHDR : isHdrSupported();
6994
- if (preferHDR) {
6995
- allowedVideoRanges = allowedVideoRanges.filter(range => range !== 'SDR');
6996
- } else {
6993
+ const allowAutoPreferHDR = allowedVideoRanges.join('') !== 'SDR' && !videoPreference.videoCodec;
6994
+ preferHDR = videoPreference.preferHDR !== undefined ? videoPreference.preferHDR : allowAutoPreferHDR && isHdrSupported();
6995
+ if (!preferHDR) {
6997
6996
  allowedVideoRanges = ['SDR'];
6998
6997
  }
6999
6998
  }
@@ -7007,13 +7006,15 @@ function getStartCodecTier(codecTiers, currentVideoRange, currentBw, audioPrefer
7007
7006
  const codecSets = Object.keys(codecTiers);
7008
7007
  const channelsPreference = audioPreference == null ? void 0 : audioPreference.channels;
7009
7008
  const audioCodecPreference = audioPreference == null ? void 0 : audioPreference.audioCodec;
7009
+ const videoCodecPreference = videoPreference == null ? void 0 : videoPreference.videoCodec;
7010
7010
  const preferStereo = channelsPreference && parseInt(channelsPreference) === 2;
7011
7011
  // Use first level set to determine stereo, and minimum resolution and framerate
7012
- let hasStereo = true;
7012
+ let hasStereo = false;
7013
7013
  let hasCurrentVideoRange = false;
7014
7014
  let minHeight = Infinity;
7015
7015
  let minFramerate = Infinity;
7016
7016
  let minBitrate = Infinity;
7017
+ let minIndex = Infinity;
7017
7018
  let selectedScore = 0;
7018
7019
  let videoRanges = [];
7019
7020
  const {
@@ -7022,14 +7023,13 @@ function getStartCodecTier(codecTiers, currentVideoRange, currentBw, audioPrefer
7022
7023
  } = getVideoSelectionOptions(currentVideoRange, videoPreference);
7023
7024
  for (let i = codecSets.length; i--;) {
7024
7025
  const tier = codecTiers[codecSets[i]];
7025
- hasStereo = tier.channels[2] > 0;
7026
+ hasStereo || (hasStereo = tier.channels[2] > 0);
7026
7027
  minHeight = Math.min(minHeight, tier.minHeight);
7027
7028
  minFramerate = Math.min(minFramerate, tier.minFramerate);
7028
7029
  minBitrate = Math.min(minBitrate, tier.minBitrate);
7029
7030
  const matchingVideoRanges = allowedVideoRanges.filter(range => tier.videoRanges[range] > 0);
7030
7031
  if (matchingVideoRanges.length > 0) {
7031
7032
  hasCurrentVideoRange = true;
7032
- videoRanges = matchingVideoRanges;
7033
7033
  }
7034
7034
  }
7035
7035
  minHeight = isFiniteNumber(minHeight) ? minHeight : 0;
@@ -7041,7 +7041,6 @@ function getStartCodecTier(codecTiers, currentVideoRange, currentBw, audioPrefer
7041
7041
  // If there are no variants with matching preference, set currentVideoRange to undefined
7042
7042
  if (!hasCurrentVideoRange) {
7043
7043
  currentVideoRange = undefined;
7044
- videoRanges = [];
7045
7044
  }
7046
7045
  const codecSet = codecSets.reduce((selected, candidate) => {
7047
7046
  // Remove candiates which do not meet bitrate, default audio, stereo or channels preference, 1080p or lower, 30fps or lower, or SDR/HDR selection if present
@@ -7049,6 +7048,7 @@ function getStartCodecTier(codecTiers, currentVideoRange, currentBw, audioPrefer
7049
7048
  if (candidate === selected) {
7050
7049
  return selected;
7051
7050
  }
7051
+ videoRanges = hasCurrentVideoRange ? allowedVideoRanges.filter(range => candidateTier.videoRanges[range] > 0) : [];
7052
7052
  if (candidateTier.minBitrate > currentBw) {
7053
7053
  logStartCodecCandidateIgnored(candidate, `min bitrate of ${candidateTier.minBitrate} > current estimate of ${currentBw}`);
7054
7054
  return selected;
@@ -7082,6 +7082,10 @@ function getStartCodecTier(codecTiers, currentVideoRange, currentBw, audioPrefer
7082
7082
  logStartCodecCandidateIgnored(candidate, `no variants with VIDEO-RANGE of ${JSON.stringify(videoRanges)} found`);
7083
7083
  return selected;
7084
7084
  }
7085
+ if (videoCodecPreference && candidate.indexOf(videoCodecPreference.substring(0, 4)) % 5 !== 0) {
7086
+ logStartCodecCandidateIgnored(candidate, `video codec preference "${videoCodecPreference}" not found`);
7087
+ return selected;
7088
+ }
7085
7089
  if (candidateTier.maxScore < selectedScore) {
7086
7090
  logStartCodecCandidateIgnored(candidate, `max score of ${candidateTier.maxScore} < selected max of ${selectedScore}`);
7087
7091
  return selected;
@@ -7090,6 +7094,7 @@ function getStartCodecTier(codecTiers, currentVideoRange, currentBw, audioPrefer
7090
7094
  if (selected && (codecsSetSelectionPreferenceValue(candidate) >= codecsSetSelectionPreferenceValue(selected) || candidateTier.fragmentError > codecTiers[selected].fragmentError)) {
7091
7095
  return selected;
7092
7096
  }
7097
+ minIndex = candidateTier.minIndex;
7093
7098
  selectedScore = candidateTier.maxScore;
7094
7099
  return candidate;
7095
7100
  }, undefined);
@@ -7098,7 +7103,8 @@ function getStartCodecTier(codecTiers, currentVideoRange, currentBw, audioPrefer
7098
7103
  videoRanges,
7099
7104
  preferHDR,
7100
7105
  minFramerate,
7101
- minBitrate
7106
+ minBitrate,
7107
+ minIndex
7102
7108
  };
7103
7109
  }
7104
7110
  function logStartCodecCandidateIgnored(codeSet, reason) {
@@ -7136,7 +7142,7 @@ function getAudioTracksByGroup(allAudioTracks) {
7136
7142
  });
7137
7143
  }
7138
7144
  function getCodecTiers(levels, audioTracksByGroup, minAutoLevel, maxAutoLevel) {
7139
- return levels.slice(minAutoLevel, maxAutoLevel + 1).reduce((tiers, level) => {
7145
+ return levels.slice(minAutoLevel, maxAutoLevel + 1).reduce((tiers, level, index) => {
7140
7146
  if (!level.codecSet) {
7141
7147
  return tiers;
7142
7148
  }
@@ -7147,6 +7153,7 @@ function getCodecTiers(levels, audioTracksByGroup, minAutoLevel, maxAutoLevel) {
7147
7153
  minBitrate: Infinity,
7148
7154
  minHeight: Infinity,
7149
7155
  minFramerate: Infinity,
7156
+ minIndex: index,
7150
7157
  maxScore: 0,
7151
7158
  videoRanges: {
7152
7159
  SDR: 0
@@ -7162,6 +7169,7 @@ function getCodecTiers(levels, audioTracksByGroup, minAutoLevel, maxAutoLevel) {
7162
7169
  const lesserWidthOrHeight = Math.min(level.height, level.width);
7163
7170
  tier.minHeight = Math.min(tier.minHeight, lesserWidthOrHeight);
7164
7171
  tier.minFramerate = Math.min(tier.minFramerate, level.frameRate);
7172
+ tier.minIndex = Math.min(tier.minIndex, index);
7165
7173
  tier.maxScore = Math.max(tier.maxScore, level.score);
7166
7174
  tier.fragmentError += level.fragmentError;
7167
7175
  tier.videoRanges[level.videoRange] = (tier.videoRanges[level.videoRange] || 0) + 1;
@@ -7785,6 +7793,7 @@ class AbrController extends Logger {
7785
7793
  videoPreference
7786
7794
  } = config;
7787
7795
  const audioTracksByGroup = this.audioTracksByGroup || (this.audioTracksByGroup = getAudioTracksByGroup(allAudioTracks));
7796
+ let minStartIndex = -1;
7788
7797
  if (firstSelection) {
7789
7798
  if (this.firstSelection !== -1) {
7790
7799
  return this.firstSelection;
@@ -7796,8 +7805,10 @@ class AbrController extends Logger {
7796
7805
  videoRanges,
7797
7806
  minFramerate,
7798
7807
  minBitrate,
7808
+ minIndex,
7799
7809
  preferHDR
7800
7810
  } = startTier;
7811
+ minStartIndex = minIndex;
7801
7812
  currentCodecSet = codecSet;
7802
7813
  currentVideoRange = preferHDR ? videoRanges[videoRanges.length - 1] : videoRanges[0];
7803
7814
  currentFrameRate = minFramerate;
@@ -7846,8 +7857,10 @@ class AbrController extends Logger {
7846
7857
  // skip candidates which change codec-family or video-range,
7847
7858
  // and which decrease or increase frame-rate for up and down-switch respectfully
7848
7859
  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)) {
7849
- levelsSkipped.push(i);
7850
- continue;
7860
+ if (firstSelection && i !== minStartIndex) {
7861
+ levelsSkipped.push(i);
7862
+ continue;
7863
+ }
7851
7864
  }
7852
7865
  const levelDetails = levelInfo.details;
7853
7866
  const avgDuration = (partCurrent ? levelDetails == null ? void 0 : levelDetails.partTarget : levelDetails == null ? void 0 : levelDetails.averagetargetduration) || currentFragDuration;
@@ -7882,7 +7895,7 @@ class AbrController extends Logger {
7882
7895
  if (levelsSkipped.length) {
7883
7896
  this.trace(`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}`);
7884
7897
  }
7885
- this.info(`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}`);
7898
+ this.info(`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:${level.codecSet} videoRange:${level.videoRange} hls.loadLevel:${loadLevel}`);
7886
7899
  }
7887
7900
  if (firstSelection) {
7888
7901
  this.firstSelection = i;
@@ -29156,7 +29169,7 @@ class Hls {
29156
29169
  * Get the video-dev/hls.js package version.
29157
29170
  */
29158
29171
  static get version() {
29159
- return "1.5.12-0.canary.10349";
29172
+ return "1.5.12-0.canary.10352";
29160
29173
  }
29161
29174
 
29162
29175
  /**
@@ -29806,7 +29819,7 @@ class Hls {
29806
29819
  */
29807
29820
  setAudioOption(audioOption) {
29808
29821
  var _this$audioTrackContr;
29809
- return (_this$audioTrackContr = this.audioTrackController) == null ? void 0 : _this$audioTrackContr.setAudioOption(audioOption);
29822
+ return ((_this$audioTrackContr = this.audioTrackController) == null ? void 0 : _this$audioTrackContr.setAudioOption(audioOption)) || null;
29810
29823
  }
29811
29824
  /**
29812
29825
  * Find and select the best matching subtitle track, making a level switch when a Group change is necessary.
@@ -29814,8 +29827,7 @@ class Hls {
29814
29827
  */
29815
29828
  setSubtitleOption(subtitleOption) {
29816
29829
  var _this$subtitleTrackCo;
29817
- (_this$subtitleTrackCo = this.subtitleTrackController) == null ? void 0 : _this$subtitleTrackCo.setSubtitleOption(subtitleOption);
29818
- return null;
29830
+ return ((_this$subtitleTrackCo = this.subtitleTrackController) == null ? void 0 : _this$subtitleTrackCo.setSubtitleOption(subtitleOption)) || null;
29819
29831
  }
29820
29832
 
29821
29833
  /**