dasha 4.0.0-alpha.8 → 4.0.0-alpha.9
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 +59 -35
- package/dist/dasha.mjs +59 -35
- package/package.json +1 -1
package/dist/dasha.cjs
CHANGED
|
@@ -217,6 +217,20 @@ const ALL_STREAM_TYPES = [
|
|
|
217
217
|
"audio",
|
|
218
218
|
"subtitle"
|
|
219
219
|
];
|
|
220
|
+
const bitrateToString = (bitrate) => {
|
|
221
|
+
return bitrate ? `${Math.round(bitrate / 1e3)} Kbps` : "";
|
|
222
|
+
};
|
|
223
|
+
const roleToString = (role) => {
|
|
224
|
+
for (const [key, value] of Object.entries(ROLE_TYPE)) if (value === role) return key;
|
|
225
|
+
return "";
|
|
226
|
+
};
|
|
227
|
+
const durationToString = (seconds) => {
|
|
228
|
+
if (!Number.isFinite(seconds) || seconds < 0) return "";
|
|
229
|
+
const mins = Math.floor(seconds / 60);
|
|
230
|
+
const secs = Math.round(seconds % 60);
|
|
231
|
+
if (mins > 0) return `~${mins}m${secs.toString().padStart(2, "0")}s`;
|
|
232
|
+
return `~${secs}s`;
|
|
233
|
+
};
|
|
220
234
|
var StreamInfo = class {
|
|
221
235
|
codec;
|
|
222
236
|
languageCode;
|
|
@@ -272,17 +286,17 @@ var VideoStreamInfo = class extends StreamInfo {
|
|
|
272
286
|
this.codec = info?.codec;
|
|
273
287
|
}
|
|
274
288
|
toShortString() {
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
289
|
+
const parts = ["Vid"];
|
|
290
|
+
if (this.width) parts.push(`${this.width}x${this.height}`);
|
|
291
|
+
if (this.bitrate) parts.push(bitrateToString(this.bitrate));
|
|
292
|
+
if (this.groupId) parts.push(this.groupId);
|
|
293
|
+
if (this.frameRate) parts.push(this.frameRate.toString());
|
|
294
|
+
if (this.codec) parts.push(this.codec);
|
|
295
|
+
if (this.videoRange) parts.push(this.videoRange);
|
|
296
|
+
if (this.segmentsCount) parts.push(`${this.segmentsCount} segments`);
|
|
297
|
+
if (this.role) parts.push(roleToString(this.role));
|
|
298
|
+
if (this.playlist) parts.push(durationToString(this.playlist.totalDuration));
|
|
299
|
+
return parts.filter(Boolean).join(" | ").trim();
|
|
286
300
|
}
|
|
287
301
|
};
|
|
288
302
|
var AudioStreamInfo = class extends StreamInfo {
|
|
@@ -300,18 +314,15 @@ var AudioStreamInfo = class extends StreamInfo {
|
|
|
300
314
|
this.codec = info?.codec;
|
|
301
315
|
}
|
|
302
316
|
toShortString() {
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
channels,
|
|
313
|
-
this.role
|
|
314
|
-
].filter(Boolean).join(" | ")}`.trim();
|
|
317
|
+
const parts = ["Aud"];
|
|
318
|
+
if (this.groupId) parts.push(this.groupId);
|
|
319
|
+
if (this.bitrate) parts.push(bitrateToString(this.bitrate));
|
|
320
|
+
if (this.name) parts.push(this.name);
|
|
321
|
+
if (this.codec) parts.push(this.codec);
|
|
322
|
+
if (this.languageCode) parts.push(this.languageCode);
|
|
323
|
+
if (this.numberOfChannels) parts.push(`${this.numberOfChannels}CH`);
|
|
324
|
+
if (this.role) parts.push(roleToString(this.role));
|
|
325
|
+
return parts.filter(Boolean).join(" | ").trim();
|
|
315
326
|
}
|
|
316
327
|
};
|
|
317
328
|
var SubtitleStreamInfo = class extends StreamInfo {
|
|
@@ -327,13 +338,14 @@ var SubtitleStreamInfo = class extends StreamInfo {
|
|
|
327
338
|
this.codec = info?.codec;
|
|
328
339
|
}
|
|
329
340
|
toShortString() {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
341
|
+
const parts = ["Sub"];
|
|
342
|
+
const text = parts.filter(Boolean).join(" | ");
|
|
343
|
+
if (this.groupId) parts.push(this.groupId);
|
|
344
|
+
if (this.languageCode) parts.push(this.languageCode);
|
|
345
|
+
if (this.name) parts.push(this.name);
|
|
346
|
+
if (this.codec) parts.push(this.codec);
|
|
347
|
+
if (this.role) parts.push(roleToString(this.role));
|
|
348
|
+
return text.trim();
|
|
337
349
|
}
|
|
338
350
|
};
|
|
339
351
|
|
|
@@ -360,15 +372,26 @@ var DefaultUrlProcessor = class {
|
|
|
360
372
|
|
|
361
373
|
//#endregion
|
|
362
374
|
//#region lib/dash/dash-content-processor.ts
|
|
375
|
+
const namespaceMap = new Map([
|
|
376
|
+
["cenc", "urn:mpeg:cenc:2013"],
|
|
377
|
+
["mspr", "urn:microsoft:playready"],
|
|
378
|
+
["mas", "urn:marlin:mas:1-0:services:schemas:mpd"]
|
|
379
|
+
]);
|
|
380
|
+
const isMissingNs = (rawText, tag) => !rawText.includes(`xmlns:${tag}`) && rawText.includes(`<${tag}:`);
|
|
381
|
+
function replaceFirst(source, oldValue, newValue) {
|
|
382
|
+
const index = source.indexOf(oldValue);
|
|
383
|
+
return index < 0 ? source : source.slice(0, index) + newValue + source.slice(index + oldValue.length);
|
|
384
|
+
}
|
|
363
385
|
var DefaultDashContentProcessor = class {
|
|
364
386
|
canProcess(extractorType, mpdContent) {
|
|
365
387
|
if (extractorType !== EXTRACTOR_TYPES.MPEG_DASH) return false;
|
|
366
|
-
return
|
|
388
|
+
return namespaceMap.keys().some((key) => isMissingNs(mpdContent, key));
|
|
367
389
|
}
|
|
368
390
|
process(mpdContent) {
|
|
369
|
-
console.debug("
|
|
370
|
-
|
|
371
|
-
return mpdContent;
|
|
391
|
+
console.debug("Namespace missing, trying to fix...");
|
|
392
|
+
const missingNamespaceKeys = Array.from(namespaceMap.keys().filter((key) => isMissingNs(mpdContent, key)));
|
|
393
|
+
if (!missingNamespaceKeys.length) return mpdContent;
|
|
394
|
+
return replaceFirst(mpdContent, "<MPD ", `<MPD ${missingNamespaceKeys.map((key) => `xmlns:${key}="${namespaceMap.get(key)}"`).join(" ")} `);
|
|
372
395
|
}
|
|
373
396
|
};
|
|
374
397
|
|
|
@@ -930,6 +953,7 @@ var DashExtractor = class DashExtractor {
|
|
|
930
953
|
streamInfo.channels = channelsString;
|
|
931
954
|
}
|
|
932
955
|
} else if (streamInfo.type === "subtitle") {
|
|
956
|
+
streamInfo.bitrate = bitrate;
|
|
933
957
|
if (roles) streamInfo.cc = checkIsClosedCaption(roles);
|
|
934
958
|
if (accessibilities) streamInfo.sdh = checkIsSdh(accessibilities);
|
|
935
959
|
}
|
|
@@ -1465,7 +1489,7 @@ var HlsExtractor = class {
|
|
|
1465
1489
|
url = response.url;
|
|
1466
1490
|
this.#m3u8Content = await response.text();
|
|
1467
1491
|
} catch (e) {
|
|
1468
|
-
if (url !== this.parserConfig.originalUrl) {
|
|
1492
|
+
if (this.parserConfig.originalUrl.startsWith("http") && url !== this.parserConfig.originalUrl) {
|
|
1469
1493
|
const response = await fetch(this.parserConfig.originalUrl, { headers: this.parserConfig.headers });
|
|
1470
1494
|
url = response.url;
|
|
1471
1495
|
this.#m3u8Content = await response.text();
|
package/dist/dasha.mjs
CHANGED
|
@@ -192,6 +192,20 @@ const ALL_STREAM_TYPES = [
|
|
|
192
192
|
"audio",
|
|
193
193
|
"subtitle"
|
|
194
194
|
];
|
|
195
|
+
const bitrateToString = (bitrate) => {
|
|
196
|
+
return bitrate ? `${Math.round(bitrate / 1e3)} Kbps` : "";
|
|
197
|
+
};
|
|
198
|
+
const roleToString = (role) => {
|
|
199
|
+
for (const [key, value] of Object.entries(ROLE_TYPE)) if (value === role) return key;
|
|
200
|
+
return "";
|
|
201
|
+
};
|
|
202
|
+
const durationToString = (seconds) => {
|
|
203
|
+
if (!Number.isFinite(seconds) || seconds < 0) return "";
|
|
204
|
+
const mins = Math.floor(seconds / 60);
|
|
205
|
+
const secs = Math.round(seconds % 60);
|
|
206
|
+
if (mins > 0) return `~${mins}m${secs.toString().padStart(2, "0")}s`;
|
|
207
|
+
return `~${secs}s`;
|
|
208
|
+
};
|
|
195
209
|
var StreamInfo = class {
|
|
196
210
|
codec;
|
|
197
211
|
languageCode;
|
|
@@ -247,17 +261,17 @@ var VideoStreamInfo = class extends StreamInfo {
|
|
|
247
261
|
this.codec = info?.codec;
|
|
248
262
|
}
|
|
249
263
|
toShortString() {
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
264
|
+
const parts = ["Vid"];
|
|
265
|
+
if (this.width) parts.push(`${this.width}x${this.height}`);
|
|
266
|
+
if (this.bitrate) parts.push(bitrateToString(this.bitrate));
|
|
267
|
+
if (this.groupId) parts.push(this.groupId);
|
|
268
|
+
if (this.frameRate) parts.push(this.frameRate.toString());
|
|
269
|
+
if (this.codec) parts.push(this.codec);
|
|
270
|
+
if (this.videoRange) parts.push(this.videoRange);
|
|
271
|
+
if (this.segmentsCount) parts.push(`${this.segmentsCount} segments`);
|
|
272
|
+
if (this.role) parts.push(roleToString(this.role));
|
|
273
|
+
if (this.playlist) parts.push(durationToString(this.playlist.totalDuration));
|
|
274
|
+
return parts.filter(Boolean).join(" | ").trim();
|
|
261
275
|
}
|
|
262
276
|
};
|
|
263
277
|
var AudioStreamInfo = class extends StreamInfo {
|
|
@@ -275,18 +289,15 @@ var AudioStreamInfo = class extends StreamInfo {
|
|
|
275
289
|
this.codec = info?.codec;
|
|
276
290
|
}
|
|
277
291
|
toShortString() {
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
channels,
|
|
288
|
-
this.role
|
|
289
|
-
].filter(Boolean).join(" | ")}`.trim();
|
|
292
|
+
const parts = ["Aud"];
|
|
293
|
+
if (this.groupId) parts.push(this.groupId);
|
|
294
|
+
if (this.bitrate) parts.push(bitrateToString(this.bitrate));
|
|
295
|
+
if (this.name) parts.push(this.name);
|
|
296
|
+
if (this.codec) parts.push(this.codec);
|
|
297
|
+
if (this.languageCode) parts.push(this.languageCode);
|
|
298
|
+
if (this.numberOfChannels) parts.push(`${this.numberOfChannels}CH`);
|
|
299
|
+
if (this.role) parts.push(roleToString(this.role));
|
|
300
|
+
return parts.filter(Boolean).join(" | ").trim();
|
|
290
301
|
}
|
|
291
302
|
};
|
|
292
303
|
var SubtitleStreamInfo = class extends StreamInfo {
|
|
@@ -302,13 +313,14 @@ var SubtitleStreamInfo = class extends StreamInfo {
|
|
|
302
313
|
this.codec = info?.codec;
|
|
303
314
|
}
|
|
304
315
|
toShortString() {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
316
|
+
const parts = ["Sub"];
|
|
317
|
+
const text = parts.filter(Boolean).join(" | ");
|
|
318
|
+
if (this.groupId) parts.push(this.groupId);
|
|
319
|
+
if (this.languageCode) parts.push(this.languageCode);
|
|
320
|
+
if (this.name) parts.push(this.name);
|
|
321
|
+
if (this.codec) parts.push(this.codec);
|
|
322
|
+
if (this.role) parts.push(roleToString(this.role));
|
|
323
|
+
return text.trim();
|
|
312
324
|
}
|
|
313
325
|
};
|
|
314
326
|
|
|
@@ -335,15 +347,26 @@ var DefaultUrlProcessor = class {
|
|
|
335
347
|
|
|
336
348
|
//#endregion
|
|
337
349
|
//#region lib/dash/dash-content-processor.ts
|
|
350
|
+
const namespaceMap = new Map([
|
|
351
|
+
["cenc", "urn:mpeg:cenc:2013"],
|
|
352
|
+
["mspr", "urn:microsoft:playready"],
|
|
353
|
+
["mas", "urn:marlin:mas:1-0:services:schemas:mpd"]
|
|
354
|
+
]);
|
|
355
|
+
const isMissingNs = (rawText, tag) => !rawText.includes(`xmlns:${tag}`) && rawText.includes(`<${tag}:`);
|
|
356
|
+
function replaceFirst(source, oldValue, newValue) {
|
|
357
|
+
const index = source.indexOf(oldValue);
|
|
358
|
+
return index < 0 ? source : source.slice(0, index) + newValue + source.slice(index + oldValue.length);
|
|
359
|
+
}
|
|
338
360
|
var DefaultDashContentProcessor = class {
|
|
339
361
|
canProcess(extractorType, mpdContent) {
|
|
340
362
|
if (extractorType !== EXTRACTOR_TYPES.MPEG_DASH) return false;
|
|
341
|
-
return
|
|
363
|
+
return namespaceMap.keys().some((key) => isMissingNs(mpdContent, key));
|
|
342
364
|
}
|
|
343
365
|
process(mpdContent) {
|
|
344
|
-
console.debug("
|
|
345
|
-
|
|
346
|
-
return mpdContent;
|
|
366
|
+
console.debug("Namespace missing, trying to fix...");
|
|
367
|
+
const missingNamespaceKeys = Array.from(namespaceMap.keys().filter((key) => isMissingNs(mpdContent, key)));
|
|
368
|
+
if (!missingNamespaceKeys.length) return mpdContent;
|
|
369
|
+
return replaceFirst(mpdContent, "<MPD ", `<MPD ${missingNamespaceKeys.map((key) => `xmlns:${key}="${namespaceMap.get(key)}"`).join(" ")} `);
|
|
347
370
|
}
|
|
348
371
|
};
|
|
349
372
|
|
|
@@ -905,6 +928,7 @@ var DashExtractor = class DashExtractor {
|
|
|
905
928
|
streamInfo.channels = channelsString;
|
|
906
929
|
}
|
|
907
930
|
} else if (streamInfo.type === "subtitle") {
|
|
931
|
+
streamInfo.bitrate = bitrate;
|
|
908
932
|
if (roles) streamInfo.cc = checkIsClosedCaption(roles);
|
|
909
933
|
if (accessibilities) streamInfo.sdh = checkIsSdh(accessibilities);
|
|
910
934
|
}
|
|
@@ -1440,7 +1464,7 @@ var HlsExtractor = class {
|
|
|
1440
1464
|
url = response.url;
|
|
1441
1465
|
this.#m3u8Content = await response.text();
|
|
1442
1466
|
} catch (e) {
|
|
1443
|
-
if (url !== this.parserConfig.originalUrl) {
|
|
1467
|
+
if (this.parserConfig.originalUrl.startsWith("http") && url !== this.parserConfig.originalUrl) {
|
|
1444
1468
|
const response = await fetch(this.parserConfig.originalUrl, { headers: this.parserConfig.headers });
|
|
1445
1469
|
url = response.url;
|
|
1446
1470
|
this.#m3u8Content = await response.text();
|