Skip to content

Commit a69e43b

Browse files
authored
feat(FormatUtils): support multiple audio tracks in the DASH manifest (#308)
1 parent b2900f4 commit a69e43b

File tree

1 file changed

+74
-15
lines changed

1 file changed

+74
-15
lines changed

src/utils/FormatUtils.ts

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ class FormatUtils {
315315
if (!video_format.index_range || !video_format.init_range) {
316316
return;
317317
}
318-
const mime_type = video_format.mime_type;
318+
const mime_type = video_format.mime_type.split(';')[0];
319319
const mime_type_index = mime_types.indexOf(mime_type);
320320
if (mime_type_index > -1) {
321321
mime_objects[mime_type_index].push(video_format);
@@ -326,23 +326,81 @@ class FormatUtils {
326326
}
327327
});
328328

329+
let set_id = 0;
329330
for (let i = 0; i < mime_types.length; i++) {
330-
const set = this.#el(document, 'AdaptationSet', {
331-
id: `${i}`,
332-
mimeType: mime_types[i].split(';')[0],
333-
startWithSAP: '1',
334-
subsegmentAlignment: 'true'
335-
});
336331

337-
period.appendChild(set);
332+
// When the video has multiple different audio tracks/langues we want to include the extra information in the manifest
333+
if (mime_objects[i][0].has_audio && mime_objects[i][0].language) {
334+
const languages: string[] = [];
335+
const language_objects: Format[][] = [ [] ];
336+
337+
mime_objects[i].forEach((format) => {
338+
const language_index = languages.indexOf(format.language as string);
339+
if (language_index > -1) {
340+
language_objects[language_index].push(format);
341+
} else {
342+
languages.push(format.language as string);
343+
language_objects.push([]);
344+
language_objects[languages.length - 1].push(format);
345+
}
346+
});
347+
348+
// The lang attribute has to go on the AdaptationSet element, so we need a separate adaptation set for each language
349+
for (let j = 0; j < languages.length; j++) {
350+
const first_format = language_objects[j][0];
351+
352+
const children = [];
353+
354+
if (first_format.audio_track) {
355+
let role;
356+
if (first_format.audio_track.audio_is_default) {
357+
role = 'main';
358+
} else if (first_format.is_dubbed) {
359+
role = 'dub';
360+
} else {
361+
role = 'alternate';
362+
}
363+
364+
children.push(
365+
this.#el(document, 'Role', {
366+
schemeIdUri: 'urn:mpeg:dash:role:2011',
367+
value: role
368+
})
369+
);
370+
}
371+
372+
const set = this.#el(document, 'AdaptationSet', {
373+
id: `${set_id++}`,
374+
mimeType: mime_types[i],
375+
startWithSAP: '1',
376+
subsegmentAlignment: 'true',
377+
lang: languages[j]
378+
}, children);
338379

339-
mime_objects[i].forEach((format) => {
340-
if (format.has_video) {
341-
this.#generateRepresentationVideo(document, set, format, url_transformer, cpn, player);
342-
} else {
343-
this.#generateRepresentationAudio(document, set, format, url_transformer, cpn, player);
380+
period.appendChild(set);
381+
382+
language_objects[j].forEach((format) => {
383+
this.#generateRepresentationAudio(document, set, format, url_transformer, cpn, player);
384+
});
344385
}
345-
});
386+
} else {
387+
const set = this.#el(document, 'AdaptationSet', {
388+
id: `${set_id++}`,
389+
mimeType: mime_types[i],
390+
startWithSAP: '1',
391+
subsegmentAlignment: 'true'
392+
});
393+
394+
period.appendChild(set);
395+
396+
mime_objects[i].forEach((format) => {
397+
if (format.has_video) {
398+
this.#generateRepresentationVideo(document, set, format, url_transformer, cpn, player);
399+
} else {
400+
this.#generateRepresentationAudio(document, set, format, url_transformer, cpn, player);
401+
}
402+
});
403+
}
346404
}
347405
}
348406

@@ -388,7 +446,8 @@ class FormatUtils {
388446
set.appendChild(this.#el(document, 'Representation', {
389447
id: format.itag?.toString(),
390448
codecs,
391-
bandwidth: format.bitrate?.toString()
449+
bandwidth: format.bitrate?.toString(),
450+
audioSamplingRate: format.audio_sample_rate?.toString()
392451
}, [
393452
this.#el(document, 'AudioChannelConfiguration', {
394453
schemeIdUri: 'urn:mpeg:dash:23003:3:audio_channel_configuration:2011',

0 commit comments

Comments
 (0)