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 };