66} from 'mpd-parser' ;
77import {
88 refreshDelay ,
9- updateMaster as updatePlaylist
9+ updateMaster as updatePlaylist ,
10+ isPlaylistUnchanged
1011} from './playlist-loader' ;
1112import { resolveUrl , resolveManifestRedirect } from './resolve-url' ;
1213import parseSidx from 'mux.js/lib/tools/parse-sidx' ;
@@ -21,6 +22,67 @@ import {toUint8} from '@videojs/vhs-utils/es/byte-helpers';
2122
2223const { EventTarget, mergeOptions } = videojs ;
2324
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+
2486/**
2587 * Parses the master XML string and updates playlist URI references.
2688 *
@@ -92,7 +154,7 @@ export const updateMaster = (oldMaster, newMaster, sidxMapping) => {
92154 addSidxSegmentsToPlaylist ( playlist , sidxMapping [ sidxKey ] . sidx , playlist . sidx . resolvedUri ) ;
93155 }
94156 }
95- const playlistUpdate = updatePlaylist ( update , playlist , true ) ;
157+ const playlistUpdate = updatePlaylist ( update , playlist , dashPlaylistUnchanged ) ;
96158
97159 if ( playlistUpdate ) {
98160 update = playlistUpdate ;
@@ -104,7 +166,7 @@ export const updateMaster = (oldMaster, newMaster, sidxMapping) => {
104166 forEachMediaGroup ( newMaster , ( properties , type , group , label ) => {
105167 if ( properties . playlists && properties . playlists . length ) {
106168 const id = properties . playlists [ 0 ] . id ;
107- const playlistUpdate = updatePlaylist ( update , properties . playlists [ 0 ] , true ) ;
169+ const playlistUpdate = updatePlaylist ( update , properties . playlists [ 0 ] , dashPlaylistUnchanged ) ;
108170
109171 if ( playlistUpdate ) {
110172 update = playlistUpdate ;
0 commit comments