diff --git a/lib/audio.js b/lib/audio.js
index de46198..a9b77cc 100644
--- a/lib/audio.js
+++ b/lib/audio.js
@@ -50,12 +50,11 @@ const parseAudioCodec = (codecs) => {
);
};
-const isAudioCodec = (codecs) => {
+const tryParseAudioCodec = (codecs) => {
try {
- parseAudioCodec(codecs);
- return true;
+ return parseAudioCodec(codecs);
} catch (e) {
- return false;
+ return null;
}
};
@@ -142,7 +141,7 @@ const createAudioTrack = ({
module.exports = {
AUDIO_CODECS,
parseAudioCodec,
- isAudioCodec,
+ tryParseAudioCodec,
createAudioTrack,
getDolbyDigitalPlusComplexityIndex,
checkIsDescriptive,
diff --git a/lib/dash.js b/lib/dash.js
index a41cc53..1ac581f 100644
--- a/lib/dash.js
+++ b/lib/dash.js
@@ -4,20 +4,20 @@ const xml = require('./xml');
const { parseDuration, isLanguageTagValid } = require('./util');
const {
parseVideoCodec,
- isVideoCodec,
+ tryParseVideoCodec,
parseDynamicRange,
createVideoTrack,
} = require('./video');
const {
parseAudioCodec,
- isAudioCodec,
+ tryParseAudioCodec,
createAudioTrack,
getDolbyDigitalPlusComplexityIndex,
checkIsDescriptive,
} = require('./audio');
const {
parseSubtitleCodec,
- isSubtitleCodec,
+ tryParseSubtitleCodec,
checkIsClosedCaption,
checkIsSdh,
checkIsForced,
@@ -79,17 +79,24 @@ const parseBaseUrl = (manifestUrl, mpd, period, representation) => {
return baseUrl;
};
+const getTrackTypeByCodecs = (codecs) => {
+ if (tryParseVideoCodec(codecs)) return 'video';
+ else if (tryParseAudioCodec(codecs)) return 'audio';
+ else if (tryParseSubtitleCodec(codecs)) return 'text';
+ return null;
+};
+
const parseContentTypes = (representation) => {
const codecs = representation.get('codecs');
- const codecsType = isVideoCodec(codecs) ? 'video' : isAudioCodec(codecs) ? 'audio' : isSubtitleCodec(codecs) ? 'text' : null;
const mimeType = representation.get('mimeType');
+ const contentTypeByCodecs = getTrackTypeByCodecs(codecs);
const contentType =
- codecsType || codecsTyperepresentation.get('contentType') || mimeType?.split('/')[0];
+ representation.get('contentType') || mimeType?.split('/')[0];
if (!contentType && !mimeType)
throw new Error(
'Unable to determine the format of a Representation, cannot continue...',
);
- return { contentType, mimeType };
+ return { contentType: contentTypeByCodecs || contentType, mimeType };
};
const parseCodecs = (representation, contentType, mimeType) => {
@@ -208,6 +215,10 @@ const parseSegmentsFromTemplate = (
: DEFAULT_SEGMENTS_COUNT;
const bandwidth = representation.get('bandwidth');
const id = representation.get('id');
+
+ const sanitizeTemplate = (template) =>
+ template?.replace(/\$.*?(RepresentationID|Number|Time).*?\$/g, '$$$1$$');
+
const segments = [];
if (segmentTimeline) {
segments.push(
@@ -219,8 +230,9 @@ const parseSegmentsFromTemplate = (
),
);
} else {
+ const template = sanitizeTemplate(segmentTemplate.get('media'));
for (let i = startNumber; i < startNumber + segmentsCount; i++) {
- const url = buildSegmentUrl(segmentTemplate.get('media'), {
+ const url = buildSegmentUrl(template, {
Bandwidth: bandwidth,
RepresentationID: id,
Number: i,
@@ -229,7 +241,9 @@ const parseSegmentsFromTemplate = (
segments.push({ url });
}
}
- const initialization = segmentTemplate.get('initialization');
+ const initialization = sanitizeTemplate(
+ segmentTemplate.get('initialization'),
+ );
if (initialization) {
const url = buildSegmentUrl(initialization, {
Bandwidth: bandwidth,
@@ -305,7 +319,6 @@ const parseContentProtection = (contentProtections) => {
};
const parseManifest = async (text, url, fallbackLanguage) => {
- text = text.replace(/\$.*?(RepresentationID|Number|Time).*?\$/g, "$$$1$$");
const mpd = appendUtils(xml.parse(text)).get('MPD');
const period = mpd.get('Period');
const durationString =
diff --git a/lib/subtitle.js b/lib/subtitle.js
index b9c555d..04c978a 100644
--- a/lib/subtitle.js
+++ b/lib/subtitle.js
@@ -51,12 +51,11 @@ const parseSubtitleCodec = (codecs) => {
);
};
-const isSubtitleCodec = (codecs) => {
+const tryParseSubtitleCodec = (codecs) => {
try {
- parseSubtitleCodec(codecs);
- return true;
+ return parseSubtitleCodec(codecs);
} catch (e) {
- return false;
+ return null;
}
};
@@ -129,7 +128,7 @@ const createSubtitleTrack = ({
module.exports = {
parseSubtitleCodec,
- isSubtitleCodec,
+ tryParseSubtitleCodec,
checkIsClosedCaption,
checkIsSdh,
checkIsForced,
diff --git a/lib/video.js b/lib/video.js
index fe25840..41bf5df 100644
--- a/lib/video.js
+++ b/lib/video.js
@@ -153,12 +153,11 @@ const parseVideoCodec = (codecs) => {
);
};
-const isVideoCodec = (codecs) => {
+const tryParseVideoCodec = (codecs) => {
try {
- parseVideoCodec(codecs);
- return true;
+ return parseVideoCodec(codecs);
} catch (e) {
- return false;
+ return null;
}
};
@@ -194,7 +193,7 @@ const parseDynamicRange = (
module.exports = {
parseVideoCodec,
- isVideoCodec,
+ tryParseVideoCodec,
parseDynamicRange,
createVideoTrack,
VIDEO_CODECS,
diff --git a/test/axinom.mpd b/test/axinom.mpd
new file mode 100644
index 0000000..0dd711a
--- /dev/null
+++ b/test/axinom.mpd
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+ AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBEAFEAVwAwAG4AawB2AGsAQQBrAGkAVABMAGkAZgBYAFUASQBQAGkAWgBnAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ARABRAFcAMABuAGsAdgBrAEEAawBpAFQATABpAGYAWABVAEkAUABpAFoAZwA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
+
+
+ AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQnrQFDeRLSAKTLifXUIPiZg==
+
+
+
+
+
+
+
+
+
+
+
+
+ AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBEAFEAVwAwAG4AawB2AGsAQQBrAGkAVABMAGkAZgBYAFUASQBQAGkAWgBnAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ARABRAFcAMABuAGsAdgBrAEEAawBpAFQATABpAGYAWABVAEkAUABpAFoAZwA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
+
+
+ AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQnrQFDeRLSAKTLifXUIPiZg==
+
+
+
+
+
+
+
+
+
+
+
+
+ AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBEAFEAVwAwAG4AawB2AGsAQQBrAGkAVABMAGkAZgBYAFUASQBQAGkAWgBnAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ARABRAFcAMABuAGsAdgBrAEEAawBpAFQATABpAGYAWABVAEkAUABpAFoAZwA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
+
+
+ AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQnrQFDeRLSAKTLifXUIPiZg==
+
+
+
+
+
+
+
+
+
+
+ AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBEAFEAVwAwAG4AawB2AGsAQQBrAGkAVABMAGkAZgBYAFUASQBQAGkAWgBnAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ARABRAFcAMABuAGsAdgBrAEEAawBpAFQATABpAGYAWABVAEkAUABpAFoAZwA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
+
+
+ AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQnrQFDeRLSAKTLifXUIPiZg==
+
+
+
+
+
+
+
+
+
+ AAAB5HBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAcTEAQAAAQABALoBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgBEAFEAVwAwAG4AawB2AGsAQQBrAGkAVABMAGkAZgBYAFUASQBQAGkAWgBnAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==
+ xAEAAAEAAQC6ATwAVwBSAE0ASABFAEEARABFAFIAIAB4AG0AbABuAHMAPQAiAGgAdAB0AHAAOgAvAC8AcwBjAGgAZQBtAGEAcwAuAG0AaQBjAHIAbwBzAG8AZgB0AC4AYwBvAG0ALwBEAFIATQAvADIAMAAwADcALwAwADMALwBQAGwAYQB5AFIAZQBhAGQAeQBIAGUAYQBkAGUAcgAiACAAdgBlAHIAcwBpAG8AbgA9ACIANAAuADAALgAwAC4AMAAiAD4APABEAEEAVABBAD4APABQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsARQBZAEwARQBOAD4AMQA2ADwALwBLAEUAWQBMAEUATgA+ADwAQQBMAEcASQBEAD4AQQBFAFMAQwBUAFIAPAAvAEEATABHAEkARAA+ADwALwBQAFIATwBUAEUAQwBUAEkATgBGAE8APgA8AEsASQBEAD4ARABRAFcAMABuAGsAdgBrAEEAawBpAFQATABpAGYAWABVAEkAUABpAFoAZwA9AD0APAAvAEsASQBEAD4APAAvAEQAQQBUAEEAPgA8AC8AVwBSAE0ASABFAEEARABFAFIAPgA=
+
+
+ AAAANHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAABQIARIQnrQFDeRLSAKTLifXUIPiZg==
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/axinom.test.js b/test/axinom.test.js
new file mode 100644
index 0000000..b97bf3d
--- /dev/null
+++ b/test/axinom.test.js
@@ -0,0 +1,24 @@
+const { test } = require('node:test');
+const { strictEqual } = require('node:assert');
+const { parse } = require('../dasha');
+const { load } = require('./utils');
+
+test('axinom manifest parsing', async () => {
+ const url =
+ 'https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p.mpd';
+ const text = load('axinom.mpd');
+ const manifest = await parse(text, url);
+
+ const firstVideoTrack = manifest.tracks.videos[0];
+ const firstVideoSegment = firstVideoTrack.segments[1]; // Skip init
+ strictEqual(
+ firstVideoSegment.url,
+ 'https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/5/1.m4s',
+ );
+
+ const firstSubtitleTrack = manifest.tracks.subtitles[0];
+ strictEqual(firstSubtitleTrack.codec, 'WVTT');
+ strictEqual(firstSubtitleTrack.language, 'en');
+
+ strictEqual(manifest.tracks.all.length, 23);
+});
diff --git a/test/bitmovin.mpd b/test/bitmovin.mpd
new file mode 100644
index 0000000..1adfcb7
--- /dev/null
+++ b/test/bitmovin.mpd
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+ AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA==
+
+
+
+
+
+ AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA==
+
+
+
+
+
+ AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA==
+
+
+
+
+
+ AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA==
+
+
+
+
+
+ AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA==
+
+
+
+
+
+ AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA==
+
+
+
+
+
+
+
+
+
+ AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA==
+
+
+
+
+
diff --git a/test/bitmovin.test.js b/test/bitmovin.test.js
new file mode 100644
index 0000000..0a96a49
--- /dev/null
+++ b/test/bitmovin.test.js
@@ -0,0 +1,19 @@
+const { test } = require('node:test');
+const { strictEqual } = require('node:assert');
+const { parse } = require('../dasha');
+const { load } = require('./utils');
+
+test('bitmovin manifest parsing', async () => {
+ const url =
+ 'https://cdn.bitmovin.com/content/assets/art-of-motion_drm/mpds/11331.mpd';
+ const text = load('bitmovin.mpd');
+ const manifest = await parse(text, url);
+
+ const firstAudioTrack = manifest.tracks.audios[0];
+ strictEqual(
+ firstAudioTrack.protection.widevine.pssh,
+ 'AAAAW3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADsIARIQ62dqu8s0Xpa7z2FmMPGj2hoNd2lkZXZpbmVfdGVzdCIQZmtqM2xqYVNkZmFsa3IzaioCSEQyAA==',
+ );
+
+ strictEqual(manifest.tracks.all.length, 7);
+});
diff --git a/test/dasha.test.js b/test/dasha.test.js
index fd00484..ece8ff3 100644
--- a/test/dasha.test.js
+++ b/test/dasha.test.js
@@ -1,10 +1,8 @@
const { test } = require('node:test');
const { strictEqual } = require('node:assert');
-const { readFileSync } = require('node:fs');
const { getQualityLabel } = require('../lib/util');
const { parse } = require('../dasha');
-
-const load = (path) => readFileSync(path, 'utf8');
+const { load } = require('./utils');
test('get video quality label', () => {
strictEqual(getQualityLabel({ width: 1920, height: 804 }), '1080p');
@@ -22,7 +20,7 @@ test('DASH: parse with URL parameter', async () => {
});
test('DASH: parse without URL parameter', async () => {
- const text = load('./test/cr.mpd');
+ const text = load('cr.mpd');
const manifest = await parse(text);
strictEqual(manifest.tracks.all.length, 8);
const initUrl =
diff --git a/test/utils.js b/test/utils.js
new file mode 100644
index 0000000..032a31a
--- /dev/null
+++ b/test/utils.js
@@ -0,0 +1,6 @@
+const { readFileSync } = require('node:fs');
+const { join } = require('node:path');
+
+const load = (filename) => readFileSync(join('./test', filename), 'utf8');
+
+module.exports = { load };