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.
@@ -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.levels[hls.loadLevel];
676
- if (minLevel?.bitrate < autoLevel?.bitrate) {
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: string = State.STOPPED;
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
- return BufferHelper.bufferInfo(
1215
- bufferable,
1216
- pos,
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
- public media: HTMLMediaElement | null = null;
85
+ private media: HTMLMediaElement | null = null;
86
86
 
87
87
  // A reference to the active media source
88
- public mediaSource: MediaSource | null = null;
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
- protected registerListeners() {
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
- protected unregisterListeners() {
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
- protected onManifestParsed(
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
- protected onMediaAttaching(
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
- protected onMediaDetaching(
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
- protected onBufferReset() {
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
- protected onBufferCodecs(
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 && (currentCodec !== nextCodec || forceChangeType)) {
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
- protected appendChangeType(
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
- protected onBufferAppending(
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
- protected onBufferFlushing(
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
- protected onFragParsed(event: Events.FRAG_PARSED, data: FragParsedData) {
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
- protected onBufferEos(event: Events.BUFFER_EOS, data: BufferEOSData) {
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
- protected onLevelUpdated(
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
- protected checkPendingTracks() {
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.levels[hls.loadLevel];
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.levels[hls.loadLevel];
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): Fragment | null {
324
+ public getPartialFragment(time: number): MediaFragment | null {
325
325
  let bestFragment: Fragment | null = null;
326
326
  let timePadding: number;
327
327
  let startTime: number;