hls.js 1.6.6-0.canary.11351 → 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 +131 -77
- package/dist/hls.js.d.ts +1 -0
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +140 -94
- 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 +132 -85
- 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 +124 -73
- 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/controller/buffer-controller.ts +7 -5
- package/src/utils/mediacapabilities-helper.ts +135 -81
package/dist/hls.light.mjs
CHANGED
@@ -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.
|
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 &&
|
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;
|
@@ -10393,11 +10395,13 @@ transfer tracks: ${stringify(transferredTracks, (key, value) => key === 'initSeg
|
|
10393
10395
|
this.updateDuration();
|
10394
10396
|
}
|
10395
10397
|
updateDuration() {
|
10396
|
-
|
10397
|
-
|
10398
|
-
|
10399
|
-
|
10400
|
-
|
10398
|
+
this.blockUntilOpen(() => {
|
10399
|
+
const durationAndRange = this.getDurationAndRange();
|
10400
|
+
if (!durationAndRange) {
|
10401
|
+
return;
|
10402
|
+
}
|
10403
|
+
this.updateMediaSource(durationAndRange);
|
10404
|
+
});
|
10401
10405
|
}
|
10402
10406
|
onError(event, data) {
|
10403
10407
|
if (data.details === ErrorDetails.BUFFER_APPEND_ERROR && data.frag) {
|
@@ -19887,7 +19891,7 @@ function assignTrackIdsByGroup(tracks) {
|
|
19887
19891
|
});
|
19888
19892
|
}
|
19889
19893
|
|
19890
|
-
const version = "1.6.6-0.canary.
|
19894
|
+
const version = "1.6.6-0.canary.11353";
|
19891
19895
|
|
19892
19896
|
// ensure the worker ends up in the bundle
|
19893
19897
|
// If the worker should not be included this gets aliased to empty.js
|
@@ -22440,68 +22444,43 @@ function getUnsupportedResult(error, configurations) {
|
|
22440
22444
|
error
|
22441
22445
|
};
|
22442
22446
|
}
|
22443
|
-
|
22444
|
-
function getMediaDecodingInfoPromise(level, audioTracksByGroup, mediaCapabilities) {
|
22447
|
+
function getMediaDecodingInfoPromise(level, audioTracksByGroup, mediaCapabilities, cache = {}) {
|
22445
22448
|
const videoCodecs = level.videoCodec;
|
22446
|
-
|
22447
|
-
if (!videoCodecs && !audioCodecs || !mediaCapabilities) {
|
22449
|
+
if (!videoCodecs && !level.audioCodec || !mediaCapabilities) {
|
22448
22450
|
return Promise.resolve(SUPPORTED_INFO_DEFAULT);
|
22449
22451
|
}
|
22450
22452
|
const configurations = [];
|
22451
|
-
|
22452
|
-
|
22453
|
-
|
22454
|
-
|
22455
|
-
|
22456
|
-
|
22457
|
-
|
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'
|
22458
22460
|
};
|
22459
|
-
|
22460
|
-
|
22461
|
-
baseVideoConfiguration.transferFunction = videoRange.toLowerCase();
|
22461
|
+
if (videoCount) {
|
22462
|
+
configuration.video = videoDecodeList[i % videoCount];
|
22462
22463
|
}
|
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
|
+
}
|
22470
|
+
}
|
22471
|
+
configurations.push(configuration);
|
22472
|
+
}
|
22473
|
+
if (videoCodecs) {
|
22464
22474
|
// Override Windows Firefox HEVC MediaCapabilities result (https://github.com/video-dev/hls.js/issues/7046)
|
22465
22475
|
const ua = navigator.userAgent;
|
22466
|
-
if (
|
22467
|
-
return Promise.resolve(getUnsupportedResult(new Error(`Overriding Windows Firefox HEVC MediaCapabilities result based on user-agent
|
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));
|
22468
22478
|
}
|
22469
|
-
configurations.push.apply(configurations, videoCodecsArray.map(videoCodec => ({
|
22470
|
-
type: 'media-source',
|
22471
|
-
video: _objectSpread2(_objectSpread2({}, baseVideoConfiguration), {}, {
|
22472
|
-
contentType: mimeTypeForCodec(fillInMissingAV01Params(videoCodec), 'video')
|
22473
|
-
})
|
22474
|
-
})));
|
22475
|
-
}
|
22476
|
-
if (audioCodecs && level.audioGroups) {
|
22477
|
-
level.audioGroups.forEach(audioGroupId => {
|
22478
|
-
var _audioTracksByGroup$g;
|
22479
|
-
if (!audioGroupId) {
|
22480
|
-
return;
|
22481
|
-
}
|
22482
|
-
(_audioTracksByGroup$g = audioTracksByGroup.groups[audioGroupId]) == null ? void 0 : _audioTracksByGroup$g.tracks.forEach(audioTrack => {
|
22483
|
-
if (audioTrack.groupId === audioGroupId) {
|
22484
|
-
const channels = audioTrack.channels || '';
|
22485
|
-
const channelsNumber = parseFloat(channels);
|
22486
|
-
if (isFiniteNumber(channelsNumber) && channelsNumber > 2) {
|
22487
|
-
configurations.push.apply(configurations, audioCodecs.split(',').map(audioCodec => ({
|
22488
|
-
type: 'media-source',
|
22489
|
-
audio: {
|
22490
|
-
contentType: mimeTypeForCodec(audioCodec, 'audio'),
|
22491
|
-
channels: '' + channelsNumber
|
22492
|
-
// spatialRendering:
|
22493
|
-
// audioCodec === 'ec-3' && channels.indexOf('JOC'),
|
22494
|
-
}
|
22495
|
-
})));
|
22496
|
-
}
|
22497
|
-
}
|
22498
|
-
});
|
22499
|
-
});
|
22500
22479
|
}
|
22501
22480
|
return Promise.all(configurations.map(configuration => {
|
22502
22481
|
// Cache MediaCapabilities promises
|
22503
22482
|
const decodingInfoKey = getMediaDecodingInfoKey(configuration);
|
22504
|
-
return
|
22483
|
+
return cache[decodingInfoKey] || (cache[decodingInfoKey] = mediaCapabilities.decodingInfo(configuration));
|
22505
22484
|
})).then(decodingInfoResults => ({
|
22506
22485
|
supported: !decodingInfoResults.some(info => !info.supported),
|
22507
22486
|
configurations,
|
@@ -22513,22 +22492,90 @@ function getMediaDecodingInfoPromise(level, audioTracksByGroup, mediaCapabilitie
|
|
22513
22492
|
error
|
22514
22493
|
}));
|
22515
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
|
+
}
|
22516
22564
|
function getMediaDecodingInfoKey(config) {
|
22565
|
+
let key = '';
|
22517
22566
|
const {
|
22518
22567
|
audio,
|
22519
22568
|
video
|
22520
22569
|
} = config;
|
22521
|
-
|
22522
|
-
|
22523
|
-
|
22524
|
-
|
22525
|
-
|
22526
|
-
|
22527
|
-
|
22528
|
-
return `c${audio.channels}${audio.spatialRendering ? 's' : 'n'}_${codec}`;
|
22529
|
-
}
|
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}`;
|
22530
22577
|
}
|
22531
|
-
return
|
22578
|
+
return key;
|
22532
22579
|
}
|
22533
22580
|
|
22534
22581
|
/**
|