hls.js 1.5.12-0.canary.10351 → 1.5.12-0.canary.10353
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.js +60 -46
- package/dist/hls.js.d.ts +1 -0
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +57 -43
- 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 +55 -41
- 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 +58 -44
- 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 +1 -1
- package/src/controller/abr-controller.ts +15 -5
- package/src/demux/video/avc-video-parser.ts +3 -3
- package/src/demux/video/base-video-parser.ts +24 -20
- package/src/demux/video/hevc-video-parser.ts +3 -3
- package/src/hls.ts +4 -3
- package/src/types/demuxer.ts +0 -1
- package/src/types/media-playlist.ts +9 -1
- package/src/utils/hdr.ts +4 -7
- package/src/utils/rendition-helper.ts +26 -5
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.
|
423
|
+
newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.12-0.canary.10353"}`);
|
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
|
-
|
6994
|
-
|
6995
|
-
|
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 =
|
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
|
-
|
7850
|
-
|
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:${
|
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;
|
@@ -11948,6 +11961,20 @@ class BaseVideoParser {
|
|
11948
11961
|
length: 0
|
11949
11962
|
};
|
11950
11963
|
}
|
11964
|
+
getLastNalUnit(samples) {
|
11965
|
+
var _VideoSample;
|
11966
|
+
let VideoSample = this.VideoSample;
|
11967
|
+
let lastUnit;
|
11968
|
+
// try to fallback to previous sample if current one is empty
|
11969
|
+
if (!VideoSample || VideoSample.units.length === 0) {
|
11970
|
+
VideoSample = samples[samples.length - 1];
|
11971
|
+
}
|
11972
|
+
if ((_VideoSample = VideoSample) != null && _VideoSample.units) {
|
11973
|
+
const units = VideoSample.units;
|
11974
|
+
lastUnit = units[units.length - 1];
|
11975
|
+
}
|
11976
|
+
return lastUnit;
|
11977
|
+
}
|
11951
11978
|
pushAccessUnit(VideoSample, videoTrack) {
|
11952
11979
|
if (VideoSample.units.length && VideoSample.frame) {
|
11953
11980
|
// if sample does not have PTS/DTS, patch with last sample PTS/DTS
|
@@ -11970,7 +11997,7 @@ class BaseVideoParser {
|
|
11970
11997
|
logger.log(VideoSample.pts + '/' + VideoSample.dts + ':' + VideoSample.debug);
|
11971
11998
|
}
|
11972
11999
|
}
|
11973
|
-
parseNALu(track, array,
|
12000
|
+
parseNALu(track, array, endOfSegment) {
|
11974
12001
|
const len = array.byteLength;
|
11975
12002
|
let state = track.naluState || 0;
|
11976
12003
|
const lastState = state;
|
@@ -12012,10 +12039,6 @@ class BaseVideoParser {
|
|
12012
12039
|
data: array.subarray(lastUnitStart, overflow),
|
12013
12040
|
type: lastUnitType
|
12014
12041
|
};
|
12015
|
-
if (track.lastNalu) {
|
12016
|
-
units.push(track.lastNalu);
|
12017
|
-
track.lastNalu = null;
|
12018
|
-
}
|
12019
12042
|
// logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
|
12020
12043
|
units.push(unit);
|
12021
12044
|
} else {
|
@@ -12023,7 +12046,7 @@ class BaseVideoParser {
|
|
12023
12046
|
// first check if start code delimiter is overlapping between 2 PES packets,
|
12024
12047
|
// ie it started in last packet (lastState not zero)
|
12025
12048
|
// and ended at the beginning of this PES packet (i <= 4 - lastState)
|
12026
|
-
const lastUnit = track.
|
12049
|
+
const lastUnit = this.getLastNalUnit(track.samples);
|
12027
12050
|
if (lastUnit) {
|
12028
12051
|
if (lastState && i <= 4 - lastState) {
|
12029
12052
|
// start delimiter overlapping between PES packets
|
@@ -12040,8 +12063,6 @@ class BaseVideoParser {
|
|
12040
12063
|
// logger.log('first NALU found with overflow:' + overflow);
|
12041
12064
|
lastUnit.data = appendUint8Array(lastUnit.data, array.subarray(0, overflow));
|
12042
12065
|
lastUnit.state = 0;
|
12043
|
-
units.push(lastUnit);
|
12044
|
-
track.lastNalu = null;
|
12045
12066
|
}
|
12046
12067
|
}
|
12047
12068
|
}
|
@@ -12066,21 +12087,15 @@ class BaseVideoParser {
|
|
12066
12087
|
type: lastUnitType,
|
12067
12088
|
state: state
|
12068
12089
|
};
|
12069
|
-
|
12070
|
-
|
12071
|
-
|
12072
|
-
|
12073
|
-
|
12074
|
-
// logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
|
12075
|
-
}
|
12076
|
-
} else if (units.length === 0) {
|
12077
|
-
// no NALu found
|
12090
|
+
units.push(unit);
|
12091
|
+
// logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
|
12092
|
+
}
|
12093
|
+
// no NALu found
|
12094
|
+
if (units.length === 0) {
|
12078
12095
|
// append pes.data to previous NAL unit
|
12079
|
-
const lastUnit = track.
|
12096
|
+
const lastUnit = this.getLastNalUnit(track.samples);
|
12080
12097
|
if (lastUnit) {
|
12081
12098
|
lastUnit.data = appendUint8Array(lastUnit.data, array);
|
12082
|
-
units.push(lastUnit);
|
12083
|
-
track.lastNalu = null;
|
12084
12099
|
}
|
12085
12100
|
}
|
12086
12101
|
track.naluState = state;
|
@@ -12231,8 +12246,8 @@ class ExpGolomb {
|
|
12231
12246
|
}
|
12232
12247
|
|
12233
12248
|
class AvcVideoParser extends BaseVideoParser {
|
12234
|
-
parsePES(track, textTrack, pes,
|
12235
|
-
const units = this.parseNALu(track, pes.data,
|
12249
|
+
parsePES(track, textTrack, pes, endOfSegment, duration) {
|
12250
|
+
const units = this.parseNALu(track, pes.data, endOfSegment);
|
12236
12251
|
let VideoSample = this.VideoSample;
|
12237
12252
|
let push;
|
12238
12253
|
let spsfound = false;
|
@@ -12362,7 +12377,7 @@ class AvcVideoParser extends BaseVideoParser {
|
|
12362
12377
|
}
|
12363
12378
|
});
|
12364
12379
|
// if last PES packet, push samples
|
12365
|
-
if (
|
12380
|
+
if (endOfSegment && VideoSample) {
|
12366
12381
|
this.pushAccessUnit(VideoSample, track);
|
12367
12382
|
this.VideoSample = null;
|
12368
12383
|
}
|
@@ -12561,8 +12576,8 @@ class HevcVideoParser extends BaseVideoParser {
|
|
12561
12576
|
super(...args);
|
12562
12577
|
this.initVPS = null;
|
12563
12578
|
}
|
12564
|
-
parsePES(track, textTrack, pes,
|
12565
|
-
const units = this.parseNALu(track, pes.data,
|
12579
|
+
parsePES(track, textTrack, pes, endOfSegment, duration) {
|
12580
|
+
const units = this.parseNALu(track, pes.data, endOfSegment);
|
12566
12581
|
let VideoSample = this.VideoSample;
|
12567
12582
|
let push;
|
12568
12583
|
let spsfound = false;
|
@@ -12724,7 +12739,7 @@ class HevcVideoParser extends BaseVideoParser {
|
|
12724
12739
|
}
|
12725
12740
|
});
|
12726
12741
|
// if last PES packet, push samples
|
12727
|
-
if (
|
12742
|
+
if (endOfSegment && VideoSample) {
|
12728
12743
|
this.pushAccessUnit(VideoSample, track);
|
12729
12744
|
this.VideoSample = null;
|
12730
12745
|
}
|
@@ -29156,7 +29171,7 @@ class Hls {
|
|
29156
29171
|
* Get the video-dev/hls.js package version.
|
29157
29172
|
*/
|
29158
29173
|
static get version() {
|
29159
|
-
return "1.5.12-0.canary.
|
29174
|
+
return "1.5.12-0.canary.10353";
|
29160
29175
|
}
|
29161
29176
|
|
29162
29177
|
/**
|
@@ -29806,7 +29821,7 @@ class Hls {
|
|
29806
29821
|
*/
|
29807
29822
|
setAudioOption(audioOption) {
|
29808
29823
|
var _this$audioTrackContr;
|
29809
|
-
return (_this$audioTrackContr = this.audioTrackController) == null ? void 0 : _this$audioTrackContr.setAudioOption(audioOption);
|
29824
|
+
return ((_this$audioTrackContr = this.audioTrackController) == null ? void 0 : _this$audioTrackContr.setAudioOption(audioOption)) || null;
|
29810
29825
|
}
|
29811
29826
|
/**
|
29812
29827
|
* Find and select the best matching subtitle track, making a level switch when a Group change is necessary.
|
@@ -29814,8 +29829,7 @@ class Hls {
|
|
29814
29829
|
*/
|
29815
29830
|
setSubtitleOption(subtitleOption) {
|
29816
29831
|
var _this$subtitleTrackCo;
|
29817
|
-
(_this$subtitleTrackCo = this.subtitleTrackController) == null ? void 0 : _this$subtitleTrackCo.setSubtitleOption(subtitleOption);
|
29818
|
-
return null;
|
29832
|
+
return ((_this$subtitleTrackCo = this.subtitleTrackController) == null ? void 0 : _this$subtitleTrackCo.setSubtitleOption(subtitleOption)) || null;
|
29819
29833
|
}
|
29820
29834
|
|
29821
29835
|
/**
|