Skip to content

Commit ba36f53

Browse files
committed
cr
1 parent 3a8d013 commit ba36f53

File tree

2 files changed

+75
-59
lines changed

2 files changed

+75
-59
lines changed

src/dash-playlist-loader.js

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
} from 'mpd-parser';
77
import {
88
refreshDelay,
9-
updateMaster as updatePlaylist
9+
updateMaster as updatePlaylist,
10+
isPlaylistUnchanged
1011
} from './playlist-loader';
1112
import { resolveUrl, resolveManifestRedirect } from './resolve-url';
1213
import parseSidx from 'mux.js/lib/tools/parse-sidx';
@@ -21,6 +22,67 @@ import {toUint8} from '@videojs/vhs-utils/es/byte-helpers';
2122

2223
const { 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;

src/playlist-loader.js

Lines changed: 10 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ export const resolveSegmentUris = (segment, baseUri) => {
5757
}
5858
};
5959

60+
// consider the playlist unchanged if the playlist object is the same or
61+
// the number of segments is equal, the media sequence number is unchanged,
62+
// and this playlist hasn't become the end of the playlist
63+
export const isPlaylistUnchanged = (a, b) => a === b ||
64+
(a.segments && b.segments && a.segments.length === b.segments.length &&
65+
a.endList === b.endList &&
66+
a.mediaSequence === b.mediaSequence);
67+
6068
/**
6169
* Returns a new master playlist that is the result of merging an
6270
* updated media playlist into the original version. If the
@@ -69,69 +77,15 @@ export const resolveSegmentUris = (segment, baseUri) => {
6977
* master playlist with the updated media playlist merged in, or
7078
* null if the merge produced no change.
7179
*/
72-
export const updateMaster = (master, media, dash = false) => {
80+
export const updateMaster = (master, media, unchangedCheck = isPlaylistUnchanged) => {
7381
const result = mergeOptions(master, {});
7482
const playlist = result.playlists[media.id];
7583

7684
if (!playlist) {
7785
return null;
7886
}
7987

80-
// consider the playlist unchanged if the number of segments is equal, the media
81-
// sequence number is unchanged, and this playlist hasn't become the end of the playlist
82-
let unchanged = playlist.segments &&
83-
media.segments &&
84-
playlist.segments.length === media.segments.length &&
85-
playlist.endList === media.endList &&
86-
playlist.mediaSequence === media.mediaSequence;
87-
88-
// for dash mediaSequence and segment lengths will often match as
89-
// mediaSequence is almost always 1 and the number of segments generated for a
90-
// given time is often the same. So we need to make sure that the underlying segments are
91-
// different.
92-
if (dash && unchanged) {
93-
const oldSidx = playlist.sidx;
94-
const newSidx = media.sidx;
95-
96-
// if sidx changed then the playlists are different.
97-
if (oldSidx && newSidx && (oldSidx.offset !== newSidx.offset || oldSidx.length !== newSidx.length)) {
98-
unchanged = false;
99-
} else if ((!oldSidx && newSidx) || (oldSidx && !newSidx)) {
100-
unchanged = false;
101-
} else {
102-
for (let i = 0; i < playlist.segments.length; i++) {
103-
const oldSegment = playlist.segments[i];
104-
const newSegment = media.segments[i];
105-
106-
// if uris are different between segments there was a change
107-
if (oldSegment.uri !== newSegment.uri) {
108-
unchanged = false;
109-
continue;
110-
}
111-
112-
// neither segment has a byternage, there will be no byterange change.
113-
if (!oldSegment.byterange && !newSegment.byterange) {
114-
continue;
115-
}
116-
const oldByterange = oldSegment.byterange;
117-
const newByterange = newSegment.byterange;
118-
119-
// if byterange only exists on one of the segments, there was a change.
120-
if ((oldByterange && !newByterange) || (!oldByterange && newByterange)) {
121-
unchanged = false;
122-
continue;
123-
}
124-
125-
// if both segments have byterange with different offsets, there was a change.
126-
if (oldByterange.offset !== newByterange.offset || oldByterange.length !== newByterange.length) {
127-
unchanged = false;
128-
continue;
129-
}
130-
}
131-
}
132-
}
133-
134-
if (unchanged) {
88+
if (unchangedCheck(playlist, media)) {
13589
return null;
13690
}
13791

0 commit comments

Comments
 (0)