hls.js 1.6.0-beta.3.0.canary.10980 → 1.6.0-beta.3.0.canary.10982
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 +15 -6
- package/dist/hls.d.ts +15 -6
- package/dist/hls.js +4609 -4503
- package/dist/hls.js.d.ts +15 -6
- package/dist/hls.js.map +1 -1
- package/dist/hls.light.js +5646 -5601
- 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 +3802 -3759
- 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 +4597 -4494
- 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/config.ts +4 -4
- package/src/controller/abr-controller.ts +2 -1
- package/src/controller/audio-stream-controller.ts +7 -5
- package/src/controller/base-stream-controller.ts +2 -2
- package/src/controller/buffer-controller.ts +8 -3
- package/src/controller/error-controller.ts +14 -0
- package/src/controller/id3-track-controller.ts +1 -1
- package/src/controller/interstitial-player.ts +15 -5
- package/src/controller/interstitials-controller.ts +146 -84
- package/src/controller/stream-controller.ts +16 -12
- package/src/define-plugin.d.ts +1 -1
- package/src/hls.ts +4 -1
- package/src/loader/interstitial-event.ts +2 -2
- package/src/utils/codecs.ts +14 -1
- package/src/utils/mediacapabilities-helper.ts +31 -4
- package/src/utils/mp4-tools.ts +2 -3
package/package.json
CHANGED
package/src/config.ts
CHANGED
@@ -308,7 +308,7 @@ export type HlsConfig = {
|
|
308
308
|
interstitialsController?: typeof InterstitialsController;
|
309
309
|
// Option to disable internal playback handling of Interstitials (set to false to disable Interstitials playback without disabling parsing and schedule events)
|
310
310
|
enableInterstitialPlayback: boolean;
|
311
|
-
// Option to disable appending
|
311
|
+
// Option to disable appending Interstitials inline on same timeline and MediaSource as Primary media
|
312
312
|
interstitialAppendInPlace: boolean;
|
313
313
|
// How many seconds past the end of a live playlist to preload Interstitial assets
|
314
314
|
interstitialLiveLookAhead: number;
|
@@ -440,7 +440,7 @@ export const hlsDefaultConfig: HlsConfig = {
|
|
440
440
|
enableEmsgMetadataCues: true,
|
441
441
|
enableEmsgKLVMetadata: false,
|
442
442
|
enableID3MetadataCues: true,
|
443
|
-
enableInterstitialPlayback:
|
443
|
+
enableInterstitialPlayback: __USE_INTERSTITIALS__,
|
444
444
|
interstitialAppendInPlace: true,
|
445
445
|
interstitialLiveLookAhead: 10,
|
446
446
|
useMediaCapabilities: __USE_MEDIA_CAPABILITIES__,
|
@@ -533,7 +533,7 @@ export const hlsDefaultConfig: HlsConfig = {
|
|
533
533
|
: defaultLoadPolicy,
|
534
534
|
},
|
535
535
|
interstitialAssetListLoadPolicy: {
|
536
|
-
default:
|
536
|
+
default: __USE_INTERSTITIALS__
|
537
537
|
? {
|
538
538
|
maxTimeToFirstByteMs: 10000,
|
539
539
|
maxLoadTimeMs: 30000,
|
@@ -582,7 +582,7 @@ export const hlsDefaultConfig: HlsConfig = {
|
|
582
582
|
contentSteeringController: __USE_CONTENT_STEERING__
|
583
583
|
? ContentSteeringController
|
584
584
|
: undefined,
|
585
|
-
interstitialsController:
|
585
|
+
interstitialsController: __USE_INTERSTITIALS__
|
586
586
|
? InterstitialsController
|
587
587
|
: undefined,
|
588
588
|
};
|
@@ -8,6 +8,7 @@ import {
|
|
8
8
|
requiresMediaCapabilitiesDecodingInfo,
|
9
9
|
SUPPORTED_INFO_DEFAULT,
|
10
10
|
} from '../utils/mediacapabilities-helper';
|
11
|
+
import { isHEVC } from '../utils/mp4-tools';
|
11
12
|
import {
|
12
13
|
type AudioTracksByGroup,
|
13
14
|
type CodecSetTier,
|
@@ -804,7 +805,7 @@ class AbrController extends Logger implements AbrComponentAPI {
|
|
804
805
|
currentBw,
|
805
806
|
audioPreference,
|
806
807
|
) ||
|
807
|
-
levelInfo.videoCodec
|
808
|
+
isHEVC(levelInfo.videoCodec)) // Force media capabilities check for HEVC to avoid failure on Windows
|
808
809
|
) {
|
809
810
|
levelInfo.supportedPromise = getMediaDecodingInfoPromise(
|
810
811
|
levelInfo,
|
@@ -797,13 +797,15 @@ class AudioStreamController
|
|
797
797
|
this.state = State.IDLE;
|
798
798
|
}
|
799
799
|
break;
|
800
|
+
case ErrorDetails.BUFFER_ADD_CODEC_ERROR:
|
800
801
|
case ErrorDetails.BUFFER_APPEND_ERROR:
|
801
|
-
|
802
|
-
if (!data.parent || data.parent !== 'audio') {
|
802
|
+
if (data.parent !== 'audio') {
|
803
803
|
return;
|
804
804
|
}
|
805
|
-
|
806
|
-
|
805
|
+
this.resetLoadingState();
|
806
|
+
break;
|
807
|
+
case ErrorDetails.BUFFER_FULL_ERROR:
|
808
|
+
if (data.parent !== 'audio') {
|
807
809
|
return;
|
808
810
|
}
|
809
811
|
if (this.reduceLengthAndFlushBuffer(data)) {
|
@@ -954,7 +956,7 @@ class AudioStreamController
|
|
954
956
|
}
|
955
957
|
const track = tracks.audio;
|
956
958
|
|
957
|
-
track.id =
|
959
|
+
track.id = PlaylistLevelType.AUDIO;
|
958
960
|
|
959
961
|
const variantAudioCodecs = currentLevel.audioCodec;
|
960
962
|
this.log(
|
@@ -454,7 +454,7 @@ export default class BaseStreamController
|
|
454
454
|
) {
|
455
455
|
const config = this.hls.config;
|
456
456
|
if (
|
457
|
-
|
457
|
+
__USE_INTERSTITIALS__ &&
|
458
458
|
config.interstitialsController &&
|
459
459
|
config.enableInterstitialPlayback !== false &&
|
460
460
|
frag.type !== PlaylistLevelType.SUBTITLE
|
@@ -488,7 +488,7 @@ export default class BaseStreamController
|
|
488
488
|
}
|
489
489
|
}
|
490
490
|
}
|
491
|
-
// Skip loading of fragments that overlap completely with appendInPlace
|
491
|
+
// Skip loading of fragments that overlap completely with appendInPlace interstitials
|
492
492
|
const playerQueue = interstitials?.playerQueue;
|
493
493
|
if (playerQueue) {
|
494
494
|
for (let i = playerQueue.length; i--; ) {
|
@@ -1336,7 +1336,6 @@ transfer tracks: ${stringify(transferredTracks, (key, value) => (key === 'initSe
|
|
1336
1336
|
} else {
|
1337
1337
|
// ok, let's create them now !
|
1338
1338
|
this.createSourceBuffers();
|
1339
|
-
this.bufferCreated();
|
1340
1339
|
}
|
1341
1340
|
}
|
1342
1341
|
}
|
@@ -1409,6 +1408,10 @@ transfer tracks: ${stringify(transferredTracks, (key, value) => (key === 'initSe
|
|
1409
1408
|
this.error(
|
1410
1409
|
`error while trying to add sourceBuffer: ${error.message}`,
|
1411
1410
|
);
|
1411
|
+
// remove init segment from queue and delete track info
|
1412
|
+
this.shiftAndExecuteNext(type);
|
1413
|
+
this.operationQueue?.removeBlockers();
|
1414
|
+
delete this.tracks[type];
|
1412
1415
|
this.hls.trigger(Events.ERROR, {
|
1413
1416
|
type: ErrorTypes.MEDIA_ERROR,
|
1414
1417
|
details: ErrorDetails.BUFFER_ADD_CODEC_ERROR,
|
@@ -1416,12 +1419,14 @@ transfer tracks: ${stringify(transferredTracks, (key, value) => (key === 'initSe
|
|
1416
1419
|
error,
|
1417
1420
|
sourceBufferName: type,
|
1418
1421
|
mimeType: mimeType,
|
1422
|
+
parent: track.id as PlaylistLevelType,
|
1419
1423
|
});
|
1420
|
-
|
1424
|
+
return;
|
1421
1425
|
}
|
1422
1426
|
this.trackSourceBuffer(type, track);
|
1423
1427
|
}
|
1424
1428
|
}
|
1429
|
+
this.bufferCreated();
|
1425
1430
|
}
|
1426
1431
|
|
1427
1432
|
private getTrackCodec(track: BaseTrack, trackName: SourceBufferName): string {
|
@@ -1450,7 +1455,7 @@ transfer tracks: ${stringify(transferredTracks, (key, value) => (key === 'initSe
|
|
1450
1455
|
id: track.id,
|
1451
1456
|
listeners: [],
|
1452
1457
|
};
|
1453
|
-
|
1458
|
+
this.removeBufferListeners(type);
|
1454
1459
|
this.addBufferListener(type, 'updatestart', this.onSBUpdateStart);
|
1455
1460
|
this.addBufferListener(type, 'updateend', this.onSBUpdateEnd);
|
1456
1461
|
this.addBufferListener(type, 'error', this.onSBUpdateError);
|
@@ -3,6 +3,7 @@ import { ErrorDetails, ErrorTypes } from '../errors';
|
|
3
3
|
import { Events } from '../events';
|
4
4
|
import { HdcpLevels } from '../types/level';
|
5
5
|
import { PlaylistContextType, PlaylistLevelType } from '../types/loader';
|
6
|
+
import { getCodecsForMimeType } from '../utils/codecs';
|
6
7
|
import {
|
7
8
|
getRetryConfig,
|
8
9
|
isTimeoutError,
|
@@ -506,6 +507,19 @@ export default class ErrorController
|
|
506
507
|
data.errorAction.resolved = true;
|
507
508
|
// Stream controller is responsible for this but won't switch on false start
|
508
509
|
this.hls.nextLoadLevel = this.hls.nextAutoLevel;
|
510
|
+
if (
|
511
|
+
data.details === ErrorDetails.BUFFER_ADD_CODEC_ERROR &&
|
512
|
+
data.mimeType &&
|
513
|
+
data.sourceBufferName !== 'audiovideo'
|
514
|
+
) {
|
515
|
+
const codec = getCodecsForMimeType(data.mimeType);
|
516
|
+
const levels = this.hls.levels;
|
517
|
+
for (let i = levels.length; i--; ) {
|
518
|
+
if (levels[i][`${data.sourceBufferName}Codec`] === codec) {
|
519
|
+
this.hls.removeLevel(i);
|
520
|
+
}
|
521
|
+
}
|
522
|
+
}
|
509
523
|
}
|
510
524
|
}
|
511
525
|
}
|
@@ -461,7 +461,7 @@ class ID3TrackController implements ComponentAPI {
|
|
461
461
|
this.id3Track.addCue(cue);
|
462
462
|
cues[key] = cue;
|
463
463
|
if (
|
464
|
-
|
464
|
+
__USE_INTERSTITIALS__ &&
|
465
465
|
this.hls.config.interstitialsController
|
466
466
|
) {
|
467
467
|
if (key === 'X-ASSET-LIST' || key === 'X-ASSET-URL') {
|
@@ -9,9 +9,17 @@ import {
|
|
9
9
|
} from '../loader/interstitial-event';
|
10
10
|
import { BufferHelper } from '../utils/buffer-helper';
|
11
11
|
import type { HlsConfig } from '../config';
|
12
|
+
import type { InterstitialScheduleEventItem } from '../controller/interstitials-schedule';
|
12
13
|
import type Hls from '../hls';
|
13
14
|
import type { BufferCodecsData, MediaAttachingData } from '../types/events';
|
14
15
|
|
16
|
+
export interface InterstitialPlayer {
|
17
|
+
currentTime: number;
|
18
|
+
duration: number;
|
19
|
+
assetPlayers: (HlsAssetPlayer | null)[];
|
20
|
+
playingIndex: number;
|
21
|
+
scheduleItem: InterstitialScheduleEventItem | null;
|
22
|
+
}
|
15
23
|
export class HlsAssetPlayer {
|
16
24
|
public readonly hls: Hls;
|
17
25
|
public readonly interstitial: InterstitialEvent;
|
@@ -19,7 +27,6 @@ export class HlsAssetPlayer {
|
|
19
27
|
public tracks: Partial<BufferCodecsData> | null = null;
|
20
28
|
private hasDetails: boolean = false;
|
21
29
|
private mediaAttached: HTMLMediaElement | null = null;
|
22
|
-
private playoutOffset: number = 0;
|
23
30
|
|
24
31
|
constructor(
|
25
32
|
HlsPlayerClass: typeof Hls,
|
@@ -49,8 +56,6 @@ export class HlsAssetPlayer {
|
|
49
56
|
this.mediaAttached = media;
|
50
57
|
const event = this.interstitial;
|
51
58
|
if (event.playoutLimit) {
|
52
|
-
this.playoutOffset =
|
53
|
-
event.assetList[event.assetList.indexOf(assetItem)]?.startOffset || 0;
|
54
59
|
media.addEventListener('timeupdate', this.checkPlayout);
|
55
60
|
}
|
56
61
|
});
|
@@ -59,7 +64,8 @@ export class HlsAssetPlayer {
|
|
59
64
|
private checkPlayout = () => {
|
60
65
|
const interstitial = this.interstitial;
|
61
66
|
const playoutLimit = interstitial.playoutLimit;
|
62
|
-
|
67
|
+
const currentTime = this.currentTime;
|
68
|
+
if (this.startOffset + currentTime >= playoutLimit) {
|
63
69
|
this.hls.trigger(Events.PLAYOUT_LIMIT_REACHED, {});
|
64
70
|
}
|
65
71
|
};
|
@@ -98,7 +104,7 @@ export class HlsAssetPlayer {
|
|
98
104
|
}
|
99
105
|
|
100
106
|
get duration(): number {
|
101
|
-
const duration = this.assetItem
|
107
|
+
const duration = this.assetItem.duration;
|
102
108
|
if (!duration) {
|
103
109
|
return 0;
|
104
110
|
}
|
@@ -113,6 +119,10 @@ export class HlsAssetPlayer {
|
|
113
119
|
return Math.max(0, duration - this.currentTime);
|
114
120
|
}
|
115
121
|
|
122
|
+
get startOffset(): number {
|
123
|
+
return this.assetItem.startOffset;
|
124
|
+
}
|
125
|
+
|
116
126
|
get timelineOffset(): number {
|
117
127
|
return this.hls?.config.timelineOffset || 0;
|
118
128
|
}
|