hls.js 1.6.0-beta.2.0.canary.10924 → 1.6.0-beta.2.0.canary.10926
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 +68 -30
- package/dist/hls.d.ts +68 -30
- package/dist/hls.js +684 -496
- package/dist/hls.js.d.ts +68 -30
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +3882 -3693
- 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 +1140 -954
- 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 +684 -499
- package/dist/hls.mjs.map +1 -1
- package/dist/hls.worker.js +1 -1
- package/package.json +1 -1
- package/src/config.ts +15 -9
- package/src/controller/abr-controller.ts +2 -2
- package/src/controller/base-stream-controller.ts +16 -12
- package/src/controller/buffer-controller.ts +19 -22
- package/src/controller/error-controller.ts +2 -2
- package/src/controller/fragment-tracker.ts +1 -1
- package/src/controller/gap-controller.ts +273 -38
- package/src/controller/interstitials-controller.ts +14 -11
- package/src/controller/level-controller.ts +4 -0
- package/src/controller/stream-controller.ts +26 -73
- package/src/hls.ts +57 -3
- package/src/utils/buffer-helper.ts +35 -13
- package/src/utils/event-listener-helper.ts +16 -0
- package/src/utils/rendition-helper.ts +1 -1
@@ -672,8 +672,8 @@ class AbrController extends Logger implements AbrComponentAPI {
|
|
672
672
|
}
|
673
673
|
// If no matching level found, see if min auto level would be a better option
|
674
674
|
const minLevel = hls.levels[minAutoLevel];
|
675
|
-
const autoLevel = hls.
|
676
|
-
if (minLevel?.bitrate < autoLevel
|
675
|
+
const autoLevel = hls.loadLevelObj;
|
676
|
+
if (autoLevel && minLevel?.bitrate < autoLevel.bitrate) {
|
677
677
|
return minAutoLevel;
|
678
678
|
}
|
679
679
|
// or if bitrate is not lower, continue to use loadLevel
|
@@ -79,6 +79,11 @@ export const State = {
|
|
79
79
|
WAITING_LEVEL: 'WAITING_LEVEL',
|
80
80
|
};
|
81
81
|
|
82
|
+
export type InFlightData = {
|
83
|
+
frag: Fragment | null;
|
84
|
+
state: (typeof State)[keyof typeof State];
|
85
|
+
};
|
86
|
+
|
82
87
|
export default class BaseStreamController
|
83
88
|
extends TaskLoop
|
84
89
|
implements NetworkComponentAPI
|
@@ -89,7 +94,7 @@ export default class BaseStreamController
|
|
89
94
|
protected fragCurrent: Fragment | null = null;
|
90
95
|
protected fragmentTracker: FragmentTracker;
|
91
96
|
protected transmuxer: TransmuxerInterface | null = null;
|
92
|
-
protected _state:
|
97
|
+
protected _state: (typeof State)[keyof typeof State] = State.STOPPED;
|
93
98
|
protected playlistType: PlaylistLevelType;
|
94
99
|
protected media: HTMLMediaElement | null = null;
|
95
100
|
protected mediaBuffer: Bufferable | null = null;
|
@@ -194,6 +199,10 @@ export default class BaseStreamController
|
|
194
199
|
this.buffering = true;
|
195
200
|
}
|
196
201
|
|
202
|
+
public get inFlightFrag(): InFlightData {
|
203
|
+
return { frag: this.fragCurrent, state: this.state };
|
204
|
+
}
|
205
|
+
|
197
206
|
protected _streamEnded(
|
198
207
|
bufferInfo: BufferInfo,
|
199
208
|
levelDetails: LevelDetails,
|
@@ -395,13 +404,8 @@ export default class BaseStreamController
|
|
395
404
|
// reset startPosition and lastCurrentTime to restart playback @ stream beginning
|
396
405
|
this.log(`setting startPosition to 0 because media ended`);
|
397
406
|
this.startPosition = this.lastCurrentTime = 0;
|
398
|
-
this.triggerEnded();
|
399
407
|
};
|
400
408
|
|
401
|
-
protected triggerEnded() {
|
402
|
-
/* overridden in stream-controller */
|
403
|
-
}
|
404
|
-
|
405
409
|
protected onManifestLoaded(
|
406
410
|
event: Events.MANIFEST_LOADED,
|
407
411
|
data: ManifestLoadedData,
|
@@ -1211,11 +1215,11 @@ export default class BaseStreamController
|
|
1211
1215
|
bufferedFragAtPos &&
|
1212
1216
|
(bufferInfo.nextStart <= bufferedFragAtPos.end || bufferedFragAtPos.gap)
|
1213
1217
|
) {
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
Math.max(bufferInfo.nextStart, maxBufferHole),
|
1218
|
+
const gapDuration = Math.max(
|
1219
|
+
Math.min(bufferInfo.nextStart, bufferedFragAtPos.end) - pos,
|
1220
|
+
maxBufferHole,
|
1218
1221
|
);
|
1222
|
+
return BufferHelper.bufferInfo(bufferable, pos, gapDuration);
|
1219
1223
|
}
|
1220
1224
|
}
|
1221
1225
|
return bufferInfo;
|
@@ -2023,7 +2027,7 @@ export default class BaseStreamController
|
|
2023
2027
|
}
|
2024
2028
|
}
|
2025
2029
|
|
2026
|
-
set state(nextState) {
|
2030
|
+
set state(nextState: (typeof State)[keyof typeof State]) {
|
2027
2031
|
const previousState = this._state;
|
2028
2032
|
if (previousState !== nextState) {
|
2029
2033
|
this._state = nextState;
|
@@ -2031,7 +2035,7 @@ export default class BaseStreamController
|
|
2031
2035
|
}
|
2032
2036
|
}
|
2033
2037
|
|
2034
|
-
get state() {
|
2038
|
+
get state(): (typeof State)[keyof typeof State] {
|
2035
2039
|
return this._state;
|
2036
2040
|
}
|
2037
2041
|
}
|
@@ -82,10 +82,10 @@ export default class BufferController extends Logger implements ComponentAPI {
|
|
82
82
|
private bufferCodecEventsTotal: number = 0;
|
83
83
|
|
84
84
|
// A reference to the attached media element
|
85
|
-
|
85
|
+
private media: HTMLMediaElement | null = null;
|
86
86
|
|
87
87
|
// A reference to the active media source
|
88
|
-
|
88
|
+
private mediaSource: MediaSource | null = null;
|
89
89
|
|
90
90
|
// Last MP3 audio chunk appended
|
91
91
|
private lastMpegAudioChunk: ChunkMetadata | null = null;
|
@@ -152,7 +152,7 @@ export default class BufferController extends Logger implements ComponentAPI {
|
|
152
152
|
this._onStartStreaming = this._onEndStreaming = null;
|
153
153
|
}
|
154
154
|
|
155
|
-
|
155
|
+
private registerListeners() {
|
156
156
|
const { hls } = this;
|
157
157
|
hls.on(Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
|
158
158
|
hls.on(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
@@ -169,7 +169,7 @@ export default class BufferController extends Logger implements ComponentAPI {
|
|
169
169
|
hls.on(Events.ERROR, this.onError, this);
|
170
170
|
}
|
171
171
|
|
172
|
-
|
172
|
+
private unregisterListeners() {
|
173
173
|
const { hls } = this;
|
174
174
|
hls.off(Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
|
175
175
|
hls.off(Events.MEDIA_DETACHING, this.onMediaDetaching, this);
|
@@ -247,7 +247,7 @@ export default class BufferController extends Logger implements ComponentAPI {
|
|
247
247
|
this.details = null;
|
248
248
|
}
|
249
249
|
|
250
|
-
|
250
|
+
private onManifestParsed(
|
251
251
|
event: Events.MANIFEST_PARSED,
|
252
252
|
data: ManifestParsedData,
|
253
253
|
) {
|
@@ -270,7 +270,7 @@ export default class BufferController extends Logger implements ComponentAPI {
|
|
270
270
|
}
|
271
271
|
}
|
272
272
|
|
273
|
-
|
273
|
+
private onMediaAttaching(
|
274
274
|
event: Events.MEDIA_ATTACHING,
|
275
275
|
data: MediaAttachingData,
|
276
276
|
) {
|
@@ -440,6 +440,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
440
440
|
}
|
441
441
|
this.hls.pauseBuffering();
|
442
442
|
};
|
443
|
+
|
443
444
|
private _onStartStreaming = (event) => {
|
444
445
|
if (!this.hls) {
|
445
446
|
return;
|
@@ -447,7 +448,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
447
448
|
this.hls.resumeBuffering();
|
448
449
|
};
|
449
450
|
|
450
|
-
|
451
|
+
private onMediaDetaching(
|
451
452
|
event: Events.MEDIA_DETACHING,
|
452
453
|
data: MediaDetachingData,
|
453
454
|
) {
|
@@ -540,7 +541,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
540
541
|
this.hls.trigger(Events.MEDIA_DETACHED, data);
|
541
542
|
}
|
542
543
|
|
543
|
-
|
544
|
+
private onBufferReset() {
|
544
545
|
this.sourceBuffers.forEach(([type]) => {
|
545
546
|
if (type) {
|
546
547
|
this.resetBuffer(type);
|
@@ -580,10 +581,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
580
581
|
this.operationQueue = new BufferOperationQueue(this.tracks);
|
581
582
|
}
|
582
583
|
|
583
|
-
|
584
|
-
event: Events.BUFFER_CODECS,
|
585
|
-
data: BufferCodecsData,
|
586
|
-
) {
|
584
|
+
private onBufferCodecs(event: Events.BUFFER_CODECS, data: BufferCodecsData) {
|
587
585
|
const tracks = this.tracks;
|
588
586
|
const trackNames = Object.keys(data);
|
589
587
|
this.log(
|
@@ -614,7 +612,6 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
614
612
|
const sbTrack = transferredTrack?.buffer ? transferredTrack : track;
|
615
613
|
const sbCodec = sbTrack?.pendingCodec || sbTrack?.codec;
|
616
614
|
const trackLevelCodec = sbTrack?.levelCodec;
|
617
|
-
const forceChangeType = !sbTrack || !!this.hls.config.assetPlayerId;
|
618
615
|
if (!track) {
|
619
616
|
track = tracks[trackName] = {
|
620
617
|
buffer: undefined,
|
@@ -637,7 +634,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
637
634
|
);
|
638
635
|
let trackCodec = pickMostCompleteCodecName(codec, levelCodec);
|
639
636
|
const nextCodec = trackCodec?.replace(VIDEO_CODEC_PROFILE_REPLACE, '$1');
|
640
|
-
if (trackCodec &&
|
637
|
+
if (trackCodec && currentCodecFull && currentCodec !== nextCodec) {
|
641
638
|
if (trackName.slice(0, 5) === 'audio') {
|
642
639
|
trackCodec = getCodecCompatibleName(trackCodec, this.appendSource);
|
643
640
|
}
|
@@ -676,7 +673,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
676
673
|
}, {});
|
677
674
|
}
|
678
675
|
|
679
|
-
|
676
|
+
private appendChangeType(
|
680
677
|
type: SourceBufferName,
|
681
678
|
container: string,
|
682
679
|
codec: string,
|
@@ -748,7 +745,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
748
745
|
}
|
749
746
|
}
|
750
747
|
|
751
|
-
|
748
|
+
private onBufferAppending(
|
752
749
|
event: Events.BUFFER_APPENDING,
|
753
750
|
eventData: BufferAppendingData,
|
754
751
|
) {
|
@@ -956,7 +953,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
956
953
|
};
|
957
954
|
}
|
958
955
|
|
959
|
-
|
956
|
+
private onBufferFlushing(
|
960
957
|
event: Events.BUFFER_FLUSHING,
|
961
958
|
data: BufferFlushingData,
|
962
959
|
) {
|
@@ -972,7 +969,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
972
969
|
}
|
973
970
|
}
|
974
971
|
|
975
|
-
|
972
|
+
private onFragParsed(event: Events.FRAG_PARSED, data: FragParsedData) {
|
976
973
|
const { frag, part } = data;
|
977
974
|
const buffersAppendedTo: SourceBufferName[] = [];
|
978
975
|
const elementaryStreams = part
|
@@ -1017,7 +1014,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
1017
1014
|
this.trimBuffers();
|
1018
1015
|
}
|
1019
1016
|
|
1020
|
-
get bufferedToEnd(): boolean {
|
1017
|
+
public get bufferedToEnd(): boolean {
|
1021
1018
|
return (
|
1022
1019
|
this.sourceBufferCount > 0 &&
|
1023
1020
|
!this.sourceBuffers.some(
|
@@ -1029,7 +1026,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
1029
1026
|
|
1030
1027
|
// on BUFFER_EOS mark matching sourcebuffer(s) as "ending" and "ended" and queue endOfStream after remaining operations(s)
|
1031
1028
|
// an undefined data.type will mark all buffers as EOS.
|
1032
|
-
|
1029
|
+
private onBufferEos(event: Events.BUFFER_EOS, data: BufferEOSData) {
|
1033
1030
|
this.sourceBuffers.forEach(([type]) => {
|
1034
1031
|
if (type) {
|
1035
1032
|
const track = this.tracks[type] as SourceBufferTrack;
|
@@ -1078,7 +1075,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
1078
1075
|
}
|
1079
1076
|
}
|
1080
1077
|
|
1081
|
-
|
1078
|
+
private onLevelUpdated(
|
1082
1079
|
event: Events.LEVEL_UPDATED,
|
1083
1080
|
{ details }: LevelUpdatedData,
|
1084
1081
|
) {
|
@@ -1321,7 +1318,7 @@ transfer tracks: ${JSON.stringify(transferredTracks, (key, value) => (key === 'i
|
|
1321
1318
|
);
|
1322
1319
|
}
|
1323
1320
|
|
1324
|
-
|
1321
|
+
private checkPendingTracks() {
|
1325
1322
|
const { bufferCodecEventsTotal, pendingTrackCount, tracks } = this;
|
1326
1323
|
this.log(
|
1327
1324
|
`checkPendingTracks (pending: ${pendingTrackCount} codec events expected: ${bufferCodecEventsTotal}) ${JSON.stringify(tracks)}`,
|
@@ -176,7 +176,7 @@ export default class ErrorController
|
|
176
176
|
case ErrorDetails.SUBTITLE_LOAD_ERROR:
|
177
177
|
case ErrorDetails.SUBTITLE_TRACK_LOAD_TIMEOUT:
|
178
178
|
if (context) {
|
179
|
-
const level = hls.
|
179
|
+
const level = hls.loadLevelObj;
|
180
180
|
if (
|
181
181
|
level &&
|
182
182
|
((context.type === PlaylistContextType.AUDIO_TRACK &&
|
@@ -200,7 +200,7 @@ export default class ErrorController
|
|
200
200
|
return;
|
201
201
|
case ErrorDetails.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED:
|
202
202
|
{
|
203
|
-
const level = hls.
|
203
|
+
const level = hls.loadLevelObj;
|
204
204
|
const restrictedHdcpLevel = level?.attrs['HDCP-LEVEL'];
|
205
205
|
if (restrictedHdcpLevel) {
|
206
206
|
data.errorAction = {
|
@@ -321,7 +321,7 @@ export class FragmentTracker implements ComponentAPI {
|
|
321
321
|
/**
|
322
322
|
* Gets the partial fragment for a certain time
|
323
323
|
*/
|
324
|
-
public getPartialFragment(time: number):
|
324
|
+
public getPartialFragment(time: number): MediaFragment | null {
|
325
325
|
let bestFragment: Fragment | null = null;
|
326
326
|
let timePadding: number;
|
327
327
|
let startTime: number;
|