dasha 4.0.0-alpha.3 → 4.0.0-alpha.4

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/dasha.cjs CHANGED
@@ -21,32 +21,17 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  }) : target, mod));
22
22
 
23
23
  //#endregion
24
+ let node_crypto = require("node:crypto");
25
+ node_crypto = __toESM(node_crypto);
24
26
  let node_fs = require("node:fs");
25
- node_fs = __toESM(node_fs);
26
27
  let barsic = require("barsic");
27
- barsic = __toESM(barsic);
28
28
  let node_fs_promises = require("node:fs/promises");
29
- node_fs_promises = __toESM(node_fs_promises);
30
29
  let node_url = require("node:url");
31
- node_url = __toESM(node_url);
32
30
  let node_path = require("node:path");
33
31
  node_path = __toESM(node_path);
34
32
  let temporal_polyfill = require("temporal-polyfill");
35
- temporal_polyfill = __toESM(temporal_polyfill);
36
33
  let __xmldom_xmldom = require("@xmldom/xmldom");
37
- __xmldom_xmldom = __toESM(__xmldom_xmldom);
38
- let node_crypto = require("node:crypto");
39
- node_crypto = __toESM(node_crypto);
40
34
 
41
- //#region lib/shared/media-type.ts
42
- const MEDIA_TYPES = {
43
- VIDEO: "video",
44
- AUDIO: "audio",
45
- SUBTITLES: "subtitle",
46
- CLOSED_CAPTIONS: "closed-captions"
47
- };
48
-
49
- //#endregion
50
35
  //#region lib/shared/encrypt-method.ts
51
36
  const ENCRYPT_METHODS = {
52
37
  NONE: "none",
@@ -59,6 +44,23 @@ const ENCRYPT_METHODS = {
59
44
  UNKNOWN: "unknown"
60
45
  };
61
46
 
47
+ //#endregion
48
+ //#region lib/shared/encrypt-info.ts
49
+ var EncryptInfo = class {
50
+ method = ENCRYPT_METHODS.NONE;
51
+ key;
52
+ iv;
53
+ drm;
54
+ constructor(method) {
55
+ this.method = this.parseMethod(method);
56
+ this.drm = {};
57
+ }
58
+ parseMethod(method) {
59
+ if (method) return ENCRYPT_METHODS[method.replace("-", "_")];
60
+ else return ENCRYPT_METHODS.UNKNOWN;
61
+ }
62
+ };
63
+
62
64
  //#endregion
63
65
  //#region lib/shared/extractor-type.ts
64
66
  const EXTRACTOR_TYPES = {
@@ -68,6 +70,132 @@ const EXTRACTOR_TYPES = {
68
70
  MSS: "MSS"
69
71
  };
70
72
 
73
+ //#endregion
74
+ //#region lib/shared/media-part.ts
75
+ var MediaPart = class {
76
+ mediaSegments = [];
77
+ constructor(segments) {
78
+ this.mediaSegments = segments || [];
79
+ }
80
+ };
81
+
82
+ //#endregion
83
+ //#region lib/shared/media-segment.ts
84
+ var MediaSegment = class MediaSegment {
85
+ index = NaN;
86
+ duration = NaN;
87
+ title;
88
+ dateTime;
89
+ startRange;
90
+ get stopRange() {
91
+ return this.startRange !== void 0 && this.expectLength !== void 0 ? this.startRange + this.expectLength - 1 : void 0;
92
+ }
93
+ expectLength;
94
+ encryptInfo = new EncryptInfo();
95
+ get isEncrypted() {
96
+ return this.encryptInfo.method !== ENCRYPT_METHODS.NONE;
97
+ }
98
+ url = "";
99
+ nameFromVar;
100
+ equals(segment) {
101
+ if (segment instanceof MediaSegment) return this.index == segment.index && Math.abs(this.duration - segment.duration) < .001 && this.title == segment.title && this.startRange == segment.startRange && this.stopRange == segment.stopRange && this.expectLength == segment.expectLength && this.url == segment.url;
102
+ else return false;
103
+ }
104
+ getHashCode() {
105
+ const payload = [
106
+ this.index,
107
+ this.duration,
108
+ this.title,
109
+ this.startRange,
110
+ this.stopRange,
111
+ this.expectLength,
112
+ this.url
113
+ ].join("-");
114
+ return node_crypto.default.createHash("md5").update(payload).digest("hex");
115
+ }
116
+ };
117
+
118
+ //#endregion
119
+ //#region lib/shared/media-type.ts
120
+ const MEDIA_TYPES = {
121
+ VIDEO: "video",
122
+ AUDIO: "audio",
123
+ SUBTITLES: "subtitle",
124
+ CLOSED_CAPTIONS: "closed-captions"
125
+ };
126
+
127
+ //#endregion
128
+ //#region lib/shared/stream-spec.ts
129
+ var StreamSpec = class {
130
+ mediaType;
131
+ groupId = null;
132
+ language;
133
+ name;
134
+ default;
135
+ skippedDuration;
136
+ bandwidth;
137
+ codecs = null;
138
+ resolution;
139
+ frameRate;
140
+ channels = null;
141
+ extension = null;
142
+ role;
143
+ videoRange;
144
+ characteristics;
145
+ publishTime;
146
+ audioId;
147
+ videoId;
148
+ subtitleId;
149
+ periodId = null;
150
+ url = "";
151
+ originalUrl = "";
152
+ playlist;
153
+ get segmentsCount() {
154
+ return this.playlist?.mediaParts.reduce((sum, part) => sum + part.mediaSegments.length, 0) ?? 0;
155
+ }
156
+ toShortString() {
157
+ let prefixStr = "";
158
+ let returnStr = "";
159
+ const encStr = "";
160
+ const bandwidth = this.bandwidth ? `${this.bandwidth / 1e3} Kbps` : "";
161
+ const channels = this.channels ? `${this.channels}CH` : "";
162
+ if (this.mediaType === MEDIA_TYPES.AUDIO) {
163
+ prefixStr = `Aud ${encStr}`;
164
+ returnStr = [
165
+ this.groupId,
166
+ bandwidth,
167
+ this.name,
168
+ this.codecs,
169
+ this.language,
170
+ channels,
171
+ this.role
172
+ ].filter(Boolean).join(" | ");
173
+ } else if (this.mediaType === MEDIA_TYPES.SUBTITLES) {
174
+ prefixStr = `Sub ${encStr}`;
175
+ returnStr = [
176
+ this.groupId,
177
+ this.language,
178
+ this.name,
179
+ this.codecs,
180
+ this.role
181
+ ].filter(Boolean).join(" | ");
182
+ } else {
183
+ prefixStr = `Vid ${encStr}`;
184
+ returnStr = [
185
+ this.resolution,
186
+ bandwidth,
187
+ this.groupId,
188
+ this.frameRate,
189
+ this.codecs,
190
+ this.videoRange,
191
+ this.role
192
+ ].filter(Boolean).join(" | ");
193
+ }
194
+ returnStr = `${prefixStr} | ${returnStr}`;
195
+ return returnStr.trim();
196
+ }
197
+ };
198
+
71
199
  //#endregion
72
200
  //#region lib/shared/role-type.ts
73
201
  const ROLE_TYPE = {
@@ -184,23 +312,6 @@ var DefaultHlsContentProcessor = class DefaultHlsContentProcessor {
184
312
  }
185
313
  };
186
314
 
187
- //#endregion
188
- //#region lib/shared/encrypt-info.ts
189
- var EncryptInfo = class {
190
- method = ENCRYPT_METHODS.NONE;
191
- key;
192
- iv;
193
- drm;
194
- constructor(method) {
195
- this.method = this.parseMethod(method);
196
- this.drm = {};
197
- }
198
- parseMethod(method) {
199
- if (method) return ENCRYPT_METHODS[method.replace("-", "_")];
200
- else return ENCRYPT_METHODS.UNKNOWN;
201
- }
202
- };
203
-
204
315
  //#endregion
205
316
  //#region lib/hls/hls-key-processor.ts
206
317
  var DefaultHlsKeyProcessor = class {
@@ -281,78 +392,6 @@ var ParserConfig = class {
281
392
  keyRetryCount = 3;
282
393
  };
283
394
 
284
- //#endregion
285
- //#region lib/shared/stream-spec.ts
286
- var StreamSpec = class {
287
- mediaType;
288
- groupId = null;
289
- language;
290
- name;
291
- default;
292
- skippedDuration;
293
- bandwidth;
294
- codecs = null;
295
- resolution;
296
- frameRate;
297
- channels = null;
298
- extension = null;
299
- role;
300
- videoRange;
301
- characteristics;
302
- publishTime;
303
- audioId;
304
- videoId;
305
- subtitleId;
306
- periodId = null;
307
- url = "";
308
- originalUrl = "";
309
- playlist;
310
- get segmentsCount() {
311
- return this.playlist?.mediaParts.reduce((sum, part) => sum + part.mediaSegments.length, 0) ?? 0;
312
- }
313
- toShortString() {
314
- let prefixStr = "";
315
- let returnStr = "";
316
- const encStr = "";
317
- const bandwidth = this.bandwidth ? `${this.bandwidth / 1e3} Kbps` : "";
318
- const channels = this.channels ? `${this.channels}CH` : "";
319
- if (this.mediaType === MEDIA_TYPES.AUDIO) {
320
- prefixStr = `Aud ${encStr}`;
321
- returnStr = [
322
- this.groupId,
323
- bandwidth,
324
- this.name,
325
- this.codecs,
326
- this.language,
327
- channels,
328
- this.role
329
- ].filter(Boolean).join(" | ");
330
- } else if (this.mediaType === MEDIA_TYPES.SUBTITLES) {
331
- prefixStr = `Sub ${encStr}`;
332
- returnStr = [
333
- this.groupId,
334
- this.language,
335
- this.name,
336
- this.codecs,
337
- this.role
338
- ].filter(Boolean).join(" | ");
339
- } else {
340
- prefixStr = `Vid ${encStr}`;
341
- returnStr = [
342
- this.resolution,
343
- bandwidth,
344
- this.groupId,
345
- this.frameRate,
346
- this.codecs,
347
- this.videoRange,
348
- this.role
349
- ].filter(Boolean).join(" | ");
350
- }
351
- returnStr = `${prefixStr} | ${returnStr}`;
352
- return returnStr.trim();
353
- }
354
- };
355
-
356
395
  //#endregion
357
396
  //#region lib/dash/dash-tags.ts
358
397
  const DASH_TAGS = {
@@ -431,51 +470,6 @@ var Playlist = class {
431
470
  mediaParts = [];
432
471
  };
433
472
 
434
- //#endregion
435
- //#region lib/shared/media-part.ts
436
- var MediaPart = class {
437
- mediaSegments = [];
438
- constructor(segments) {
439
- this.mediaSegments = segments || [];
440
- }
441
- };
442
-
443
- //#endregion
444
- //#region lib/shared/media-segment.ts
445
- var MediaSegment = class MediaSegment {
446
- index = NaN;
447
- duration = NaN;
448
- title;
449
- dateTime;
450
- startRange;
451
- get stopRange() {
452
- return this.startRange !== void 0 && this.expectLength !== void 0 ? this.startRange + this.expectLength - 1 : void 0;
453
- }
454
- expectLength;
455
- encryptInfo = new EncryptInfo();
456
- get isEncrypted() {
457
- return this.encryptInfo.method !== ENCRYPT_METHODS.NONE;
458
- }
459
- url = "";
460
- nameFromVar;
461
- equals(segment) {
462
- if (segment instanceof MediaSegment) return this.index == segment.index && Math.abs(this.duration - segment.duration) < .001 && this.title == segment.title && this.startRange == segment.startRange && this.stopRange == segment.stopRange && this.expectLength == segment.expectLength && this.url == segment.url;
463
- else return false;
464
- }
465
- getHashCode() {
466
- const payload = [
467
- this.index,
468
- this.duration,
469
- this.title,
470
- this.startRange,
471
- this.stopRange,
472
- this.expectLength,
473
- this.url
474
- ].join("-");
475
- return node_crypto.default.createHash("md5").update(payload).digest("hex");
476
- }
477
- };
478
-
479
473
  //#endregion
480
474
  //#region lib/dash/dash-utils.ts
481
475
  /**
@@ -1199,10 +1193,23 @@ var StreamExtractor = class {
1199
1193
  };
1200
1194
 
1201
1195
  //#endregion
1196
+ exports.DASH_TAGS = DASH_TAGS;
1197
+ exports.DashExtractor = DashExtractor;
1198
+ exports.DefaultDashContentProcessor = DefaultDashContentProcessor;
1199
+ exports.DefaultHlsContentProcessor = DefaultHlsContentProcessor;
1200
+ exports.DefaultHlsKeyProcessor = DefaultHlsKeyProcessor;
1202
1201
  exports.DefaultUrlProcessor = DefaultUrlProcessor;
1203
1202
  exports.ENCRYPT_METHODS = ENCRYPT_METHODS;
1204
1203
  exports.EXTRACTOR_TYPES = EXTRACTOR_TYPES;
1204
+ exports.EncryptInfo = EncryptInfo;
1205
+ exports.HLS_TAGS = HLS_TAGS;
1206
+ exports.HlsExtractor = HlsExtractor;
1205
1207
  exports.MEDIA_TYPES = MEDIA_TYPES;
1208
+ exports.MediaPart = MediaPart;
1209
+ exports.MediaSegment = MediaSegment;
1206
1210
  exports.ParserConfig = ParserConfig;
1207
1211
  exports.ROLE_TYPE = ROLE_TYPE;
1208
- exports.StreamExtractor = StreamExtractor;
1212
+ exports.StreamExtractor = StreamExtractor;
1213
+ exports.StreamSpec = StreamSpec;
1214
+ exports.getRange = getRange;
1215
+ exports.parseRange = parseRange;
package/dist/dasha.d.cts CHANGED
@@ -1,12 +1,3 @@
1
- //#region lib/shared/media-type.d.ts
2
- declare const MEDIA_TYPES: {
3
- readonly VIDEO: "video";
4
- readonly AUDIO: "audio";
5
- readonly SUBTITLES: "subtitle";
6
- readonly CLOSED_CAPTIONS: "closed-captions";
7
- };
8
- type MediaType = (typeof MEDIA_TYPES)[keyof typeof MEDIA_TYPES];
9
- //#endregion
10
1
  //#region lib/shared/encrypt-method.d.ts
11
2
  declare const ENCRYPT_METHODS: {
12
3
  readonly NONE: "none";
@@ -20,30 +11,6 @@ declare const ENCRYPT_METHODS: {
20
11
  };
21
12
  type EncryptMethod = (typeof ENCRYPT_METHODS)[keyof typeof ENCRYPT_METHODS];
22
13
  //#endregion
23
- //#region lib/shared/extractor-type.d.ts
24
- declare const EXTRACTOR_TYPES: {
25
- readonly MPEG_DASH: "MPEG_DASH";
26
- readonly HLS: "HLS";
27
- readonly HTTP_LIVE: "HTTP_LIVE";
28
- readonly MSS: "MSS";
29
- };
30
- type ExtractorType = (typeof EXTRACTOR_TYPES)[keyof typeof EXTRACTOR_TYPES];
31
- //#endregion
32
- //#region lib/shared/role-type.d.ts
33
- declare const ROLE_TYPE: {
34
- Subtitle: number;
35
- Main: number;
36
- Alternate: number;
37
- Supplementary: number;
38
- Commentary: number;
39
- Dub: number;
40
- Description: number;
41
- Sign: number;
42
- Metadata: number;
43
- ForcedSubtitle: number;
44
- };
45
- type RoleType = (typeof ROLE_TYPE)[keyof typeof ROLE_TYPE];
46
- //#endregion
47
14
  //#region lib/shared/encrypt-info.d.ts
48
15
  type DrmType = 'widevine' | 'playready' | 'fairplay';
49
16
  declare class EncryptInfo {
@@ -58,41 +25,14 @@ declare class EncryptInfo {
58
25
  parseMethod(method?: string | null): EncryptMethod;
59
26
  }
60
27
  //#endregion
61
- //#region lib/processor.d.ts
62
- interface ContentProcessor {
63
- canProcess(extractorType: ExtractorType, rawText: string, parserConfig: ParserConfig): boolean;
64
- process(rawText: string, parserConfig: ParserConfig): string;
65
- }
66
- interface KeyProcessor {
67
- canProcess(extractorType: ExtractorType, keyLine: string, m3u8Url: string, m3u8Content: string, parserConfig: ParserConfig): boolean;
68
- process(keyLine: string, m3u8Url: string, m3u8Content: string, parserConfig: ParserConfig): Promise<EncryptInfo>;
69
- }
70
- interface UrlProcessor {
71
- canProcess(extractorType: ExtractorType, originalUrl: string, parserConfig: ParserConfig): boolean;
72
- process(originalUrl: string, parserConfig: ParserConfig): string;
73
- }
74
- declare class DefaultUrlProcessor implements UrlProcessor {
75
- canProcess(_extractorType: ExtractorType, _originalUrl: string, parserConfig: ParserConfig): boolean;
76
- process(url: string, parserConfig: ParserConfig): string;
77
- }
78
- //#endregion
79
- //#region lib/parser-config.d.ts
80
- declare class ParserConfig {
81
- url: string;
82
- originalUrl: string;
83
- baseUrl?: string;
84
- customParserArgs: Record<string, string>;
85
- headers: Record<string, string>;
86
- contentProcessors: ContentProcessor[];
87
- urlProcessors: UrlProcessor[];
88
- keyProcessors: KeyProcessor[];
89
- customMethod?: EncryptMethod;
90
- customKey?: Uint8Array;
91
- customIv?: Uint8Array;
92
- urlProcessorArgs?: string;
93
- appendUrlParams: boolean;
94
- keyRetryCount: number;
95
- }
28
+ //#region lib/shared/extractor-type.d.ts
29
+ declare const EXTRACTOR_TYPES: {
30
+ readonly MPEG_DASH: "MPEG_DASH";
31
+ readonly HLS: "HLS";
32
+ readonly HTTP_LIVE: "HTTP_LIVE";
33
+ readonly MSS: "MSS";
34
+ };
35
+ type ExtractorType = (typeof EXTRACTOR_TYPES)[keyof typeof EXTRACTOR_TYPES];
96
36
  //#endregion
97
37
  //#region lib/shared/media-segment.d.ts
98
38
  declare class MediaSegment {
@@ -117,6 +57,15 @@ declare class MediaPart {
117
57
  constructor(segments?: MediaSegment[]);
118
58
  }
119
59
  //#endregion
60
+ //#region lib/shared/media-type.d.ts
61
+ declare const MEDIA_TYPES: {
62
+ readonly VIDEO: "video";
63
+ readonly AUDIO: "audio";
64
+ readonly SUBTITLES: "subtitle";
65
+ readonly CLOSED_CAPTIONS: "closed-captions";
66
+ };
67
+ type MediaType = (typeof MEDIA_TYPES)[keyof typeof MEDIA_TYPES];
68
+ //#endregion
120
69
  //#region lib/shared/playlist.d.ts
121
70
  declare class Playlist {
122
71
  url: string;
@@ -128,6 +77,21 @@ declare class Playlist {
128
77
  mediaParts: MediaPart[];
129
78
  }
130
79
  //#endregion
80
+ //#region lib/shared/role-type.d.ts
81
+ declare const ROLE_TYPE: {
82
+ Subtitle: number;
83
+ Main: number;
84
+ Alternate: number;
85
+ Supplementary: number;
86
+ Commentary: number;
87
+ Dub: number;
88
+ Description: number;
89
+ Sign: number;
90
+ Metadata: number;
91
+ ForcedSubtitle: number;
92
+ };
93
+ type RoleType = (typeof ROLE_TYPE)[keyof typeof ROLE_TYPE];
94
+ //#endregion
131
95
  //#region lib/shared/stream-spec.d.ts
132
96
  declare class StreamSpec {
133
97
  mediaType?: MediaType;
@@ -157,6 +121,52 @@ declare class StreamSpec {
157
121
  toShortString(): string;
158
122
  }
159
123
  //#endregion
124
+ //#region lib/extractor.d.ts
125
+ interface Extractor {
126
+ extractorType: ExtractorType;
127
+ extractStreams(rawText: string): Promise<StreamSpec[]>;
128
+ fetchPlayList(streamSpecs: StreamSpec[]): Promise<void>;
129
+ refreshPlayList(streamSpecs: StreamSpec[]): Promise<void>;
130
+ preProcessUrl(url: string): string;
131
+ preProcessContent(): void;
132
+ }
133
+ //#endregion
134
+ //#region lib/processor.d.ts
135
+ interface ContentProcessor {
136
+ canProcess(extractorType: ExtractorType, rawText: string, parserConfig: ParserConfig): boolean;
137
+ process(rawText: string, parserConfig: ParserConfig): string;
138
+ }
139
+ interface KeyProcessor {
140
+ canProcess(extractorType: ExtractorType, keyLine: string, m3u8Url: string, m3u8Content: string, parserConfig: ParserConfig): boolean;
141
+ process(keyLine: string, m3u8Url: string, m3u8Content: string, parserConfig: ParserConfig): Promise<EncryptInfo>;
142
+ }
143
+ interface UrlProcessor {
144
+ canProcess(extractorType: ExtractorType, originalUrl: string, parserConfig: ParserConfig): boolean;
145
+ process(originalUrl: string, parserConfig: ParserConfig): string;
146
+ }
147
+ declare class DefaultUrlProcessor implements UrlProcessor {
148
+ canProcess(_extractorType: ExtractorType, _originalUrl: string, parserConfig: ParserConfig): boolean;
149
+ process(url: string, parserConfig: ParserConfig): string;
150
+ }
151
+ //#endregion
152
+ //#region lib/parser-config.d.ts
153
+ declare class ParserConfig {
154
+ url: string;
155
+ originalUrl: string;
156
+ baseUrl?: string;
157
+ customParserArgs: Record<string, string>;
158
+ headers: Record<string, string>;
159
+ contentProcessors: ContentProcessor[];
160
+ urlProcessors: UrlProcessor[];
161
+ keyProcessors: KeyProcessor[];
162
+ customMethod?: EncryptMethod;
163
+ customKey?: Uint8Array;
164
+ customIv?: Uint8Array;
165
+ urlProcessorArgs?: string;
166
+ appendUrlParams: boolean;
167
+ keyRetryCount: number;
168
+ }
169
+ //#endregion
160
170
  //#region lib/stream-extractor.d.ts
161
171
  declare class StreamExtractor {
162
172
  #private;
@@ -169,4 +179,111 @@ declare class StreamExtractor {
169
179
  refreshPlayList(streamSpecs: StreamSpec[]): Promise<void>;
170
180
  }
171
181
  //#endregion
172
- export { ContentProcessor, DefaultUrlProcessor, ENCRYPT_METHODS, EXTRACTOR_TYPES, EncryptMethod, ExtractorType, KeyProcessor, MEDIA_TYPES, MediaType, ParserConfig, ROLE_TYPE, RoleType, StreamExtractor, UrlProcessor };
182
+ //#region lib/dash/dash-content-processor.d.ts
183
+ declare class DefaultDashContentProcessor implements ContentProcessor {
184
+ canProcess(extractorType: ExtractorType, mpdContent: string): boolean;
185
+ process(mpdContent: string): string;
186
+ }
187
+ //#endregion
188
+ //#region lib/dash/dash-extractor.d.ts
189
+ declare class DashExtractor implements Extractor {
190
+ #private;
191
+ get extractorType(): ExtractorType;
192
+ constructor(parserConfig: ParserConfig);
193
+ extractStreams(rawText: string): Promise<StreamSpec[]>;
194
+ refreshPlayList(streamSpecs: StreamSpec[]): Promise<void>;
195
+ fetchPlayList(streamSpecs: StreamSpec[]): Promise<void>;
196
+ preProcessUrl(url: string): string;
197
+ preProcessContent(): void;
198
+ }
199
+ //#endregion
200
+ //#region lib/dash/dash-tags.d.ts
201
+ declare const DASH_TAGS: {
202
+ TemplateRepresentationID: string;
203
+ TemplateBandwidth: string;
204
+ TemplateNumber: string;
205
+ TemplateTime: string;
206
+ };
207
+ //#endregion
208
+ //#region lib/dash/dash-utils.d.ts
209
+ /**
210
+ * Extracts StartRange and ExpectLength information from a string like "100-300"
211
+ * @param range - The range string in the format "start-end"
212
+ * @returns A tuple containing [StartRange, ExpectLength]
213
+ */
214
+ declare const parseRange: (range: string) => [number, number];
215
+ //#endregion
216
+ //#region lib/hls/hls-content-processor.d.ts
217
+ declare class DefaultHlsContentProcessor implements ContentProcessor {
218
+ private static readonly YkDVRegex;
219
+ private static readonly DNSPRegex;
220
+ private static readonly DNSPSubRegex;
221
+ private static readonly OrderFixRegex;
222
+ private static readonly ATVRegex;
223
+ private static readonly ATVRegex2;
224
+ canProcess(extractorType: ExtractorType): boolean;
225
+ process(m3u8Content: string, parserConfig: ParserConfig): string;
226
+ private applyRegexReplacement;
227
+ }
228
+ //#endregion
229
+ //#region lib/hls/hls-extractor.d.ts
230
+ declare class HlsExtractor implements Extractor {
231
+ #private;
232
+ get extractorType(): ExtractorType;
233
+ parserConfig: ParserConfig;
234
+ constructor(parserConfig: ParserConfig);
235
+ preProcessContent(): void;
236
+ preProcessUrl(url: string): string;
237
+ extractStreams(rawText: string): Promise<StreamSpec[]>;
238
+ fetchPlayList(lists: StreamSpec[]): Promise<void>;
239
+ refreshPlayList(streamSpecs: StreamSpec[]): Promise<void>;
240
+ }
241
+ //#endregion
242
+ //#region lib/hls/hls-key-processor.d.ts
243
+ declare class DefaultHlsKeyProcessor implements KeyProcessor {
244
+ canProcess(extractorType: ExtractorType): boolean;
245
+ process(keyLine: string, m3u8Url: string, _m3u8Content: string, parserConfig: ParserConfig): Promise<EncryptInfo>;
246
+ private getAttribute;
247
+ private fetchKeyWithRetry;
248
+ private preProcessUrl;
249
+ }
250
+ //#endregion
251
+ //#region lib/hls/hls-tags.d.ts
252
+ declare const HLS_TAGS: {
253
+ extM3u: string;
254
+ extXTargetDuration: string;
255
+ extXMediaSequence: string;
256
+ extXDiscontinuitySequence: string;
257
+ extXProgramDateTime: string;
258
+ extXMedia: string;
259
+ extXPlaylistType: string;
260
+ extXKey: string;
261
+ extXStreamInf: string;
262
+ extXVersion: string;
263
+ extXAllowCache: string;
264
+ extXEndlist: string;
265
+ extInf: string;
266
+ extIframesOnly: string;
267
+ extXByterange: string;
268
+ extXIframeStreamInf: string;
269
+ extXDiscontinuity: string;
270
+ extXCueOutStart: string;
271
+ extXCueOut: string;
272
+ extIsIndependentSegments: string;
273
+ extXScte35: string;
274
+ extXCueStart: string;
275
+ extXCueEnd: string;
276
+ extXCueSpan: string;
277
+ extXMap: string;
278
+ extXStart: string;
279
+ };
280
+ //#endregion
281
+ //#region lib/hls/hls-utils.d.ts
282
+ /**
283
+ * Extracts length and optional start values from a string formatted as "n[@o]".
284
+ * @param input - The input string.
285
+ * @returns A tuple containing [n (length), o (start)].
286
+ */
287
+ declare function getRange(input: string): [number, number | null];
288
+ //#endregion
289
+ export { ContentProcessor, DASH_TAGS, DashExtractor, DefaultDashContentProcessor, DefaultHlsContentProcessor, DefaultHlsKeyProcessor, DefaultUrlProcessor, ENCRYPT_METHODS, EXTRACTOR_TYPES, EncryptInfo, EncryptMethod, Extractor, ExtractorType, HLS_TAGS, HlsExtractor, KeyProcessor, MEDIA_TYPES, MediaPart, MediaSegment, MediaType, ParserConfig, ROLE_TYPE, RoleType, StreamExtractor, StreamSpec, UrlProcessor, getRange, parseRange };
@@ -1,12 +1,3 @@
1
- //#region lib/shared/media-type.d.ts
2
- declare const MEDIA_TYPES: {
3
- readonly VIDEO: "video";
4
- readonly AUDIO: "audio";
5
- readonly SUBTITLES: "subtitle";
6
- readonly CLOSED_CAPTIONS: "closed-captions";
7
- };
8
- type MediaType = (typeof MEDIA_TYPES)[keyof typeof MEDIA_TYPES];
9
- //#endregion
10
1
  //#region lib/shared/encrypt-method.d.ts
11
2
  declare const ENCRYPT_METHODS: {
12
3
  readonly NONE: "none";
@@ -20,30 +11,6 @@ declare const ENCRYPT_METHODS: {
20
11
  };
21
12
  type EncryptMethod = (typeof ENCRYPT_METHODS)[keyof typeof ENCRYPT_METHODS];
22
13
  //#endregion
23
- //#region lib/shared/extractor-type.d.ts
24
- declare const EXTRACTOR_TYPES: {
25
- readonly MPEG_DASH: "MPEG_DASH";
26
- readonly HLS: "HLS";
27
- readonly HTTP_LIVE: "HTTP_LIVE";
28
- readonly MSS: "MSS";
29
- };
30
- type ExtractorType = (typeof EXTRACTOR_TYPES)[keyof typeof EXTRACTOR_TYPES];
31
- //#endregion
32
- //#region lib/shared/role-type.d.ts
33
- declare const ROLE_TYPE: {
34
- Subtitle: number;
35
- Main: number;
36
- Alternate: number;
37
- Supplementary: number;
38
- Commentary: number;
39
- Dub: number;
40
- Description: number;
41
- Sign: number;
42
- Metadata: number;
43
- ForcedSubtitle: number;
44
- };
45
- type RoleType = (typeof ROLE_TYPE)[keyof typeof ROLE_TYPE];
46
- //#endregion
47
14
  //#region lib/shared/encrypt-info.d.ts
48
15
  type DrmType = 'widevine' | 'playready' | 'fairplay';
49
16
  declare class EncryptInfo {
@@ -58,41 +25,14 @@ declare class EncryptInfo {
58
25
  parseMethod(method?: string | null): EncryptMethod;
59
26
  }
60
27
  //#endregion
61
- //#region lib/processor.d.ts
62
- interface ContentProcessor {
63
- canProcess(extractorType: ExtractorType, rawText: string, parserConfig: ParserConfig): boolean;
64
- process(rawText: string, parserConfig: ParserConfig): string;
65
- }
66
- interface KeyProcessor {
67
- canProcess(extractorType: ExtractorType, keyLine: string, m3u8Url: string, m3u8Content: string, parserConfig: ParserConfig): boolean;
68
- process(keyLine: string, m3u8Url: string, m3u8Content: string, parserConfig: ParserConfig): Promise<EncryptInfo>;
69
- }
70
- interface UrlProcessor {
71
- canProcess(extractorType: ExtractorType, originalUrl: string, parserConfig: ParserConfig): boolean;
72
- process(originalUrl: string, parserConfig: ParserConfig): string;
73
- }
74
- declare class DefaultUrlProcessor implements UrlProcessor {
75
- canProcess(_extractorType: ExtractorType, _originalUrl: string, parserConfig: ParserConfig): boolean;
76
- process(url: string, parserConfig: ParserConfig): string;
77
- }
78
- //#endregion
79
- //#region lib/parser-config.d.ts
80
- declare class ParserConfig {
81
- url: string;
82
- originalUrl: string;
83
- baseUrl?: string;
84
- customParserArgs: Record<string, string>;
85
- headers: Record<string, string>;
86
- contentProcessors: ContentProcessor[];
87
- urlProcessors: UrlProcessor[];
88
- keyProcessors: KeyProcessor[];
89
- customMethod?: EncryptMethod;
90
- customKey?: Uint8Array;
91
- customIv?: Uint8Array;
92
- urlProcessorArgs?: string;
93
- appendUrlParams: boolean;
94
- keyRetryCount: number;
95
- }
28
+ //#region lib/shared/extractor-type.d.ts
29
+ declare const EXTRACTOR_TYPES: {
30
+ readonly MPEG_DASH: "MPEG_DASH";
31
+ readonly HLS: "HLS";
32
+ readonly HTTP_LIVE: "HTTP_LIVE";
33
+ readonly MSS: "MSS";
34
+ };
35
+ type ExtractorType = (typeof EXTRACTOR_TYPES)[keyof typeof EXTRACTOR_TYPES];
96
36
  //#endregion
97
37
  //#region lib/shared/media-segment.d.ts
98
38
  declare class MediaSegment {
@@ -117,6 +57,15 @@ declare class MediaPart {
117
57
  constructor(segments?: MediaSegment[]);
118
58
  }
119
59
  //#endregion
60
+ //#region lib/shared/media-type.d.ts
61
+ declare const MEDIA_TYPES: {
62
+ readonly VIDEO: "video";
63
+ readonly AUDIO: "audio";
64
+ readonly SUBTITLES: "subtitle";
65
+ readonly CLOSED_CAPTIONS: "closed-captions";
66
+ };
67
+ type MediaType = (typeof MEDIA_TYPES)[keyof typeof MEDIA_TYPES];
68
+ //#endregion
120
69
  //#region lib/shared/playlist.d.ts
121
70
  declare class Playlist {
122
71
  url: string;
@@ -128,6 +77,21 @@ declare class Playlist {
128
77
  mediaParts: MediaPart[];
129
78
  }
130
79
  //#endregion
80
+ //#region lib/shared/role-type.d.ts
81
+ declare const ROLE_TYPE: {
82
+ Subtitle: number;
83
+ Main: number;
84
+ Alternate: number;
85
+ Supplementary: number;
86
+ Commentary: number;
87
+ Dub: number;
88
+ Description: number;
89
+ Sign: number;
90
+ Metadata: number;
91
+ ForcedSubtitle: number;
92
+ };
93
+ type RoleType = (typeof ROLE_TYPE)[keyof typeof ROLE_TYPE];
94
+ //#endregion
131
95
  //#region lib/shared/stream-spec.d.ts
132
96
  declare class StreamSpec {
133
97
  mediaType?: MediaType;
@@ -157,6 +121,52 @@ declare class StreamSpec {
157
121
  toShortString(): string;
158
122
  }
159
123
  //#endregion
124
+ //#region lib/extractor.d.ts
125
+ interface Extractor {
126
+ extractorType: ExtractorType;
127
+ extractStreams(rawText: string): Promise<StreamSpec[]>;
128
+ fetchPlayList(streamSpecs: StreamSpec[]): Promise<void>;
129
+ refreshPlayList(streamSpecs: StreamSpec[]): Promise<void>;
130
+ preProcessUrl(url: string): string;
131
+ preProcessContent(): void;
132
+ }
133
+ //#endregion
134
+ //#region lib/processor.d.ts
135
+ interface ContentProcessor {
136
+ canProcess(extractorType: ExtractorType, rawText: string, parserConfig: ParserConfig): boolean;
137
+ process(rawText: string, parserConfig: ParserConfig): string;
138
+ }
139
+ interface KeyProcessor {
140
+ canProcess(extractorType: ExtractorType, keyLine: string, m3u8Url: string, m3u8Content: string, parserConfig: ParserConfig): boolean;
141
+ process(keyLine: string, m3u8Url: string, m3u8Content: string, parserConfig: ParserConfig): Promise<EncryptInfo>;
142
+ }
143
+ interface UrlProcessor {
144
+ canProcess(extractorType: ExtractorType, originalUrl: string, parserConfig: ParserConfig): boolean;
145
+ process(originalUrl: string, parserConfig: ParserConfig): string;
146
+ }
147
+ declare class DefaultUrlProcessor implements UrlProcessor {
148
+ canProcess(_extractorType: ExtractorType, _originalUrl: string, parserConfig: ParserConfig): boolean;
149
+ process(url: string, parserConfig: ParserConfig): string;
150
+ }
151
+ //#endregion
152
+ //#region lib/parser-config.d.ts
153
+ declare class ParserConfig {
154
+ url: string;
155
+ originalUrl: string;
156
+ baseUrl?: string;
157
+ customParserArgs: Record<string, string>;
158
+ headers: Record<string, string>;
159
+ contentProcessors: ContentProcessor[];
160
+ urlProcessors: UrlProcessor[];
161
+ keyProcessors: KeyProcessor[];
162
+ customMethod?: EncryptMethod;
163
+ customKey?: Uint8Array;
164
+ customIv?: Uint8Array;
165
+ urlProcessorArgs?: string;
166
+ appendUrlParams: boolean;
167
+ keyRetryCount: number;
168
+ }
169
+ //#endregion
160
170
  //#region lib/stream-extractor.d.ts
161
171
  declare class StreamExtractor {
162
172
  #private;
@@ -169,4 +179,111 @@ declare class StreamExtractor {
169
179
  refreshPlayList(streamSpecs: StreamSpec[]): Promise<void>;
170
180
  }
171
181
  //#endregion
172
- export { ContentProcessor, DefaultUrlProcessor, ENCRYPT_METHODS, EXTRACTOR_TYPES, EncryptMethod, ExtractorType, KeyProcessor, MEDIA_TYPES, MediaType, ParserConfig, ROLE_TYPE, RoleType, StreamExtractor, UrlProcessor };
182
+ //#region lib/dash/dash-content-processor.d.ts
183
+ declare class DefaultDashContentProcessor implements ContentProcessor {
184
+ canProcess(extractorType: ExtractorType, mpdContent: string): boolean;
185
+ process(mpdContent: string): string;
186
+ }
187
+ //#endregion
188
+ //#region lib/dash/dash-extractor.d.ts
189
+ declare class DashExtractor implements Extractor {
190
+ #private;
191
+ get extractorType(): ExtractorType;
192
+ constructor(parserConfig: ParserConfig);
193
+ extractStreams(rawText: string): Promise<StreamSpec[]>;
194
+ refreshPlayList(streamSpecs: StreamSpec[]): Promise<void>;
195
+ fetchPlayList(streamSpecs: StreamSpec[]): Promise<void>;
196
+ preProcessUrl(url: string): string;
197
+ preProcessContent(): void;
198
+ }
199
+ //#endregion
200
+ //#region lib/dash/dash-tags.d.ts
201
+ declare const DASH_TAGS: {
202
+ TemplateRepresentationID: string;
203
+ TemplateBandwidth: string;
204
+ TemplateNumber: string;
205
+ TemplateTime: string;
206
+ };
207
+ //#endregion
208
+ //#region lib/dash/dash-utils.d.ts
209
+ /**
210
+ * Extracts StartRange and ExpectLength information from a string like "100-300"
211
+ * @param range - The range string in the format "start-end"
212
+ * @returns A tuple containing [StartRange, ExpectLength]
213
+ */
214
+ declare const parseRange: (range: string) => [number, number];
215
+ //#endregion
216
+ //#region lib/hls/hls-content-processor.d.ts
217
+ declare class DefaultHlsContentProcessor implements ContentProcessor {
218
+ private static readonly YkDVRegex;
219
+ private static readonly DNSPRegex;
220
+ private static readonly DNSPSubRegex;
221
+ private static readonly OrderFixRegex;
222
+ private static readonly ATVRegex;
223
+ private static readonly ATVRegex2;
224
+ canProcess(extractorType: ExtractorType): boolean;
225
+ process(m3u8Content: string, parserConfig: ParserConfig): string;
226
+ private applyRegexReplacement;
227
+ }
228
+ //#endregion
229
+ //#region lib/hls/hls-extractor.d.ts
230
+ declare class HlsExtractor implements Extractor {
231
+ #private;
232
+ get extractorType(): ExtractorType;
233
+ parserConfig: ParserConfig;
234
+ constructor(parserConfig: ParserConfig);
235
+ preProcessContent(): void;
236
+ preProcessUrl(url: string): string;
237
+ extractStreams(rawText: string): Promise<StreamSpec[]>;
238
+ fetchPlayList(lists: StreamSpec[]): Promise<void>;
239
+ refreshPlayList(streamSpecs: StreamSpec[]): Promise<void>;
240
+ }
241
+ //#endregion
242
+ //#region lib/hls/hls-key-processor.d.ts
243
+ declare class DefaultHlsKeyProcessor implements KeyProcessor {
244
+ canProcess(extractorType: ExtractorType): boolean;
245
+ process(keyLine: string, m3u8Url: string, _m3u8Content: string, parserConfig: ParserConfig): Promise<EncryptInfo>;
246
+ private getAttribute;
247
+ private fetchKeyWithRetry;
248
+ private preProcessUrl;
249
+ }
250
+ //#endregion
251
+ //#region lib/hls/hls-tags.d.ts
252
+ declare const HLS_TAGS: {
253
+ extM3u: string;
254
+ extXTargetDuration: string;
255
+ extXMediaSequence: string;
256
+ extXDiscontinuitySequence: string;
257
+ extXProgramDateTime: string;
258
+ extXMedia: string;
259
+ extXPlaylistType: string;
260
+ extXKey: string;
261
+ extXStreamInf: string;
262
+ extXVersion: string;
263
+ extXAllowCache: string;
264
+ extXEndlist: string;
265
+ extInf: string;
266
+ extIframesOnly: string;
267
+ extXByterange: string;
268
+ extXIframeStreamInf: string;
269
+ extXDiscontinuity: string;
270
+ extXCueOutStart: string;
271
+ extXCueOut: string;
272
+ extIsIndependentSegments: string;
273
+ extXScte35: string;
274
+ extXCueStart: string;
275
+ extXCueEnd: string;
276
+ extXCueSpan: string;
277
+ extXMap: string;
278
+ extXStart: string;
279
+ };
280
+ //#endregion
281
+ //#region lib/hls/hls-utils.d.ts
282
+ /**
283
+ * Extracts length and optional start values from a string formatted as "n[@o]".
284
+ * @param input - The input string.
285
+ * @returns A tuple containing [n (length), o (start)].
286
+ */
287
+ declare function getRange(input: string): [number, number | null];
288
+ //#endregion
289
+ export { ContentProcessor, DASH_TAGS, DashExtractor, DefaultDashContentProcessor, DefaultHlsContentProcessor, DefaultHlsKeyProcessor, DefaultUrlProcessor, ENCRYPT_METHODS, EXTRACTOR_TYPES, EncryptInfo, EncryptMethod, Extractor, ExtractorType, HLS_TAGS, HlsExtractor, KeyProcessor, MEDIA_TYPES, MediaPart, MediaSegment, MediaType, ParserConfig, ROLE_TYPE, RoleType, StreamExtractor, StreamSpec, UrlProcessor, getRange, parseRange };
@@ -1,3 +1,4 @@
1
+ import crypto from "node:crypto";
1
2
  import { existsSync, readFileSync } from "node:fs";
2
3
  import { b } from "barsic";
3
4
  import { readFile } from "node:fs/promises";
@@ -5,17 +6,7 @@ import { pathToFileURL } from "node:url";
5
6
  import path from "node:path";
6
7
  import { Temporal } from "temporal-polyfill";
7
8
  import { DOMParser } from "@xmldom/xmldom";
8
- import crypto from "node:crypto";
9
-
10
- //#region lib/shared/media-type.ts
11
- const MEDIA_TYPES = {
12
- VIDEO: "video",
13
- AUDIO: "audio",
14
- SUBTITLES: "subtitle",
15
- CLOSED_CAPTIONS: "closed-captions"
16
- };
17
9
 
18
- //#endregion
19
10
  //#region lib/shared/encrypt-method.ts
20
11
  const ENCRYPT_METHODS = {
21
12
  NONE: "none",
@@ -28,6 +19,23 @@ const ENCRYPT_METHODS = {
28
19
  UNKNOWN: "unknown"
29
20
  };
30
21
 
22
+ //#endregion
23
+ //#region lib/shared/encrypt-info.ts
24
+ var EncryptInfo = class {
25
+ method = ENCRYPT_METHODS.NONE;
26
+ key;
27
+ iv;
28
+ drm;
29
+ constructor(method) {
30
+ this.method = this.parseMethod(method);
31
+ this.drm = {};
32
+ }
33
+ parseMethod(method) {
34
+ if (method) return ENCRYPT_METHODS[method.replace("-", "_")];
35
+ else return ENCRYPT_METHODS.UNKNOWN;
36
+ }
37
+ };
38
+
31
39
  //#endregion
32
40
  //#region lib/shared/extractor-type.ts
33
41
  const EXTRACTOR_TYPES = {
@@ -37,6 +45,132 @@ const EXTRACTOR_TYPES = {
37
45
  MSS: "MSS"
38
46
  };
39
47
 
48
+ //#endregion
49
+ //#region lib/shared/media-part.ts
50
+ var MediaPart = class {
51
+ mediaSegments = [];
52
+ constructor(segments) {
53
+ this.mediaSegments = segments || [];
54
+ }
55
+ };
56
+
57
+ //#endregion
58
+ //#region lib/shared/media-segment.ts
59
+ var MediaSegment = class MediaSegment {
60
+ index = NaN;
61
+ duration = NaN;
62
+ title;
63
+ dateTime;
64
+ startRange;
65
+ get stopRange() {
66
+ return this.startRange !== void 0 && this.expectLength !== void 0 ? this.startRange + this.expectLength - 1 : void 0;
67
+ }
68
+ expectLength;
69
+ encryptInfo = new EncryptInfo();
70
+ get isEncrypted() {
71
+ return this.encryptInfo.method !== ENCRYPT_METHODS.NONE;
72
+ }
73
+ url = "";
74
+ nameFromVar;
75
+ equals(segment) {
76
+ if (segment instanceof MediaSegment) return this.index == segment.index && Math.abs(this.duration - segment.duration) < .001 && this.title == segment.title && this.startRange == segment.startRange && this.stopRange == segment.stopRange && this.expectLength == segment.expectLength && this.url == segment.url;
77
+ else return false;
78
+ }
79
+ getHashCode() {
80
+ const payload = [
81
+ this.index,
82
+ this.duration,
83
+ this.title,
84
+ this.startRange,
85
+ this.stopRange,
86
+ this.expectLength,
87
+ this.url
88
+ ].join("-");
89
+ return crypto.createHash("md5").update(payload).digest("hex");
90
+ }
91
+ };
92
+
93
+ //#endregion
94
+ //#region lib/shared/media-type.ts
95
+ const MEDIA_TYPES = {
96
+ VIDEO: "video",
97
+ AUDIO: "audio",
98
+ SUBTITLES: "subtitle",
99
+ CLOSED_CAPTIONS: "closed-captions"
100
+ };
101
+
102
+ //#endregion
103
+ //#region lib/shared/stream-spec.ts
104
+ var StreamSpec = class {
105
+ mediaType;
106
+ groupId = null;
107
+ language;
108
+ name;
109
+ default;
110
+ skippedDuration;
111
+ bandwidth;
112
+ codecs = null;
113
+ resolution;
114
+ frameRate;
115
+ channels = null;
116
+ extension = null;
117
+ role;
118
+ videoRange;
119
+ characteristics;
120
+ publishTime;
121
+ audioId;
122
+ videoId;
123
+ subtitleId;
124
+ periodId = null;
125
+ url = "";
126
+ originalUrl = "";
127
+ playlist;
128
+ get segmentsCount() {
129
+ return this.playlist?.mediaParts.reduce((sum, part) => sum + part.mediaSegments.length, 0) ?? 0;
130
+ }
131
+ toShortString() {
132
+ let prefixStr = "";
133
+ let returnStr = "";
134
+ const encStr = "";
135
+ const bandwidth = this.bandwidth ? `${this.bandwidth / 1e3} Kbps` : "";
136
+ const channels = this.channels ? `${this.channels}CH` : "";
137
+ if (this.mediaType === MEDIA_TYPES.AUDIO) {
138
+ prefixStr = `Aud ${encStr}`;
139
+ returnStr = [
140
+ this.groupId,
141
+ bandwidth,
142
+ this.name,
143
+ this.codecs,
144
+ this.language,
145
+ channels,
146
+ this.role
147
+ ].filter(Boolean).join(" | ");
148
+ } else if (this.mediaType === MEDIA_TYPES.SUBTITLES) {
149
+ prefixStr = `Sub ${encStr}`;
150
+ returnStr = [
151
+ this.groupId,
152
+ this.language,
153
+ this.name,
154
+ this.codecs,
155
+ this.role
156
+ ].filter(Boolean).join(" | ");
157
+ } else {
158
+ prefixStr = `Vid ${encStr}`;
159
+ returnStr = [
160
+ this.resolution,
161
+ bandwidth,
162
+ this.groupId,
163
+ this.frameRate,
164
+ this.codecs,
165
+ this.videoRange,
166
+ this.role
167
+ ].filter(Boolean).join(" | ");
168
+ }
169
+ returnStr = `${prefixStr} | ${returnStr}`;
170
+ return returnStr.trim();
171
+ }
172
+ };
173
+
40
174
  //#endregion
41
175
  //#region lib/shared/role-type.ts
42
176
  const ROLE_TYPE = {
@@ -153,23 +287,6 @@ var DefaultHlsContentProcessor = class DefaultHlsContentProcessor {
153
287
  }
154
288
  };
155
289
 
156
- //#endregion
157
- //#region lib/shared/encrypt-info.ts
158
- var EncryptInfo = class {
159
- method = ENCRYPT_METHODS.NONE;
160
- key;
161
- iv;
162
- drm;
163
- constructor(method) {
164
- this.method = this.parseMethod(method);
165
- this.drm = {};
166
- }
167
- parseMethod(method) {
168
- if (method) return ENCRYPT_METHODS[method.replace("-", "_")];
169
- else return ENCRYPT_METHODS.UNKNOWN;
170
- }
171
- };
172
-
173
290
  //#endregion
174
291
  //#region lib/hls/hls-key-processor.ts
175
292
  var DefaultHlsKeyProcessor = class {
@@ -250,78 +367,6 @@ var ParserConfig = class {
250
367
  keyRetryCount = 3;
251
368
  };
252
369
 
253
- //#endregion
254
- //#region lib/shared/stream-spec.ts
255
- var StreamSpec = class {
256
- mediaType;
257
- groupId = null;
258
- language;
259
- name;
260
- default;
261
- skippedDuration;
262
- bandwidth;
263
- codecs = null;
264
- resolution;
265
- frameRate;
266
- channels = null;
267
- extension = null;
268
- role;
269
- videoRange;
270
- characteristics;
271
- publishTime;
272
- audioId;
273
- videoId;
274
- subtitleId;
275
- periodId = null;
276
- url = "";
277
- originalUrl = "";
278
- playlist;
279
- get segmentsCount() {
280
- return this.playlist?.mediaParts.reduce((sum, part) => sum + part.mediaSegments.length, 0) ?? 0;
281
- }
282
- toShortString() {
283
- let prefixStr = "";
284
- let returnStr = "";
285
- const encStr = "";
286
- const bandwidth = this.bandwidth ? `${this.bandwidth / 1e3} Kbps` : "";
287
- const channels = this.channels ? `${this.channels}CH` : "";
288
- if (this.mediaType === MEDIA_TYPES.AUDIO) {
289
- prefixStr = `Aud ${encStr}`;
290
- returnStr = [
291
- this.groupId,
292
- bandwidth,
293
- this.name,
294
- this.codecs,
295
- this.language,
296
- channels,
297
- this.role
298
- ].filter(Boolean).join(" | ");
299
- } else if (this.mediaType === MEDIA_TYPES.SUBTITLES) {
300
- prefixStr = `Sub ${encStr}`;
301
- returnStr = [
302
- this.groupId,
303
- this.language,
304
- this.name,
305
- this.codecs,
306
- this.role
307
- ].filter(Boolean).join(" | ");
308
- } else {
309
- prefixStr = `Vid ${encStr}`;
310
- returnStr = [
311
- this.resolution,
312
- bandwidth,
313
- this.groupId,
314
- this.frameRate,
315
- this.codecs,
316
- this.videoRange,
317
- this.role
318
- ].filter(Boolean).join(" | ");
319
- }
320
- returnStr = `${prefixStr} | ${returnStr}`;
321
- return returnStr.trim();
322
- }
323
- };
324
-
325
370
  //#endregion
326
371
  //#region lib/dash/dash-tags.ts
327
372
  const DASH_TAGS = {
@@ -400,51 +445,6 @@ var Playlist = class {
400
445
  mediaParts = [];
401
446
  };
402
447
 
403
- //#endregion
404
- //#region lib/shared/media-part.ts
405
- var MediaPart = class {
406
- mediaSegments = [];
407
- constructor(segments) {
408
- this.mediaSegments = segments || [];
409
- }
410
- };
411
-
412
- //#endregion
413
- //#region lib/shared/media-segment.ts
414
- var MediaSegment = class MediaSegment {
415
- index = NaN;
416
- duration = NaN;
417
- title;
418
- dateTime;
419
- startRange;
420
- get stopRange() {
421
- return this.startRange !== void 0 && this.expectLength !== void 0 ? this.startRange + this.expectLength - 1 : void 0;
422
- }
423
- expectLength;
424
- encryptInfo = new EncryptInfo();
425
- get isEncrypted() {
426
- return this.encryptInfo.method !== ENCRYPT_METHODS.NONE;
427
- }
428
- url = "";
429
- nameFromVar;
430
- equals(segment) {
431
- if (segment instanceof MediaSegment) return this.index == segment.index && Math.abs(this.duration - segment.duration) < .001 && this.title == segment.title && this.startRange == segment.startRange && this.stopRange == segment.stopRange && this.expectLength == segment.expectLength && this.url == segment.url;
432
- else return false;
433
- }
434
- getHashCode() {
435
- const payload = [
436
- this.index,
437
- this.duration,
438
- this.title,
439
- this.startRange,
440
- this.stopRange,
441
- this.expectLength,
442
- this.url
443
- ].join("-");
444
- return crypto.createHash("md5").update(payload).digest("hex");
445
- }
446
- };
447
-
448
448
  //#endregion
449
449
  //#region lib/dash/dash-utils.ts
450
450
  /**
@@ -1168,4 +1168,4 @@ var StreamExtractor = class {
1168
1168
  };
1169
1169
 
1170
1170
  //#endregion
1171
- export { DefaultUrlProcessor, ENCRYPT_METHODS, EXTRACTOR_TYPES, MEDIA_TYPES, ParserConfig, ROLE_TYPE, StreamExtractor };
1171
+ export { DASH_TAGS, DashExtractor, DefaultDashContentProcessor, DefaultHlsContentProcessor, DefaultHlsKeyProcessor, DefaultUrlProcessor, ENCRYPT_METHODS, EXTRACTOR_TYPES, EncryptInfo, HLS_TAGS, HlsExtractor, MEDIA_TYPES, MediaPart, MediaSegment, ParserConfig, ROLE_TYPE, StreamExtractor, StreamSpec, getRange, parseRange };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dasha",
3
- "version": "4.0.0-alpha.3",
3
+ "version": "4.0.0-alpha.4",
4
4
  "description": "Streaming manifest parser",
5
5
  "files": [
6
6
  "dist"
@@ -73,9 +73,9 @@
73
73
  "eslint-plugin-prettier": "^5.5.4",
74
74
  "globals": "^16.5.0",
75
75
  "prettier": "^3.6.2",
76
- "tsdown": "^0.15.12",
76
+ "tsdown": "^0.16.1",
77
77
  "typescript": "^5.9.3",
78
78
  "typescript-eslint": "^8.46.3",
79
- "vitest": "^4.0.6"
79
+ "vitest": "^4.0.8"
80
80
  }
81
81
  }