dasha 3.0.0 → 3.0.2
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/lib/dash.js +29 -26
- package/lib/track.js +10 -6
- package/package.json +1 -1
- package/types/dasha.d.ts +3 -3
package/lib/dash.js
CHANGED
|
@@ -236,35 +236,36 @@ const parseSegmentFromBase = async (segmentBase, baseUrl) => {
|
|
|
236
236
|
return { url: baseUrl, range: mediaRange };
|
|
237
237
|
};
|
|
238
238
|
|
|
239
|
+
const transformSegmentUrls = (segments) => {
|
|
240
|
+
for (const segment of segments) {
|
|
241
|
+
const hasHtmlEscapeCode = segment.url.includes('&');
|
|
242
|
+
if (hasHtmlEscapeCode) {
|
|
243
|
+
const url = new URL(segment.url);
|
|
244
|
+
const entries = new URLSearchParams(url.searchParams.toString()).entries();
|
|
245
|
+
for (const [key, value] of entries) {
|
|
246
|
+
url.searchParams.delete(key);
|
|
247
|
+
url.searchParams.append(key.replaceAll('amp;', ''), value);
|
|
248
|
+
}
|
|
249
|
+
segment.url = url.toString();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const protectionSchemas = {
|
|
255
|
+
'urn:mpeg:dash:mp4protection:2011': 'common',
|
|
256
|
+
'urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95': 'playready',
|
|
257
|
+
'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed': 'widevine',
|
|
258
|
+
};
|
|
259
|
+
|
|
239
260
|
const parseContentProtection = (contentProtections) => {
|
|
240
261
|
const protection = {};
|
|
241
|
-
const commonId = 'urn:mpeg:dash:mp4protection:2011';
|
|
242
|
-
const playreadyId = 'urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95';
|
|
243
|
-
const widevineId = 'urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed';
|
|
244
262
|
for (const contentProtection of contentProtections) {
|
|
245
263
|
const id = contentProtection.get('schemeIdUri')?.toLowerCase();
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
keyId: contentProtection.get('cenc:default_KID'),
|
|
252
|
-
};
|
|
253
|
-
continue;
|
|
254
|
-
case playreadyId:
|
|
255
|
-
protection.playready = {
|
|
256
|
-
id,
|
|
257
|
-
value: contentProtection.get('value'),
|
|
258
|
-
pssh: contentProtection.get('cenc:pssh')?.get(),
|
|
259
|
-
};
|
|
260
|
-
continue;
|
|
261
|
-
case widevineId:
|
|
262
|
-
protection.widevine = {
|
|
263
|
-
id,
|
|
264
|
-
pssh: contentProtection.get('cenc:pssh')?.get(),
|
|
265
|
-
};
|
|
266
|
-
continue;
|
|
267
|
-
}
|
|
264
|
+
const value = contentProtection.get('value');
|
|
265
|
+
const pssh = contentProtection.get('cenc:pssh')?.get();
|
|
266
|
+
const defaultKeyId = contentProtection.get('cenc:default_KID');
|
|
267
|
+
const data = { id, value, pssh, defaultKeyId };
|
|
268
|
+
protection[protectionSchemas[id]] = data;
|
|
268
269
|
}
|
|
269
270
|
return protection;
|
|
270
271
|
};
|
|
@@ -312,6 +313,7 @@ const parseManifest = async (text, url, fallbackLanguage) => {
|
|
|
312
313
|
} else {
|
|
313
314
|
throw new Error('Could not find a way to get segments from this MPD manifest.');
|
|
314
315
|
}
|
|
316
|
+
transformSegmentUrls(segments);
|
|
315
317
|
|
|
316
318
|
const label = get('label');
|
|
317
319
|
const fps = get('frameRate') ?? segmentBase?.attributes.timescale;
|
|
@@ -322,10 +324,11 @@ const parseManifest = async (text, url, fallbackLanguage) => {
|
|
|
322
324
|
const essentialProps = getAll('EssentialProperty');
|
|
323
325
|
const accessibilities = adaptationSet.getAll('Accessibility');
|
|
324
326
|
const roles = adaptationSet.getAll('Role');
|
|
325
|
-
const contentProtections =
|
|
327
|
+
const contentProtections = getAll('ContentProtection');
|
|
326
328
|
|
|
327
329
|
const id = [
|
|
328
330
|
new URL(baseUrl).hostname,
|
|
331
|
+
contentType,
|
|
329
332
|
codecs,
|
|
330
333
|
bitrate,
|
|
331
334
|
language,
|
package/lib/track.js
CHANGED
|
@@ -33,14 +33,18 @@ const createAudioLanguageFilter = (audios) => {
|
|
|
33
33
|
if (!alreadyAdded) languages.push(audio.language);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
const
|
|
36
|
+
const filtered = [];
|
|
37
37
|
for (const language of languages) {
|
|
38
38
|
const tracks = audios.filter((track) => track.language?.startsWith(language));
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
filtered.push(...tracks);
|
|
40
|
+
}
|
|
41
|
+
const results = [];
|
|
42
|
+
const filteredLanguages = [...new Set(filtered.map((track) => track.language))];
|
|
43
|
+
for (const language of filteredLanguages) {
|
|
44
|
+
const tracks = filtered
|
|
45
|
+
.filter((track) => track.language === language)
|
|
46
|
+
.slice(0, maxTracksPerLanguage);
|
|
47
|
+
results.push(...tracks);
|
|
44
48
|
}
|
|
45
49
|
return results;
|
|
46
50
|
};
|
package/package.json
CHANGED
package/types/dasha.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function parse(text: string, url
|
|
1
|
+
export function parse(text: string, url?: string, fallbackLanguage?: string): Promise<Manifest>;
|
|
2
2
|
|
|
3
3
|
export interface Manifest {
|
|
4
4
|
duration?: number;
|
|
@@ -50,9 +50,9 @@ export interface Segment {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export interface TrackProtection {
|
|
53
|
-
common?: { id: string; value: 'cenc' | 'cbcs';
|
|
53
|
+
common?: { id: string; value: 'cenc' | 'cbcs'; defaultKeyId?: string };
|
|
54
54
|
playready?: { id: string; pssh?: string; value?: string };
|
|
55
|
-
widevine?: { id: string; pssh: string };
|
|
55
|
+
widevine?: { id: string; pssh: string; defaultKeyId?: string };
|
|
56
56
|
fairplay?: { keyFormat: string; uri: string; method: string };
|
|
57
57
|
}
|
|
58
58
|
|