hls.js 1.6.0-beta.1.0.canary.10751 → 1.6.0-beta.1.0.canary.10754
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/README.md +6 -11
- package/dist/hls.d.mts +4 -0
- package/dist/hls.d.ts +4 -0
- package/dist/hls.js +96 -44
- package/dist/hls.js.d.ts +4 -0
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +90 -42
- 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 +86 -42
- 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 +92 -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 +6 -5
- package/src/controller/audio-track-controller.ts +8 -2
- package/src/loader/fragment-loader.ts +1 -1
- package/src/loader/fragment.ts +33 -0
- package/src/loader/m3u8-parser.ts +10 -0
- package/src/utils/xhr-loader.ts +52 -49
package/README.md
CHANGED
@@ -86,20 +86,18 @@ For details on the HLS format and these tags' meanings, see https://datatracker.
|
|
86
86
|
- `#EXT-X-CONTENT-STEERING:<attribute-list>` Content Steering
|
87
87
|
- `#EXT-X-DEFINE:<attribute-list>` Variable Substitution (`NAME,VALUE,QUERYPARAM` attributes)
|
88
88
|
|
89
|
-
The following properties are added to their respective variants' attribute list but are not implemented in their selection and playback.
|
90
|
-
|
91
|
-
- `VIDEO-RANGE` (See [#2489](https://github.com/video-dev/hls.js/issues/2489))
|
92
|
-
|
93
89
|
#### Media Playlist tags
|
94
90
|
|
95
|
-
- `#EXTM3U`
|
96
|
-
- `#EXT-X-
|
91
|
+
- `#EXTM3U` (ignored)
|
92
|
+
- `#EXT-X-INDEPENDENT-SEGMENTS` (ignored)
|
93
|
+
- `#EXT-X-VERSION=<n>` (value is ignored)
|
97
94
|
- `#EXTINF:<duration>,[<title>]`
|
98
95
|
- `#EXT-X-ENDLIST`
|
99
96
|
- `#EXT-X-MEDIA-SEQUENCE=<n>`
|
100
97
|
- `#EXT-X-TARGETDURATION=<n>`
|
101
98
|
- `#EXT-X-DISCONTINUITY`
|
102
99
|
- `#EXT-X-DISCONTINUITY-SEQUENCE=<n>`
|
100
|
+
- `#EXT-X-BITRATE`
|
103
101
|
- `#EXT-X-BYTERANGE=<n>[@<o>]`
|
104
102
|
- `#EXT-X-MAP:<attribute-list>`
|
105
103
|
- `#EXT-X-KEY:<attribute-list>` (`KEYFORMAT="identity",METHOD=SAMPLE-AES` is only supports with MPEG-2 TS segments)
|
@@ -115,11 +113,7 @@ The following properties are added to their respective variants' attribute list
|
|
115
113
|
- `#EXT-X-DEFINE:<attribute-list>` Variable Import and Substitution (`NAME,VALUE,IMPORT,QUERYPARAM` attributes)
|
116
114
|
- `#EXT-X-GAP` (Skips loading GAP segments and parts. Skips playback of unbuffered program containing only GAP content and no suitable alternates. See [#2940](https://github.com/video-dev/hls.js/issues/2940))
|
117
115
|
|
118
|
-
|
119
|
-
|
120
|
-
- `#EXT-X-BITRATE` (Not used in ABR controller)
|
121
|
-
|
122
|
-
Parsed but missing feature support
|
116
|
+
Parsed but missing feature support:
|
123
117
|
|
124
118
|
- `#EXT-X-PRELOAD-HINT:<attribute-list>` (See [#5074](https://github.com/video-dev/hls.js/issues/3988))
|
125
119
|
- #5074
|
@@ -129,6 +123,7 @@ Parsed but missing feature support
|
|
129
123
|
For a complete list of issues, see ["Top priorities" in the Release Planning and Backlog project tab](https://github.com/video-dev/hls.js/projects/6). Codec support is dependent on the runtime environment (for example, not all browsers on the same OS support HEVC).
|
130
124
|
|
131
125
|
- `#EXT-X-I-FRAME-STREAM-INF` I-frame Media Playlist files
|
126
|
+
- `REQ-VIDEO-LAYOUT` is not used in variant filtering or selection
|
132
127
|
- "identity" format `SAMPLE-AES` method keys with fmp4, aac, mp3, vtt... segments (MPEG-2 TS only)
|
133
128
|
- MPEG-2 TS segments with FairPlay Streaming, PlayReady, or Widevine encryption
|
134
129
|
- FairPlay Streaming legacy keys (For com.apple.fps.1_0 use native Safari playback)
|
package/dist/hls.d.mts
CHANGED
@@ -1290,6 +1290,7 @@ export declare class Fragment extends BaseSegment {
|
|
1290
1290
|
private _decryptdata;
|
1291
1291
|
private _programDateTime;
|
1292
1292
|
private _ref;
|
1293
|
+
private _bitrate?;
|
1293
1294
|
rawProgramDateTime: string | null;
|
1294
1295
|
tagList: Array<string[]>;
|
1295
1296
|
duration: number;
|
@@ -1319,6 +1320,9 @@ export declare class Fragment extends BaseSegment {
|
|
1319
1320
|
gap?: boolean;
|
1320
1321
|
urlId: number;
|
1321
1322
|
constructor(type: PlaylistLevelType, base: Base | string);
|
1323
|
+
get byteLength(): number | null;
|
1324
|
+
get bitrate(): number | null;
|
1325
|
+
set bitrate(value: number);
|
1322
1326
|
get decryptdata(): LevelKey | null;
|
1323
1327
|
get end(): number;
|
1324
1328
|
get endProgramDateTime(): number | null;
|
package/dist/hls.d.ts
CHANGED
@@ -1290,6 +1290,7 @@ export declare class Fragment extends BaseSegment {
|
|
1290
1290
|
private _decryptdata;
|
1291
1291
|
private _programDateTime;
|
1292
1292
|
private _ref;
|
1293
|
+
private _bitrate?;
|
1293
1294
|
rawProgramDateTime: string | null;
|
1294
1295
|
tagList: Array<string[]>;
|
1295
1296
|
duration: number;
|
@@ -1319,6 +1320,9 @@ export declare class Fragment extends BaseSegment {
|
|
1319
1320
|
gap?: boolean;
|
1320
1321
|
urlId: number;
|
1321
1322
|
constructor(type: PlaylistLevelType, base: Base | string);
|
1323
|
+
get byteLength(): number | null;
|
1324
|
+
get bitrate(): number | null;
|
1325
|
+
set bitrate(value: number);
|
1322
1326
|
get decryptdata(): LevelKey | null;
|
1323
1327
|
get end(): number;
|
1324
1328
|
get endProgramDateTime(): number | null;
|
package/dist/hls.js
CHANGED
@@ -1057,7 +1057,7 @@
|
|
1057
1057
|
// Some browsers don't allow to use bind on console object anyway
|
1058
1058
|
// fallback to default if needed
|
1059
1059
|
try {
|
1060
|
-
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-beta.1.0.canary.
|
1060
|
+
newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.6.0-beta.1.0.canary.10754");
|
1061
1061
|
} catch (e) {
|
1062
1062
|
/* log fn threw an exception. All logger methods are no-ops. */
|
1063
1063
|
return createLogger();
|
@@ -2115,7 +2115,7 @@
|
|
2115
2115
|
var bwEstimate = _this.getBwEstimate();
|
2116
2116
|
var levels = hls.levels;
|
2117
2117
|
var level = levels[frag.level];
|
2118
|
-
var expectedLen =
|
2118
|
+
var expectedLen = Math.max(stats.loaded, Math.round(duration * (frag.bitrate || level.averageBitrate) / 8));
|
2119
2119
|
var timeStreaming = loadedFirstByte ? timeLoading - ttfb : timeLoading;
|
2120
2120
|
if (timeStreaming < 1 && loadedFirstByte) {
|
2121
2121
|
timeStreaming = Math.min(timeLoading, stats.loaded * 8 / bwEstimate);
|
@@ -2595,7 +2595,7 @@
|
|
2595
2595
|
}
|
2596
2596
|
|
2597
2597
|
// Use average bitrate when starvation delay (buffer length) is gt or eq two segment durations and rebuffering is not expected (maxStarvationDelay > 0)
|
2598
|
-
var bitrate = currentFragDuration && bufferStarvationDelay >= currentFragDuration * 2 && maxStarvationDelay === 0 ?
|
2598
|
+
var bitrate = currentFragDuration && bufferStarvationDelay >= currentFragDuration * 2 && maxStarvationDelay === 0 ? levelInfo.averageBitrate : levelInfo.maxBitrate;
|
2599
2599
|
var fetchDuration = _this3.getTimeToLoadFrag(ttfbEstimateSec, adjustedbw, bitrate * avgDuration, levelDetails === undefined);
|
2600
2600
|
var canSwitchWithinTolerance =
|
2601
2601
|
// if adjusted bw is greater than level bitrate AND
|
@@ -4330,6 +4330,8 @@
|
|
4330
4330
|
_this._decryptdata = null;
|
4331
4331
|
_this._programDateTime = null;
|
4332
4332
|
_this._ref = null;
|
4333
|
+
// Approximate bit rate of the fragment expressed in bits per second (bps) as indicated by the last EXT-X-BITRATE (kbps) tag
|
4334
|
+
_this._bitrate = void 0;
|
4333
4335
|
_this.rawProgramDateTime = null;
|
4334
4336
|
_this.tagList = [];
|
4335
4337
|
// EXTINF has to be present for a m3u8 to be considered valid
|
@@ -4437,6 +4439,38 @@
|
|
4437
4439
|
info.endDTS = Math.max(info.endDTS, endDTS);
|
4438
4440
|
};
|
4439
4441
|
return _createClass(Fragment, [{
|
4442
|
+
key: "byteLength",
|
4443
|
+
get: function get() {
|
4444
|
+
if (this.hasStats) {
|
4445
|
+
var total = this.stats.total;
|
4446
|
+
if (total) {
|
4447
|
+
return total;
|
4448
|
+
}
|
4449
|
+
}
|
4450
|
+
if (this.byteRange) {
|
4451
|
+
var start = this.byteRange[0];
|
4452
|
+
var end = this.byteRange[1];
|
4453
|
+
if (isFiniteNumber(start) && isFiniteNumber(end)) {
|
4454
|
+
return end - start;
|
4455
|
+
}
|
4456
|
+
}
|
4457
|
+
return null;
|
4458
|
+
}
|
4459
|
+
}, {
|
4460
|
+
key: "bitrate",
|
4461
|
+
get: function get() {
|
4462
|
+
if (this.byteLength) {
|
4463
|
+
return this.byteLength * 8 / this.duration;
|
4464
|
+
}
|
4465
|
+
if (this._bitrate) {
|
4466
|
+
return this._bitrate;
|
4467
|
+
}
|
4468
|
+
return null;
|
4469
|
+
},
|
4470
|
+
set: function set(value) {
|
4471
|
+
this._bitrate = value;
|
4472
|
+
}
|
4473
|
+
}, {
|
4440
4474
|
key: "decryptdata",
|
4441
4475
|
get: function get() {
|
4442
4476
|
var levelkeys = this.levelkeys;
|
@@ -7649,6 +7683,7 @@
|
|
7649
7683
|
var currentPart = 0;
|
7650
7684
|
var totalduration = 0;
|
7651
7685
|
var discontinuityCounter = 0;
|
7686
|
+
var currentBitrate = 0;
|
7652
7687
|
var prevFrag = null;
|
7653
7688
|
var frag = new Fragment(type, base);
|
7654
7689
|
var result;
|
@@ -7669,6 +7704,9 @@
|
|
7669
7704
|
frag.start = totalduration;
|
7670
7705
|
frag.sn = currentSN;
|
7671
7706
|
frag.cc = discontinuityCounter;
|
7707
|
+
if (currentBitrate) {
|
7708
|
+
frag.bitrate = currentBitrate;
|
7709
|
+
}
|
7672
7710
|
frag.level = id;
|
7673
7711
|
if (currentInitSegment) {
|
7674
7712
|
frag.initSegment = currentInitSegment;
|
@@ -7798,6 +7836,12 @@
|
|
7798
7836
|
break;
|
7799
7837
|
case 'BITRATE':
|
7800
7838
|
frag.tagList.push([tag, value1]);
|
7839
|
+
currentBitrate = parseInt(value1) * 1000;
|
7840
|
+
if (isFiniteNumber(currentBitrate)) {
|
7841
|
+
frag.bitrate = currentBitrate;
|
7842
|
+
} else {
|
7843
|
+
currentBitrate = 0;
|
7844
|
+
}
|
7801
7845
|
break;
|
7802
7846
|
case 'DATERANGE':
|
7803
7847
|
{
|
@@ -16178,7 +16222,7 @@
|
|
16178
16222
|
return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
|
16179
16223
|
}
|
16180
16224
|
|
16181
|
-
var version = "1.6.0-beta.1.0.canary.
|
16225
|
+
var version = "1.6.0-beta.1.0.canary.10754";
|
16182
16226
|
|
16183
16227
|
// ensure the worker ends up in the bundle
|
16184
16228
|
// If the worker should not be included this gets aliased to empty.js
|
@@ -17862,12 +17906,16 @@
|
|
17862
17906
|
return -1;
|
17863
17907
|
};
|
17864
17908
|
_proto.loadPlaylist = function loadPlaylist(hlsUrlParameters) {
|
17909
|
+
var _this$hls$levels$this;
|
17865
17910
|
var audioTrack = this.currentTrack;
|
17866
|
-
if (
|
17911
|
+
if (!audioTrack) {
|
17912
|
+
return;
|
17913
|
+
}
|
17914
|
+
var url = audioTrack.url;
|
17915
|
+
if (this.shouldLoadPlaylist(audioTrack) && url !== ((_this$hls$levels$this = this.hls.levels[this.hls.loadLevel]) == null ? void 0 : _this$hls$levels$this.uri)) {
|
17867
17916
|
_BasePlaylistControll.prototype.loadPlaylist.call(this);
|
17868
17917
|
var id = audioTrack.id;
|
17869
17918
|
var groupId = audioTrack.groupId;
|
17870
|
-
var url = audioTrack.url;
|
17871
17919
|
if (hlsUrlParameters) {
|
17872
17920
|
try {
|
17873
17921
|
url = hlsUrlParameters.addDirectives(url);
|
@@ -29851,47 +29899,51 @@
|
|
29851
29899
|
xhr.onprogress = null;
|
29852
29900
|
var _status = xhr.status;
|
29853
29901
|
// http status between 200 to 299 are all successful
|
29854
|
-
var
|
29855
|
-
if (_status >= 200 && _status < 300
|
29856
|
-
|
29857
|
-
|
29858
|
-
|
29859
|
-
|
29860
|
-
|
29861
|
-
|
29862
|
-
|
29863
|
-
|
29864
|
-
|
29865
|
-
|
29866
|
-
onProgress
|
29867
|
-
|
29868
|
-
|
29902
|
+
var useResponseText = xhr.responseType === 'text' ? xhr.responseText : null;
|
29903
|
+
if (_status >= 200 && _status < 300) {
|
29904
|
+
var data = useResponseText != null ? useResponseText : xhr.response;
|
29905
|
+
if (data != null) {
|
29906
|
+
stats.loading.end = Math.max(self.performance.now(), stats.loading.first);
|
29907
|
+
var len = xhr.responseType === 'arraybuffer' ? data.byteLength : data.length;
|
29908
|
+
stats.loaded = stats.total = len;
|
29909
|
+
stats.bwEstimate = stats.total * 8000 / (stats.loading.end - stats.loading.first);
|
29910
|
+
if (!this.callbacks) {
|
29911
|
+
return;
|
29912
|
+
}
|
29913
|
+
var onProgress = this.callbacks.onProgress;
|
29914
|
+
if (onProgress) {
|
29915
|
+
onProgress(stats, context, data, xhr);
|
29916
|
+
}
|
29917
|
+
if (!this.callbacks) {
|
29918
|
+
return;
|
29919
|
+
}
|
29920
|
+
var _response = {
|
29921
|
+
url: xhr.responseURL,
|
29922
|
+
data: data,
|
29923
|
+
code: _status
|
29924
|
+
};
|
29925
|
+
this.callbacks.onSuccess(_response, stats, context, xhr);
|
29869
29926
|
return;
|
29870
29927
|
}
|
29871
|
-
|
29872
|
-
|
29873
|
-
|
29874
|
-
|
29875
|
-
|
29876
|
-
|
29928
|
+
}
|
29929
|
+
|
29930
|
+
// Handle bad status or nullish response
|
29931
|
+
var retryConfig = config.loadPolicy.errorRetry;
|
29932
|
+
var retryCount = stats.retry;
|
29933
|
+
// if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
|
29934
|
+
var response = {
|
29935
|
+
url: context.url,
|
29936
|
+
data: undefined,
|
29937
|
+
code: _status
|
29938
|
+
};
|
29939
|
+
if (shouldRetry(retryConfig, retryCount, false, response)) {
|
29940
|
+
this.retry(retryConfig);
|
29877
29941
|
} else {
|
29878
|
-
|
29879
|
-
|
29880
|
-
|
29881
|
-
|
29882
|
-
|
29883
|
-
data: undefined,
|
29884
|
-
code: _status
|
29885
|
-
};
|
29886
|
-
if (shouldRetry(retryConfig, retryCount, false, _response)) {
|
29887
|
-
this.retry(retryConfig);
|
29888
|
-
} else {
|
29889
|
-
logger.error(_status + " while loading " + context.url);
|
29890
|
-
this.callbacks.onError({
|
29891
|
-
code: _status,
|
29892
|
-
text: xhr.statusText
|
29893
|
-
}, context, xhr, stats);
|
29894
|
-
}
|
29942
|
+
logger.error(_status + " while loading " + context.url);
|
29943
|
+
this.callbacks.onError({
|
29944
|
+
code: _status,
|
29945
|
+
text: xhr.statusText
|
29946
|
+
}, context, xhr, stats);
|
29895
29947
|
}
|
29896
29948
|
}
|
29897
29949
|
}
|
package/dist/hls.js.d.ts
CHANGED
@@ -1290,6 +1290,7 @@ export declare class Fragment extends BaseSegment {
|
|
1290
1290
|
private _decryptdata;
|
1291
1291
|
private _programDateTime;
|
1292
1292
|
private _ref;
|
1293
|
+
private _bitrate?;
|
1293
1294
|
rawProgramDateTime: string | null;
|
1294
1295
|
tagList: Array<string[]>;
|
1295
1296
|
duration: number;
|
@@ -1319,6 +1320,9 @@ export declare class Fragment extends BaseSegment {
|
|
1319
1320
|
gap?: boolean;
|
1320
1321
|
urlId: number;
|
1321
1322
|
constructor(type: PlaylistLevelType, base: Base | string);
|
1323
|
+
get byteLength(): number | null;
|
1324
|
+
get bitrate(): number | null;
|
1325
|
+
set bitrate(value: number);
|
1322
1326
|
get decryptdata(): LevelKey | null;
|
1323
1327
|
get end(): number;
|
1324
1328
|
get endProgramDateTime(): number | null;
|