@@ -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