@zenvor/hls.js 1.0.0

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.
Files changed (159) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +472 -0
  3. package/dist/hls-demo.js +26995 -0
  4. package/dist/hls-demo.js.map +1 -0
  5. package/dist/hls.d.mts +4204 -0
  6. package/dist/hls.d.ts +4204 -0
  7. package/dist/hls.js +40050 -0
  8. package/dist/hls.js.d.ts +4204 -0
  9. package/dist/hls.js.map +1 -0
  10. package/dist/hls.light.js +27145 -0
  11. package/dist/hls.light.js.map +1 -0
  12. package/dist/hls.light.min.js +2 -0
  13. package/dist/hls.light.min.js.map +1 -0
  14. package/dist/hls.light.mjs +26392 -0
  15. package/dist/hls.light.mjs.map +1 -0
  16. package/dist/hls.min.js +2 -0
  17. package/dist/hls.min.js.map +1 -0
  18. package/dist/hls.mjs +38956 -0
  19. package/dist/hls.mjs.map +1 -0
  20. package/dist/hls.worker.js +2 -0
  21. package/dist/hls.worker.js.map +1 -0
  22. package/package.json +143 -0
  23. package/src/config.ts +794 -0
  24. package/src/controller/abr-controller.ts +1019 -0
  25. package/src/controller/algo-data-controller.ts +794 -0
  26. package/src/controller/audio-stream-controller.ts +1099 -0
  27. package/src/controller/audio-track-controller.ts +454 -0
  28. package/src/controller/base-playlist-controller.ts +438 -0
  29. package/src/controller/base-stream-controller.ts +2526 -0
  30. package/src/controller/buffer-controller.ts +2015 -0
  31. package/src/controller/buffer-operation-queue.ts +159 -0
  32. package/src/controller/cap-level-controller.ts +367 -0
  33. package/src/controller/cmcd-controller.ts +422 -0
  34. package/src/controller/content-steering-controller.ts +622 -0
  35. package/src/controller/eme-controller.ts +1617 -0
  36. package/src/controller/error-controller.ts +627 -0
  37. package/src/controller/fps-controller.ts +146 -0
  38. package/src/controller/fragment-finders.ts +256 -0
  39. package/src/controller/fragment-tracker.ts +567 -0
  40. package/src/controller/gap-controller.ts +719 -0
  41. package/src/controller/id3-track-controller.ts +488 -0
  42. package/src/controller/interstitial-player.ts +302 -0
  43. package/src/controller/interstitials-controller.ts +2895 -0
  44. package/src/controller/interstitials-schedule.ts +698 -0
  45. package/src/controller/latency-controller.ts +294 -0
  46. package/src/controller/level-controller.ts +776 -0
  47. package/src/controller/stream-controller.ts +1597 -0
  48. package/src/controller/subtitle-stream-controller.ts +508 -0
  49. package/src/controller/subtitle-track-controller.ts +617 -0
  50. package/src/controller/timeline-controller.ts +677 -0
  51. package/src/crypt/aes-crypto.ts +36 -0
  52. package/src/crypt/aes-decryptor.ts +339 -0
  53. package/src/crypt/decrypter-aes-mode.ts +4 -0
  54. package/src/crypt/decrypter.ts +225 -0
  55. package/src/crypt/fast-aes-key.ts +39 -0
  56. package/src/define-plugin.d.ts +17 -0
  57. package/src/demux/audio/aacdemuxer.ts +126 -0
  58. package/src/demux/audio/ac3-demuxer.ts +170 -0
  59. package/src/demux/audio/adts.ts +249 -0
  60. package/src/demux/audio/base-audio-demuxer.ts +205 -0
  61. package/src/demux/audio/dolby.ts +21 -0
  62. package/src/demux/audio/mp3demuxer.ts +85 -0
  63. package/src/demux/audio/mpegaudio.ts +177 -0
  64. package/src/demux/chunk-cache.ts +42 -0
  65. package/src/demux/dummy-demuxed-track.ts +13 -0
  66. package/src/demux/inject-worker.ts +75 -0
  67. package/src/demux/mp4demuxer.ts +234 -0
  68. package/src/demux/sample-aes.ts +198 -0
  69. package/src/demux/transmuxer-interface.ts +449 -0
  70. package/src/demux/transmuxer-worker.ts +221 -0
  71. package/src/demux/transmuxer.ts +560 -0
  72. package/src/demux/tsdemuxer.ts +1256 -0
  73. package/src/demux/video/avc-video-parser.ts +401 -0
  74. package/src/demux/video/base-video-parser.ts +198 -0
  75. package/src/demux/video/exp-golomb.ts +153 -0
  76. package/src/demux/video/hevc-video-parser.ts +736 -0
  77. package/src/empty-es.js +5 -0
  78. package/src/empty.js +3 -0
  79. package/src/errors.ts +107 -0
  80. package/src/events.ts +548 -0
  81. package/src/exports-default.ts +3 -0
  82. package/src/exports-named.ts +81 -0
  83. package/src/hls.ts +1613 -0
  84. package/src/is-supported.ts +54 -0
  85. package/src/loader/date-range.ts +207 -0
  86. package/src/loader/fragment-loader.ts +403 -0
  87. package/src/loader/fragment.ts +487 -0
  88. package/src/loader/interstitial-asset-list.ts +162 -0
  89. package/src/loader/interstitial-event.ts +337 -0
  90. package/src/loader/key-loader.ts +439 -0
  91. package/src/loader/level-details.ts +203 -0
  92. package/src/loader/level-key.ts +259 -0
  93. package/src/loader/load-stats.ts +17 -0
  94. package/src/loader/m3u8-parser.ts +1072 -0
  95. package/src/loader/playlist-loader.ts +839 -0
  96. package/src/polyfills/number.ts +15 -0
  97. package/src/remux/aac-helper.ts +81 -0
  98. package/src/remux/mp4-generator.ts +1380 -0
  99. package/src/remux/mp4-remuxer.ts +1261 -0
  100. package/src/remux/passthrough-remuxer.ts +434 -0
  101. package/src/task-loop.ts +130 -0
  102. package/src/types/algo.ts +44 -0
  103. package/src/types/buffer.ts +105 -0
  104. package/src/types/component-api.ts +20 -0
  105. package/src/types/demuxer.ts +208 -0
  106. package/src/types/events.ts +574 -0
  107. package/src/types/fragment-tracker.ts +23 -0
  108. package/src/types/level.ts +268 -0
  109. package/src/types/loader.ts +198 -0
  110. package/src/types/media-playlist.ts +92 -0
  111. package/src/types/network-details.ts +3 -0
  112. package/src/types/remuxer.ts +104 -0
  113. package/src/types/track.ts +12 -0
  114. package/src/types/transmuxer.ts +46 -0
  115. package/src/types/tuples.ts +6 -0
  116. package/src/types/vtt.ts +11 -0
  117. package/src/utils/arrays.ts +22 -0
  118. package/src/utils/attr-list.ts +192 -0
  119. package/src/utils/binary-search.ts +46 -0
  120. package/src/utils/buffer-helper.ts +173 -0
  121. package/src/utils/cea-608-parser.ts +1413 -0
  122. package/src/utils/chunker.ts +41 -0
  123. package/src/utils/codecs.ts +314 -0
  124. package/src/utils/cues.ts +96 -0
  125. package/src/utils/discontinuities.ts +174 -0
  126. package/src/utils/encryption-methods-util.ts +21 -0
  127. package/src/utils/error-helper.ts +95 -0
  128. package/src/utils/event-listener-helper.ts +16 -0
  129. package/src/utils/ewma-bandwidth-estimator.ts +97 -0
  130. package/src/utils/ewma.ts +43 -0
  131. package/src/utils/fetch-loader.ts +331 -0
  132. package/src/utils/global.ts +2 -0
  133. package/src/utils/hash.ts +10 -0
  134. package/src/utils/hdr.ts +67 -0
  135. package/src/utils/hex.ts +32 -0
  136. package/src/utils/imsc1-ttml-parser.ts +261 -0
  137. package/src/utils/keysystem-util.ts +45 -0
  138. package/src/utils/level-helper.ts +629 -0
  139. package/src/utils/logger.ts +120 -0
  140. package/src/utils/media-option-attributes.ts +49 -0
  141. package/src/utils/mediacapabilities-helper.ts +301 -0
  142. package/src/utils/mediakeys-helper.ts +210 -0
  143. package/src/utils/mediasource-helper.ts +37 -0
  144. package/src/utils/mp4-tools.ts +1473 -0
  145. package/src/utils/number.ts +3 -0
  146. package/src/utils/numeric-encoding-utils.ts +26 -0
  147. package/src/utils/output-filter.ts +46 -0
  148. package/src/utils/rendition-helper.ts +505 -0
  149. package/src/utils/safe-json-stringify.ts +22 -0
  150. package/src/utils/texttrack-utils.ts +164 -0
  151. package/src/utils/time-ranges.ts +17 -0
  152. package/src/utils/timescale-conversion.ts +46 -0
  153. package/src/utils/utf8-utils.ts +18 -0
  154. package/src/utils/variable-substitution.ts +105 -0
  155. package/src/utils/vttcue.ts +384 -0
  156. package/src/utils/vttparser.ts +497 -0
  157. package/src/utils/webvtt-parser.ts +166 -0
  158. package/src/utils/xhr-loader.ts +337 -0
  159. package/src/version.ts +1 -0
@@ -0,0 +1,268 @@
1
+ import type { MediaPlaylist } from './media-playlist';
2
+ import type { LevelDetails } from '../loader/level-details';
3
+ import type { AttrList } from '../utils/attr-list';
4
+ import type { MediaDecodingInfo } from '../utils/mediacapabilities-helper';
5
+
6
+ export interface LevelParsed extends CodecsParsed {
7
+ attrs: LevelAttributes;
8
+ bitrate: number;
9
+ details?: LevelDetails;
10
+ height?: number;
11
+ id?: number;
12
+ name: string;
13
+ supplemental?: CodecsParsed;
14
+ url: string;
15
+ width?: number;
16
+ }
17
+
18
+ export interface CodecsParsed {
19
+ audioCodec?: string;
20
+ videoCodec?: string;
21
+ textCodec?: string;
22
+ unknownCodecs?: string[];
23
+ }
24
+
25
+ export interface LevelAttributes extends AttrList {
26
+ 'ALLOWED-CPC'?: string;
27
+ AUDIO?: string;
28
+ 'AVERAGE-BANDWIDTH'?: string;
29
+ BANDWIDTH?: string;
30
+ 'CLOSED-CAPTIONS'?: string;
31
+ CODECS?: string;
32
+ 'FRAME-RATE'?: string;
33
+ 'HDCP-LEVEL'?: 'TYPE-0' | 'TYPE-1' | 'NONE';
34
+ 'PATHWAY-ID'?: string;
35
+ RESOLUTION?: string;
36
+ SCORE?: string;
37
+ 'STABLE-VARIANT-ID'?: string;
38
+ SUBTITLES?: string;
39
+ 'SUPPLEMENTAL-CODECS'?: string;
40
+ VIDEO?: string;
41
+ 'VIDEO-RANGE'?: VideoRange;
42
+ }
43
+
44
+ export const HdcpLevels = ['NONE', 'TYPE-0', 'TYPE-1', null] as const;
45
+ export type HdcpLevel = (typeof HdcpLevels)[number];
46
+
47
+ export function isHdcpLevel(value: any): value is HdcpLevel {
48
+ return HdcpLevels.indexOf(value) > -1;
49
+ }
50
+
51
+ export const VideoRangeValues = ['SDR', 'PQ', 'HLG'] as const;
52
+ export type VideoRange = (typeof VideoRangeValues)[number];
53
+
54
+ export function isVideoRange(value: any): value is VideoRange {
55
+ return !!value && VideoRangeValues.indexOf(value) > -1;
56
+ }
57
+
58
+ export type VariableMap = Record<string, string>;
59
+
60
+ export const enum HlsSkip {
61
+ No = '',
62
+ Yes = 'YES',
63
+ v2 = 'v2',
64
+ }
65
+
66
+ export function getSkipValue(details: LevelDetails): HlsSkip {
67
+ const { canSkipUntil, canSkipDateRanges, age } = details;
68
+ // A Client SHOULD NOT request a Playlist Delta Update unless it already
69
+ // has a version of the Playlist that is no older than one-half of the Skip Boundary.
70
+ // @see: https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis#section-6.3.7
71
+ const playlistRecentEnough = age < canSkipUntil / 2;
72
+ if (canSkipUntil && playlistRecentEnough) {
73
+ if (canSkipDateRanges) {
74
+ return HlsSkip.v2;
75
+ }
76
+ return HlsSkip.Yes;
77
+ }
78
+ return HlsSkip.No;
79
+ }
80
+
81
+ export class HlsUrlParameters {
82
+ msn?: number;
83
+ part?: number;
84
+ skip?: HlsSkip;
85
+
86
+ constructor(msn?: number, part?: number, skip?: HlsSkip) {
87
+ this.msn = msn;
88
+ this.part = part;
89
+ this.skip = skip;
90
+ }
91
+
92
+ addDirectives(uri: string): string | never {
93
+ const url: URL = new self.URL(uri);
94
+ if (this.msn !== undefined) {
95
+ url.searchParams.set('_HLS_msn', this.msn.toString());
96
+ }
97
+ if (this.part !== undefined) {
98
+ url.searchParams.set('_HLS_part', this.part.toString());
99
+ }
100
+ if (this.skip) {
101
+ url.searchParams.set('_HLS_skip', this.skip);
102
+ }
103
+ return url.href;
104
+ }
105
+ }
106
+
107
+ export class Level {
108
+ public readonly _attrs: LevelAttributes[];
109
+ public readonly audioCodec: string | undefined;
110
+ public readonly bitrate: number;
111
+ public readonly codecSet: string;
112
+ public readonly url: string[];
113
+ public readonly frameRate: number;
114
+ public readonly height: number;
115
+ public readonly id: number;
116
+ public readonly name: string;
117
+ public readonly supplemental: CodecsParsed | undefined;
118
+ public readonly videoCodec: string | undefined;
119
+ public readonly width: number;
120
+ public details?: LevelDetails;
121
+ public fragmentError: number = 0;
122
+ public loadError: number = 0;
123
+ public loaded?: { bytes: number; duration: number };
124
+ public realBitrate: number = 0;
125
+ public supportedPromise?: Promise<MediaDecodingInfo>;
126
+ public supportedResult?: MediaDecodingInfo;
127
+ private _avgBitrate: number = 0;
128
+ private _audioGroups?: (string | undefined)[];
129
+ private _subtitleGroups?: (string | undefined)[];
130
+ // Deprecated (retained for backwards compatibility)
131
+ private readonly _urlId: number = 0;
132
+
133
+ constructor(data: LevelParsed | MediaPlaylist) {
134
+ this.url = [data.url];
135
+ this._attrs = [data.attrs];
136
+ this.bitrate = data.bitrate;
137
+ if (data.details) {
138
+ this.details = data.details;
139
+ }
140
+ this.id = data.id || 0;
141
+ this.name = data.name;
142
+ this.width = data.width || 0;
143
+ this.height = data.height || 0;
144
+ this.frameRate = data.attrs.optionalFloat('FRAME-RATE', 0);
145
+ this._avgBitrate = data.attrs.decimalInteger('AVERAGE-BANDWIDTH');
146
+ this.audioCodec = data.audioCodec;
147
+ this.videoCodec = data.videoCodec;
148
+ this.codecSet = [data.videoCodec, data.audioCodec]
149
+ .filter((c) => !!c)
150
+ .map((s: string) => s.substring(0, 4))
151
+ .join(',');
152
+ if ('supplemental' in data) {
153
+ this.supplemental = data.supplemental;
154
+ const supplementalVideo = data.supplemental?.videoCodec;
155
+ if (supplementalVideo && supplementalVideo !== data.videoCodec) {
156
+ this.codecSet += `,${supplementalVideo.substring(0, 4)}`;
157
+ }
158
+ }
159
+ this.addGroupId('audio', data.attrs.AUDIO);
160
+ this.addGroupId('text', data.attrs.SUBTITLES);
161
+ }
162
+
163
+ get maxBitrate(): number {
164
+ return Math.max(this.realBitrate, this.bitrate);
165
+ }
166
+
167
+ get averageBitrate(): number {
168
+ return this._avgBitrate || this.realBitrate || this.bitrate;
169
+ }
170
+
171
+ get attrs(): LevelAttributes {
172
+ return this._attrs[0];
173
+ }
174
+
175
+ get codecs(): string {
176
+ return this.attrs.CODECS || '';
177
+ }
178
+
179
+ get pathwayId(): string {
180
+ return this.attrs['PATHWAY-ID'] || '.';
181
+ }
182
+
183
+ get videoRange(): VideoRange {
184
+ return this.attrs['VIDEO-RANGE'] || 'SDR';
185
+ }
186
+
187
+ get score(): number {
188
+ return this.attrs.optionalFloat('SCORE', 0);
189
+ }
190
+
191
+ get uri(): string {
192
+ return this.url[0] || '';
193
+ }
194
+
195
+ hasAudioGroup(groupId: string | undefined): boolean {
196
+ return hasGroup(this._audioGroups, groupId);
197
+ }
198
+
199
+ hasSubtitleGroup(groupId: string | undefined): boolean {
200
+ return hasGroup(this._subtitleGroups, groupId);
201
+ }
202
+
203
+ get audioGroups(): (string | undefined)[] | undefined {
204
+ return this._audioGroups;
205
+ }
206
+
207
+ get subtitleGroups(): (string | undefined)[] | undefined {
208
+ return this._subtitleGroups;
209
+ }
210
+
211
+ addGroupId(type: string, groupId: string | undefined) {
212
+ if (!groupId) {
213
+ return;
214
+ }
215
+ if (type === 'audio') {
216
+ let audioGroups = this._audioGroups;
217
+ if (!audioGroups) {
218
+ audioGroups = this._audioGroups = [];
219
+ }
220
+ if (audioGroups.indexOf(groupId) === -1) {
221
+ audioGroups.push(groupId);
222
+ }
223
+ } else if (type === 'text') {
224
+ let subtitleGroups = this._subtitleGroups;
225
+ if (!subtitleGroups) {
226
+ subtitleGroups = this._subtitleGroups = [];
227
+ }
228
+ if (subtitleGroups.indexOf(groupId) === -1) {
229
+ subtitleGroups.push(groupId);
230
+ }
231
+ }
232
+ }
233
+
234
+ // Deprecated methods (retained for backwards compatibility)
235
+ get urlId(): number {
236
+ return 0;
237
+ }
238
+
239
+ set urlId(value: number) {}
240
+
241
+ get audioGroupIds(): (string | undefined)[] | undefined {
242
+ return this.audioGroups ? [this.audioGroupId] : undefined;
243
+ }
244
+
245
+ get textGroupIds(): (string | undefined)[] | undefined {
246
+ return this.subtitleGroups ? [this.textGroupId] : undefined;
247
+ }
248
+
249
+ get audioGroupId(): string | undefined {
250
+ return this.audioGroups?.[0];
251
+ }
252
+
253
+ get textGroupId(): string | undefined {
254
+ return this.subtitleGroups?.[0];
255
+ }
256
+
257
+ addFallback() {}
258
+ }
259
+
260
+ function hasGroup(
261
+ groups: (string | undefined)[] | undefined,
262
+ groupId: string | undefined,
263
+ ): boolean {
264
+ if (!groupId || !groups) {
265
+ return false;
266
+ }
267
+ return groups.indexOf(groupId) !== -1;
268
+ }
@@ -0,0 +1,198 @@
1
+ import type { LoaderConfig } from '../config';
2
+ import type { HlsUrlParameters, Level } from './level';
3
+ import type { MediaPlaylist } from './media-playlist';
4
+ import type { NullableNetworkDetails } from './network-details';
5
+ import type { Fragment } from '../loader/fragment';
6
+ import type { Part } from '../loader/fragment';
7
+ import type { KeyLoaderInfo } from '../loader/key-loader';
8
+ import type { LevelDetails } from '../loader/level-details';
9
+
10
+ export interface LoaderContext {
11
+ // target URL
12
+ url: string;
13
+ // loader response type (arraybuffer or default response type for playlist)
14
+ responseType: string;
15
+ // headers
16
+ headers?: Record<string, string>;
17
+ // start byte range offset
18
+ rangeStart?: number;
19
+ // end byte range offset
20
+ rangeEnd?: number;
21
+ // true if onProgress should report partial chunk of loaded content
22
+ progressData?: boolean;
23
+ }
24
+
25
+ export interface FragmentLoaderContext extends LoaderContext {
26
+ frag: Fragment;
27
+ part: Part | null;
28
+ resetIV?: boolean;
29
+ }
30
+
31
+ export interface KeyLoaderContext extends LoaderContext {
32
+ keyInfo: KeyLoaderInfo;
33
+ frag: Fragment;
34
+ }
35
+
36
+ export interface LoaderConfiguration {
37
+ // LoaderConfig policy that overrides required settings
38
+ loadPolicy: LoaderConfig;
39
+ /**
40
+ * @deprecated use LoaderConfig timeoutRetry and errorRetry maxNumRetry
41
+ */
42
+ // Max number of load retries
43
+ maxRetry: number;
44
+ /**
45
+ * @deprecated use LoaderConfig maxTimeToFirstByteMs and maxLoadTimeMs
46
+ */
47
+ // Timeout after which `onTimeOut` callback will be triggered
48
+ // when loading has not finished after that delay
49
+ timeout: number;
50
+ /**
51
+ * @deprecated use LoaderConfig timeoutRetry and errorRetry retryDelayMs
52
+ */
53
+ // Delay between an I/O error and following connection retry (ms).
54
+ // This to avoid spamming the server
55
+ retryDelay: number;
56
+ /**
57
+ * @deprecated use LoaderConfig timeoutRetry and errorRetry maxRetryDelayMs
58
+ */
59
+ // max connection retry delay (ms)
60
+ maxRetryDelay: number;
61
+ // When streaming progressively, this is the minimum chunk size required to emit a PROGRESS event
62
+ highWaterMark?: number;
63
+ }
64
+
65
+ export interface LoaderResponse {
66
+ url: string;
67
+ data?: string | ArrayBuffer | Object;
68
+ // Errors can include HTTP status code and error message
69
+ // Successful responses should include status code 200
70
+ code?: number;
71
+ text?: string;
72
+ }
73
+
74
+ export interface LoaderStats {
75
+ aborted: boolean;
76
+ loaded: number;
77
+ retry: number;
78
+ total: number;
79
+ chunkCount: number;
80
+ bwEstimate: number;
81
+ loading: HlsProgressivePerformanceTiming;
82
+ parsing: HlsPerformanceTiming;
83
+ buffering: HlsProgressivePerformanceTiming;
84
+ }
85
+
86
+ export interface HlsPerformanceTiming {
87
+ start: number;
88
+ end: number;
89
+ }
90
+
91
+ export interface HlsChunkPerformanceTiming extends HlsPerformanceTiming {
92
+ executeStart: number;
93
+ executeEnd: number;
94
+ }
95
+
96
+ export interface HlsProgressivePerformanceTiming extends HlsPerformanceTiming {
97
+ first: number;
98
+ }
99
+
100
+ export type LoaderOnSuccess<T extends LoaderContext> = (
101
+ response: LoaderResponse,
102
+ stats: LoaderStats,
103
+ context: T,
104
+ networkDetails: NullableNetworkDetails,
105
+ ) => void;
106
+
107
+ export type LoaderOnProgress<T extends LoaderContext> = (
108
+ stats: LoaderStats,
109
+ context: T,
110
+ data: string | ArrayBuffer,
111
+ networkDetails: NullableNetworkDetails,
112
+ ) => void;
113
+
114
+ export type LoaderOnError<T extends LoaderContext> = (
115
+ error: {
116
+ // error status code
117
+ code: number;
118
+ // error description
119
+ text: string;
120
+ },
121
+ context: T,
122
+ networkDetails: NullableNetworkDetails,
123
+ stats: LoaderStats,
124
+ ) => void;
125
+
126
+ export type LoaderOnTimeout<T extends LoaderContext> = (
127
+ stats: LoaderStats,
128
+ context: T,
129
+ networkDetails: NullableNetworkDetails,
130
+ ) => void;
131
+
132
+ export type LoaderOnAbort<T extends LoaderContext> = (
133
+ stats: LoaderStats,
134
+ context: T,
135
+ networkDetails: NullableNetworkDetails,
136
+ ) => void;
137
+
138
+ export interface LoaderCallbacks<T extends LoaderContext> {
139
+ onSuccess: LoaderOnSuccess<T>;
140
+ onError: LoaderOnError<T>;
141
+ onTimeout: LoaderOnTimeout<T>;
142
+ onAbort?: LoaderOnAbort<T>;
143
+ onProgress?: LoaderOnProgress<T>;
144
+ }
145
+
146
+ export interface Loader<T extends LoaderContext> {
147
+ destroy(): void;
148
+ abort(): void;
149
+ load(
150
+ context: T,
151
+ config: LoaderConfiguration,
152
+ callbacks: LoaderCallbacks<T>,
153
+ ): void;
154
+ /**
155
+ * `getCacheAge()` is called by hls.js to get the duration that a given object
156
+ * has been sitting in a cache proxy when playing live. If implemented,
157
+ * this should return a value in seconds.
158
+ *
159
+ * For HTTP based loaders, this should return the contents of the "age" header.
160
+ *
161
+ * @returns time object being lodaded
162
+ */
163
+ getCacheAge?: () => number | null;
164
+ getResponseHeader?: (name: string) => string | null;
165
+ context: T | null;
166
+ stats: LoaderStats;
167
+ }
168
+
169
+ export const enum PlaylistContextType {
170
+ MANIFEST = 'manifest',
171
+ LEVEL = 'level',
172
+ AUDIO_TRACK = 'audioTrack',
173
+ SUBTITLE_TRACK = 'subtitleTrack',
174
+ }
175
+
176
+ export const enum PlaylistLevelType {
177
+ MAIN = 'main',
178
+ AUDIO = 'audio',
179
+ SUBTITLE = 'subtitle',
180
+ }
181
+
182
+ export interface PlaylistLoaderContext extends LoaderContext {
183
+ type: PlaylistContextType;
184
+ // the level index to load
185
+ level: number | null;
186
+ // level or track id from LevelLoadingData / TrackLoadingData
187
+ id: number | null;
188
+ // Media Playlist Group ID
189
+ groupId?: string;
190
+ // Content Steering Pathway ID (or undefined for default Pathway ".")
191
+ pathwayId?: string;
192
+ // internal representation of a parsed m3u8 level playlist
193
+ levelDetails?: LevelDetails;
194
+ // Blocking playlist request delivery directives (or null id none were added to playlist url
195
+ deliveryDirectives: HlsUrlParameters | null;
196
+ // Reference to level or track object in hls.levels, hls.allAudioTracks, or hls.allSubtitleTracks (null when loading MVP)
197
+ levelOrTrack: Level | MediaPlaylist | null;
198
+ }
@@ -0,0 +1,92 @@
1
+ import type { Level, VideoRange } from './level';
2
+ import type { PlaylistLevelType } from './loader';
3
+ import type { LevelDetails } from '../loader/level-details';
4
+ import type { AttrList } from '../utils/attr-list';
5
+
6
+ export type AudioPlaylistType = 'AUDIO';
7
+
8
+ export type MainPlaylistType = AudioPlaylistType | 'VIDEO';
9
+
10
+ export type SubtitlePlaylistType = 'SUBTITLES' | 'CLOSED-CAPTIONS';
11
+
12
+ export type MediaPlaylistType = MainPlaylistType | SubtitlePlaylistType;
13
+
14
+ export type MediaSelection = {
15
+ [PlaylistLevelType.MAIN]: Level;
16
+ [PlaylistLevelType.AUDIO]?: MediaPlaylist;
17
+ [PlaylistLevelType.SUBTITLE]?: MediaPlaylist;
18
+ };
19
+
20
+ export type VideoSelectionOption = {
21
+ preferHDR?: boolean;
22
+ allowedVideoRanges?: Array<VideoRange>;
23
+ videoCodec?: string;
24
+ };
25
+
26
+ export type AudioSelectionOption = {
27
+ lang?: string;
28
+ assocLang?: string;
29
+ characteristics?: string;
30
+ channels?: string;
31
+ name?: string;
32
+ audioCodec?: string;
33
+ groupId?: string;
34
+ default?: boolean;
35
+ };
36
+
37
+ export type SubtitleSelectionOption = {
38
+ id?: number;
39
+ lang?: string;
40
+ assocLang?: string;
41
+ characteristics?: string;
42
+ name?: string;
43
+ groupId?: string;
44
+ default?: boolean;
45
+ forced?: boolean;
46
+ };
47
+
48
+ // audioTracks, captions and subtitles returned by `M3U8Parser.parseMasterPlaylistMedia`
49
+ export interface MediaPlaylist {
50
+ attrs: MediaAttributes;
51
+ audioCodec?: string;
52
+ autoselect: boolean; // implicit false if not present
53
+ bitrate: number;
54
+ channels?: string;
55
+ characteristics?: string;
56
+ details?: LevelDetails;
57
+ height?: number;
58
+ default: boolean; // implicit false if not present
59
+ forced: boolean; // implicit false if not present
60
+ groupId: string; // required in HLS playlists
61
+ id: number; // incrementing number to track media playlists
62
+ instreamId?: string;
63
+ lang?: string;
64
+ assocLang?: string;
65
+ name: string;
66
+ textCodec?: string;
67
+ unknownCodecs?: string[];
68
+ // 'main' is a custom type added to signal a audioCodec in main track?; see playlist-loader~L310
69
+ type: MediaPlaylistType | 'main';
70
+ url: string;
71
+ videoCodec?: string;
72
+ width?: number;
73
+ // keep a reference to the track node that is associated with this MediaPlaylist
74
+ trackNode?: HTMLTrackElement;
75
+ }
76
+
77
+ export interface MediaAttributes extends AttrList {
78
+ 'ASSOC-LANGUAGE'?: string;
79
+ AUTOSELECT?: 'YES' | 'NO';
80
+ CHANNELS?: string;
81
+ CHARACTERISTICS?: string;
82
+ DEFAULT?: 'YES' | 'NO';
83
+ FORCED?: 'YES' | 'NO';
84
+ 'GROUP-ID': string;
85
+ 'INSTREAM-ID'?: string;
86
+ LANGUAGE?: string;
87
+ NAME: string;
88
+ 'PATHWAY-ID'?: string;
89
+ 'STABLE-RENDITION-ID'?: string;
90
+ TYPE?: 'AUDIO' | 'VIDEO' | 'SUBTITLES' | 'CLOSED-CAPTIONS';
91
+ URI?: string;
92
+ }
@@ -0,0 +1,3 @@
1
+ export type NetworkDetails = Response | XMLHttpRequest;
2
+
3
+ export type NullableNetworkDetails = NetworkDetails | null;
@@ -0,0 +1,104 @@
1
+ import type { SourceBufferName } from './buffer';
2
+ import type {
3
+ DemuxedAudioTrack,
4
+ DemuxedMetadataTrack,
5
+ DemuxedUserdataTrack,
6
+ DemuxedVideoTrack,
7
+ DemuxedVideoTrackBase,
8
+ MetadataSample,
9
+ UserdataSample,
10
+ } from './demuxer';
11
+ import type { PlaylistLevelType } from './loader';
12
+ import type { TrackSet } from './track';
13
+ import type { DecryptData } from '../loader/level-key';
14
+ import type { TimestampOffset } from '../utils/timescale-conversion';
15
+
16
+ export interface Remuxer {
17
+ remux(
18
+ audioTrack: DemuxedAudioTrack,
19
+ videoTrack: DemuxedVideoTrackBase,
20
+ id3Track: DemuxedMetadataTrack,
21
+ textTrack: DemuxedUserdataTrack,
22
+ timeOffset: number,
23
+ accurateTimeOffset: boolean,
24
+ flush: boolean,
25
+ playlistType: PlaylistLevelType,
26
+ ): RemuxerResult;
27
+ resetInitSegment(
28
+ initSegment: Uint8Array | undefined,
29
+ audioCodec: string | undefined,
30
+ videoCodec: string | undefined,
31
+ decryptdata: DecryptData | null,
32
+ ): void;
33
+ resetTimeStamp(defaultInitPTS: TimestampOffset | null): void;
34
+ resetNextTimestamp(): void;
35
+ destroy(): void;
36
+ }
37
+
38
+ export interface RemuxedTrack {
39
+ data1: Uint8Array<ArrayBuffer>;
40
+ data2?: Uint8Array<ArrayBuffer>;
41
+ startPTS: number;
42
+ endPTS: number;
43
+ startDTS: number;
44
+ endDTS: number;
45
+ type: SourceBufferName;
46
+ hasAudio: boolean;
47
+ hasVideo: boolean;
48
+ independent?: boolean;
49
+ firstKeyFrame?: number;
50
+ firstKeyFramePTS?: number;
51
+ nb: number;
52
+ transferredData1?: ArrayBuffer;
53
+ transferredData2?: ArrayBuffer;
54
+ dropped?: number;
55
+ encrypted?: boolean;
56
+ }
57
+
58
+ export interface RemuxedMetadata {
59
+ samples: MetadataSample[];
60
+ }
61
+
62
+ export interface RemuxedUserdata {
63
+ samples: UserdataSample[];
64
+ }
65
+
66
+ export type Mp4SampleFlags = {
67
+ isLeading: 0;
68
+ isDependedOn: 0;
69
+ hasRedundancy: 0;
70
+ degradPrio: 0;
71
+ dependsOn: 1 | 2;
72
+ isNonSync: 0 | 1;
73
+ };
74
+
75
+ export type Mp4Sample = {
76
+ size: number;
77
+ duration: number;
78
+ cts: number;
79
+ flags: Mp4SampleFlags;
80
+ };
81
+
82
+ export type RemuxedAudioTrackSamples = DemuxedAudioTrack & {
83
+ samples: Mp4Sample[];
84
+ };
85
+
86
+ export type RemuxedVideoTrackSamples = DemuxedVideoTrack & {
87
+ samples: Mp4Sample[];
88
+ };
89
+
90
+ export interface RemuxerResult {
91
+ audio?: RemuxedTrack;
92
+ video?: RemuxedTrack;
93
+ text?: RemuxedUserdata;
94
+ id3?: RemuxedMetadata;
95
+ initSegment?: InitSegmentData;
96
+ independent?: boolean;
97
+ }
98
+
99
+ export interface InitSegmentData {
100
+ tracks?: TrackSet;
101
+ initPTS: number | undefined;
102
+ timescale: number | undefined;
103
+ trackId: number | undefined;
104
+ }
@@ -0,0 +1,12 @@
1
+ import type { BaseTrack } from './buffer';
2
+
3
+ export interface TrackSet {
4
+ audio?: Track;
5
+ video?: Track;
6
+ audiovideo?: Track;
7
+ }
8
+
9
+ export interface Track extends BaseTrack {
10
+ buffer?: SourceBuffer; // eslint-disable-line no-restricted-globals
11
+ initSegment?: Uint8Array<ArrayBuffer>;
12
+ }