From cac746985dc502dcc830077a34748cfcf1999fa4 Mon Sep 17 00:00:00 2001 From: Vitaly Gashkov Date: Thu, 4 Apr 2024 20:19:25 +0500 Subject: [PATCH] fix(dash): handle case if no period base url, add unique track id --- lib/audio.js | 2 ++ lib/dash.js | 28 ++++++++++++++++++++++++---- lib/subtitle.js | 11 ++++++++++- lib/video.js | 2 ++ 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/lib/audio.js b/lib/audio.js index 86a28b8..e6ccc30 100644 --- a/lib/audio.js +++ b/lib/audio.js @@ -67,6 +67,7 @@ const checkIsDescriptive = (accessibilities = []) => { }; const createAudioTrack = ({ + id, codec, channels, bitrate, @@ -77,6 +78,7 @@ const createAudioTrack = ({ }) => { const parsedBitrate = parseBitrate(Number(bitrate)); return { + id, codec, bitrate: parsedBitrate, segments, diff --git a/lib/dash.js b/lib/dash.js index eebacab..3f6e4e7 100644 --- a/lib/dash.js +++ b/lib/dash.js @@ -57,8 +57,11 @@ const parseBaseUrl = (manifestUrl, mpd, period, representation) => { if (!manifestBaseUrl) manifestBaseUrl = manifestUrl; else if (!manifestBaseUrl.startsWith('https://')) manifestBaseUrl = new URL(manifestBaseUrl, manifestUrl).toString(); - const periodBaseUrl = new URL(period.getBaseUrl(), manifestBaseUrl).toString(); - const representationBaseUrl = new URL(representation.getBaseUrl(), periodBaseUrl).toString(); + const periodBaseUrl = new URL(period.getBaseUrl() || '', manifestBaseUrl).toString(); + const representationBaseUrl = new URL( + representation.getBaseUrl() || '', + periodBaseUrl + ).toString(); return representationBaseUrl; }; @@ -79,15 +82,16 @@ const parseCodecs = (representation, contentType, mimeType) => { const parseLanguage = (representation, adaptationSet, fallbackLanguage) => { let language = ''; const options = []; + const lang = representation.get('lang'); + const id = representation.get('id'); if (representation) { - const { lang, id } = representation.attributes; options.push(lang); if (id) { const m = id.match(/\w+_(\w+)=\d+/); if (m) options.push(m.group(1)); } } - options.push(adaptationSet.attributes.lang); + options.push(adaptationSet.get('lang')); if (fallbackLanguage) options.push(fallbackLanguage); for (const option of options) { const value = (option || '').trim(); @@ -269,9 +273,23 @@ const parseManifest = async (text, url, fallbackLanguage) => { const accessibilities = adaptationSet.getAll('Accessibility'); const roles = adaptationSet.getAll('Role'); + const id = [ + get('id'), + get('audioTrackId'), + period.get('id'), + mpd.get('id'), + bitrate, + codecs, + language, + new URL(baseUrl).hostname, + ] + .filter(Boolean) + .join('-'); + switch (contentType) { case 'video': { const track = createVideoTrack({ + id, codec: parseVideoCodec(codecs), dynamicRange: parseDynamicRange(codecs, supplementalProps, essentialProps), bitrate, @@ -286,6 +304,7 @@ const parseManifest = async (text, url, fallbackLanguage) => { } case 'audio': { const track = createAudioTrack({ + id, codec: parseAudioCodec(codecs), channels: get('AudioChannelConfiguration').get('value'), jointObjectCoding: getDolbyDigitalPlusComplexityIndex(supplementalProps), @@ -299,6 +318,7 @@ const parseManifest = async (text, url, fallbackLanguage) => { } case 'text': { const track = createSubtitleTrack({ + id, codec: parseSubtitleCodec(codecs || 'vtt'), isClosedCaption: checkIsClosedCaption(roles), isSdh: checkIsSdh(accessibilities), diff --git a/lib/subtitle.js b/lib/subtitle.js index b1f0b75..57623a8 100644 --- a/lib/subtitle.js +++ b/lib/subtitle.js @@ -76,8 +76,17 @@ const checkIsForced = (roles = []) => { return false; }; -const createSubtitleTrack = ({ codec, isClosedCaption, isSdh, isForced, language, segments }) => { +const createSubtitleTrack = ({ + id, + codec, + isClosedCaption, + isSdh, + isForced, + language, + segments, +}) => { return { + id, codec, isClosedCaption, isSdh, diff --git a/lib/video.js b/lib/video.js index 249071d..69d561f 100644 --- a/lib/video.js +++ b/lib/video.js @@ -82,6 +82,7 @@ const parseDynamicRangeFromCicp = (primaries, transfer, matrix) => { }; const createVideoTrack = ({ + id, codec, dynamicRange, bitrate, @@ -95,6 +96,7 @@ const createVideoTrack = ({ const parsedWidth = Number(width); const parsedHeight = Number(height); return { + id, codec, bitrate: parsedBitrate, segments,