1
1
import { values } from './utils/object' ;
2
2
import { findIndexes } from './utils/list' ;
3
- import { addSegmentsToPlaylist } from './segment/segmentBase' ;
3
+ import { addSidxSegmentsToPlaylist as addSidxSegmentsToPlaylist_ } from './segment/segmentBase' ;
4
4
import { byteRangeToString } from './segment/urlType' ;
5
5
6
+ export const generateSidxKey = ( sidx ) => sidx &&
7
+ sidx . uri + '-' + byteRangeToString ( sidx . byterange ) ;
8
+
6
9
const mergeDiscontiguousPlaylists = playlists => {
7
10
const mergedPlaylists = values ( playlists . reduce ( ( acc , playlist ) => {
8
11
// assuming playlist IDs are the same across periods
@@ -40,31 +43,30 @@ const mergeDiscontiguousPlaylists = playlists => {
40
43
} ) ;
41
44
} ;
42
45
43
- const addSegmentInfoFromSidx = ( playlists , sidxMapping = { } ) => {
46
+ export const addSidxSegmentsToPlaylist = ( playlist , sidxMapping ) => {
47
+ const sidxKey = generateSidxKey ( playlist . sidx ) ;
48
+ const sidxMatch = sidxKey && sidxMapping [ sidxKey ] && sidxMapping [ sidxKey ] . sidx ;
49
+
50
+ if ( sidxMatch ) {
51
+ addSidxSegmentsToPlaylist_ ( playlist , sidxMatch , playlist . sidx . resolvedUri ) ;
52
+ }
53
+
54
+ return playlist ;
55
+ } ;
56
+
57
+ export const addSidxSegmentsToPlaylists = ( playlists , sidxMapping = { } ) => {
44
58
if ( ! Object . keys ( sidxMapping ) . length ) {
45
59
return playlists ;
46
60
}
47
61
48
62
for ( const i in playlists ) {
49
- const playlist = playlists [ i ] ;
50
-
51
- if ( ! playlist . sidx ) {
52
- continue ;
53
- }
54
-
55
- const sidxKey = playlist . sidx . uri + '-' +
56
- byteRangeToString ( playlist . sidx . byterange ) ;
57
- const sidxMatch = sidxMapping [ sidxKey ] && sidxMapping [ sidxKey ] . sidx ;
58
-
59
- if ( playlist . sidx && sidxMatch ) {
60
- addSegmentsToPlaylist ( playlist , sidxMatch , playlist . sidx . resolvedUri ) ;
61
- }
63
+ playlists [ i ] = addSidxSegmentsToPlaylist ( playlists [ i ] , sidxMapping ) ;
62
64
}
63
65
64
66
return playlists ;
65
67
} ;
66
68
67
- export const formatAudioPlaylist = ( { attributes, segments, sidx } ) => {
69
+ export const formatAudioPlaylist = ( { attributes, segments, sidx } , isAudioOnly ) => {
68
70
const playlist = {
69
71
attributes : {
70
72
NAME : attributes . id ,
@@ -89,6 +91,11 @@ export const formatAudioPlaylist = ({ attributes, segments, sidx }) => {
89
91
playlist . sidx = sidx ;
90
92
}
91
93
94
+ if ( isAudioOnly ) {
95
+ playlist . attributes . AUDIO = 'audio' ;
96
+ playlist . attributes . SUBTITLES = 'subs' ;
97
+ }
98
+
92
99
return playlist ;
93
100
} ;
94
101
@@ -127,7 +134,7 @@ export const formatVttPlaylist = ({ attributes, segments }) => {
127
134
} ;
128
135
} ;
129
136
130
- export const organizeAudioPlaylists = ( playlists , sidxMapping = { } ) => {
137
+ export const organizeAudioPlaylists = ( playlists , sidxMapping = { } , isAudioOnly = false ) => {
131
138
let mainPlaylist ;
132
139
133
140
const formattedPlaylists = playlists . reduce ( ( a , playlist ) => {
@@ -143,23 +150,19 @@ export const organizeAudioPlaylists = (playlists, sidxMapping = {}) => {
143
150
label = `${ playlist . attributes . lang } ${ roleLabel } ` ;
144
151
}
145
152
146
- // skip if we already have the highest quality audio for a language
147
- if ( a [ label ] &&
148
- a [ label ] . playlists [ 0 ] . attributes . BANDWIDTH >
149
- playlist . attributes . bandwidth ) {
150
- return a ;
153
+ if ( ! a [ label ] ) {
154
+ a [ label ] = {
155
+ language,
156
+ autoselect : true ,
157
+ default : role === 'main' ,
158
+ playlists : [ ] ,
159
+ uri : ''
160
+ } ;
151
161
}
152
162
153
- a [ label ] = {
154
- language,
155
- autoselect : true ,
156
- default : role === 'main' ,
157
- playlists : addSegmentInfoFromSidx (
158
- [ formatAudioPlaylist ( playlist ) ] ,
159
- sidxMapping
160
- ) ,
161
- uri : ''
162
- } ;
163
+ const formatted = addSidxSegmentsToPlaylist ( formatAudioPlaylist ( playlist , isAudioOnly ) , sidxMapping ) ;
164
+
165
+ a [ label ] . playlists . push ( formatted ) ;
163
166
164
167
if ( typeof mainPlaylist === 'undefined' && role === 'main' ) {
165
168
mainPlaylist = playlist ;
@@ -183,21 +186,16 @@ export const organizeVttPlaylists = (playlists, sidxMapping = {}) => {
183
186
return playlists . reduce ( ( a , playlist ) => {
184
187
const label = playlist . attributes . lang || 'text' ;
185
188
186
- // skip if we already have subtitles
187
- if ( a [ label ] ) {
188
- return a ;
189
+ if ( ! a [ label ] ) {
190
+ a [ label ] = {
191
+ language : label ,
192
+ default : false ,
193
+ autoselect : false ,
194
+ playlists : [ ] ,
195
+ uri : ''
196
+ } ;
189
197
}
190
-
191
- a [ label ] = {
192
- language : label ,
193
- default : false ,
194
- autoselect : false ,
195
- playlists : addSegmentInfoFromSidx (
196
- [ formatVttPlaylist ( playlist ) ] ,
197
- sidxMapping
198
- ) ,
199
- uri : ''
200
- } ;
198
+ a [ label ] . playlists . push ( addSidxSegmentsToPlaylist ( formatVttPlaylist ( playlist ) , sidxMapping ) ) ;
201
199
202
200
return a ;
203
201
} , { } ) ;
@@ -237,6 +235,13 @@ export const formatVideoPlaylist = ({ attributes, segments, sidx }) => {
237
235
return playlist ;
238
236
} ;
239
237
238
+ const videoOnly = ( { attributes } ) =>
239
+ attributes . mimeType === 'video/mp4' || attributes . mimeType === 'video/webm' || attributes . contentType === 'video' ;
240
+ const audioOnly = ( { attributes } ) =>
241
+ attributes . mimeType === 'audio/mp4' || attributes . mimeType === 'audio/webm' || attributes . contentType === 'audio' ;
242
+ const vttOnly = ( { attributes } ) =>
243
+ attributes . mimeType === 'text/vtt' || attributes . contentType === 'text' ;
244
+
240
245
export const toM3u8 = ( dashPlaylists , locations , sidxMapping = { } ) => {
241
246
if ( ! dashPlaylists . length ) {
242
247
return { } ;
@@ -250,13 +255,6 @@ export const toM3u8 = (dashPlaylists, locations, sidxMapping = {}) => {
250
255
minimumUpdatePeriod
251
256
} = dashPlaylists [ 0 ] . attributes ;
252
257
253
- const videoOnly = ( { attributes } ) =>
254
- attributes . mimeType === 'video/mp4' || attributes . mimeType === 'video/webm' || attributes . contentType === 'video' ;
255
- const audioOnly = ( { attributes } ) =>
256
- attributes . mimeType === 'audio/mp4' || attributes . mimeType === 'audio/webm' || attributes . contentType === 'audio' ;
257
- const vttOnly = ( { attributes } ) =>
258
- attributes . mimeType === 'text/vtt' || attributes . contentType === 'text' ;
259
-
260
258
const videoPlaylists = mergeDiscontiguousPlaylists ( dashPlaylists . filter ( videoOnly ) ) . map ( formatVideoPlaylist ) ;
261
259
const audioPlaylists = mergeDiscontiguousPlaylists ( dashPlaylists . filter ( audioOnly ) ) ;
262
260
const vttPlaylists = dashPlaylists . filter ( vttOnly ) ;
@@ -274,7 +272,7 @@ export const toM3u8 = (dashPlaylists, locations, sidxMapping = {}) => {
274
272
} ,
275
273
uri : '' ,
276
274
duration,
277
- playlists : addSegmentInfoFromSidx ( videoPlaylists , sidxMapping )
275
+ playlists : addSidxSegmentsToPlaylists ( videoPlaylists , sidxMapping )
278
276
} ;
279
277
280
278
if ( minimumUpdatePeriod >= 0 ) {
@@ -289,8 +287,10 @@ export const toM3u8 = (dashPlaylists, locations, sidxMapping = {}) => {
289
287
master . suggestedPresentationDelay = suggestedPresentationDelay ;
290
288
}
291
289
290
+ const isAudioOnly = master . playlists . length === 0 ;
291
+
292
292
if ( audioPlaylists . length ) {
293
- master . mediaGroups . AUDIO . audio = organizeAudioPlaylists ( audioPlaylists , sidxMapping ) ;
293
+ master . mediaGroups . AUDIO . audio = organizeAudioPlaylists ( audioPlaylists , sidxMapping , isAudioOnly ) ;
294
294
}
295
295
296
296
if ( vttPlaylists . length ) {
0 commit comments