@@ -19,34 +19,73 @@ import {
1919const { mergeOptions, EventTarget } = videojs ;
2020
2121/**
22- * Returns a new array of segments that is the result of merging
23- * properties from an older list of segments onto an updated
24- * list. No properties on the updated playlist will be overridden.
25- *
26- * @param {Array } original the outdated list of segments
27- * @param {Array } update the updated list of segments
28- * @param {number= } offset the index of the first update
29- * segment in the original segment list. For non-live playlists,
30- * this should always be zero and does not need to be
31- * specified. For live playlists, it should be the difference
32- * between the media sequence numbers in the original and updated
33- * playlists.
34- * @return a list of merged segment objects
35- */
22+ * Returns a new segment object with properties and
23+ * the parts array merged.
24+ *
25+ * @param {Object } a the old segment
26+ * @param {Object } b the new segment
27+ *
28+ * @return {Object } the merged segment
29+ */
30+ export const updateSegment = ( a , b ) => {
31+ if ( ! a ) {
32+ return b ;
33+ }
34+
35+ const result = mergeOptions ( a , b ) ;
36+
37+ // if only the old segment has parts
38+ // then the parts are no longer valid
39+ if ( a . parts && ! b . parts ) {
40+ delete result . parts ;
41+ // if both segments have parts
42+ // copy part propeties from the old segment
43+ // to the new one.
44+ } else if ( a . parts && b . parts ) {
45+ for ( let i = 0 ; i < b . parts . length ; i ++ ) {
46+ if ( a . parts && a . parts [ i ] ) {
47+ result . parts [ i ] = mergeOptions ( a . parts [ i ] , b . parts [ i ] ) ;
48+ }
49+ }
50+ }
51+
52+ return result ;
53+ } ;
54+
55+ /**
56+ * Returns a new array of segments that is the result of merging
57+ * properties from an older list of segments onto an updated
58+ * list. No properties on the updated playlist will be ovewritten.
59+ *
60+ * @param {Array } original the outdated list of segments
61+ * @param {Array } update the updated list of segments
62+ * @param {number= } offset the index of the first update
63+ * segment in the original segment list. For non-live playlists,
64+ * this should always be zero and does not need to be
65+ * specified. For live playlists, it should be the difference
66+ * between the media sequence numbers in the original and updated
67+ * playlists.
68+ * @return {Array } a list of merged segment objects
69+ */
3670export const updateSegments = ( original , update , offset ) => {
71+ const oldSegments = original . slice ( ) ;
3772 const result = update . slice ( ) ;
3873
3974 offset = offset || 0 ;
4075 const length = Math . min ( original . length , update . length + offset ) ;
4176
4277 for ( let i = offset ; i < length ; i ++ ) {
43- result [ i - offset ] = mergeOptions ( original [ i ] , result [ i - offset ] ) ;
78+ const newIndex = i - offset ;
79+
80+ result [ newIndex ] = updateSegment ( oldSegments [ i ] , result [ newIndex ] ) ;
4481 }
4582 return result ;
4683} ;
4784
4885export const resolveSegmentUris = ( segment , baseUri ) => {
49- if ( ! segment . resolvedUri ) {
86+ // preloadSegments will not have a uri at all
87+ // as the segment isn't actually in the manifest yet, only parts
88+ if ( ! segment . resolvedUri && segment . uri ) {
5089 segment . resolvedUri = resolveUrl ( baseUri , segment . uri ) ;
5190 }
5291 if ( segment . key && ! segment . key . resolvedUri ) {
@@ -55,6 +94,23 @@ export const resolveSegmentUris = (segment, baseUri) => {
5594 if ( segment . map && ! segment . map . resolvedUri ) {
5695 segment . map . resolvedUri = resolveUrl ( baseUri , segment . map . uri ) ;
5796 }
97+ if ( segment . parts && segment . parts . length ) {
98+ segment . parts . forEach ( ( p ) => {
99+ if ( p . resolvedUri ) {
100+ return ;
101+ }
102+ p . resolvedUri = resolveUrl ( baseUri , p . uri ) ;
103+ } ) ;
104+ }
105+
106+ if ( segment . preloadHints && segment . preloadHints . length ) {
107+ segment . preloadHints . forEach ( ( p ) => {
108+ if ( p . resolvedUri ) {
109+ return ;
110+ }
111+ p . resolvedUri = resolveUrl ( baseUri , p . uri ) ;
112+ } ) ;
113+ }
58114} ;
59115
60116// consider the playlist unchanged if the playlist object is the same or
@@ -173,6 +229,7 @@ export default class PlaylistLoader extends EventTarget {
173229
174230 this . customTagParsers = ( vhsOptions && vhsOptions . customTagParsers ) || [ ] ;
175231 this . customTagMappers = ( vhsOptions && vhsOptions . customTagMappers ) || [ ] ;
232+ this . experimentalLLHLS = ( vhsOptions && vhsOptions . experimentalLLHLS ) || false ;
176233
177234 // initialize the loader state
178235 this . state = 'HAVE_NOTHING' ;
@@ -254,7 +311,8 @@ export default class PlaylistLoader extends EventTarget {
254311 oninfo : ( { message} ) => this . logger_ ( `m3u8-parser info for ${ id } : ${ message } ` ) ,
255312 manifestString : playlistString ,
256313 customTagParsers : this . customTagParsers ,
257- customTagMappers : this . customTagMappers
314+ customTagMappers : this . customTagMappers ,
315+ experimentalLLHLS : this . experimentalLLHLS
258316 } ) ;
259317
260318 playlist . lastRequest = Date . now ( ) ;
@@ -562,7 +620,8 @@ export default class PlaylistLoader extends EventTarget {
562620 const manifest = parseManifest ( {
563621 manifestString : req . responseText ,
564622 customTagParsers : this . customTagParsers ,
565- customTagMappers : this . customTagMappers
623+ customTagMappers : this . customTagMappers ,
624+ llhls : this . llhls
566625 } ) ;
567626
568627 this . setupInitialPlaylist ( manifest ) ;
0 commit comments