6
6
} from 'mpd-parser' ;
7
7
import {
8
8
refreshDelay ,
9
- updateMaster as updatePlaylist
9
+ updateMaster as updatePlaylist ,
10
+ isPlaylistUnchanged
10
11
} from './playlist-loader' ;
11
12
import { resolveUrl , resolveManifestRedirect } from './resolve-url' ;
12
13
import parseSidx from 'mux.js/lib/tools/parse-sidx' ;
@@ -21,6 +22,67 @@ import {toUint8} from '@videojs/vhs-utils/es/byte-helpers';
21
22
22
23
const { EventTarget, mergeOptions } = videojs ;
23
24
25
+ const dashPlaylistUnchanged = function ( a , b ) {
26
+ if ( ! isPlaylistUnchanged ( a , b ) ) {
27
+ return false ;
28
+ }
29
+
30
+ // for dash the above check will often return true in scenarios where
31
+ // the playlist actually has changed because mediaSequence isn't a
32
+ // dash thing, and we often set it to 1. So if the playlists have the same amount
33
+ // of segments we return true.
34
+ // So for dash we need to make sure that the underlying segments are different.
35
+
36
+ // if sidx changed then the playlists are different.
37
+ if ( a . sidx && b . sidx && ( a . sidx . offset !== b . sidx . offset || a . sidx . length !== b . sidx . length ) ) {
38
+ return false ;
39
+ } else if ( ( ! a . sidx && b . sidx ) || ( a . sidx && ! b . sidx ) ) {
40
+ return false ;
41
+ }
42
+
43
+ // one or the other does not have segments
44
+ // there was a change.
45
+ if ( a . segments && ! b . segments || ! a . segments && b . segments ) {
46
+ return false ;
47
+ }
48
+
49
+ // neither has segments nothing changed
50
+ if ( ! a . segments && ! b . segments ) {
51
+ return true ;
52
+ }
53
+
54
+ // check segments themselves
55
+ for ( let i = 0 ; i < a . segments . length ; i ++ ) {
56
+ const aSegment = a . segments [ i ] ;
57
+ const bSegment = b . segments [ i ] ;
58
+
59
+ // if uris are different between segments there was a change
60
+ if ( aSegment . uri !== bSegment . uri ) {
61
+ return false ;
62
+ }
63
+
64
+ // neither segment has a byterange, there will be no byterange change.
65
+ if ( ! aSegment . byterange && ! bSegment . byterange ) {
66
+ continue ;
67
+ }
68
+ const aByterange = aSegment . byterange ;
69
+ const bByterange = bSegment . byterange ;
70
+
71
+ // if byterange only exists on one of the segments, there was a change.
72
+ if ( ( aByterange && ! bByterange ) || ( ! aByterange && bByterange ) ) {
73
+ return false ;
74
+ }
75
+
76
+ // if both segments have byterange with different offsets, there was a change.
77
+ if ( aByterange . offset !== bByterange . offset || aByterange . length !== bByterange . length ) {
78
+ return false ;
79
+ }
80
+ }
81
+
82
+ // if everything was the same with segments, this is the same playlist.
83
+ return true ;
84
+ } ;
85
+
24
86
/**
25
87
* Parses the master XML string and updates playlist URI references.
26
88
*
@@ -92,7 +154,7 @@ export const updateMaster = (oldMaster, newMaster, sidxMapping) => {
92
154
addSidxSegmentsToPlaylist ( playlist , sidxMapping [ sidxKey ] . sidx , playlist . sidx . resolvedUri ) ;
93
155
}
94
156
}
95
- const playlistUpdate = updatePlaylist ( update , playlist , true ) ;
157
+ const playlistUpdate = updatePlaylist ( update , playlist , dashPlaylistUnchanged ) ;
96
158
97
159
if ( playlistUpdate ) {
98
160
update = playlistUpdate ;
@@ -104,7 +166,7 @@ export const updateMaster = (oldMaster, newMaster, sidxMapping) => {
104
166
forEachMediaGroup ( newMaster , ( properties , type , group , label ) => {
105
167
if ( properties . playlists && properties . playlists . length ) {
106
168
const id = properties . playlists [ 0 ] . id ;
107
- const playlistUpdate = updatePlaylist ( update , properties . playlists [ 0 ] , true ) ;
169
+ const playlistUpdate = updatePlaylist ( update , properties . playlists [ 0 ] , dashPlaylistUnchanged ) ;
108
170
109
171
if ( playlistUpdate ) {
110
172
update = playlistUpdate ;
0 commit comments