Skip to content

Commit

Permalink
cr
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonocasey committed Feb 11, 2021
1 parent 3a8d013 commit ba36f53
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 59 deletions.
68 changes: 65 additions & 3 deletions src/dash-playlist-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
} from 'mpd-parser';
import {
refreshDelay,
updateMaster as updatePlaylist
updateMaster as updatePlaylist,
isPlaylistUnchanged
} from './playlist-loader';
import { resolveUrl, resolveManifestRedirect } from './resolve-url';
import parseSidx from 'mux.js/lib/tools/parse-sidx';
Expand All @@ -21,6 +22,67 @@ import {toUint8} from '@videojs/vhs-utils/es/byte-helpers';

const { EventTarget, mergeOptions } = videojs;

const dashPlaylistUnchanged = function(a, b) {
if (!isPlaylistUnchanged(a, b)) {
return false;
}

// for dash the above check will often return true in scenarios where
// the playlist actually has changed because mediaSequence isn't a
// dash thing, and we often set it to 1. So if the playlists have the same amount
// of segments we return true.
// So for dash we need to make sure that the underlying segments are different.

// if sidx changed then the playlists are different.
if (a.sidx && b.sidx && (a.sidx.offset !== b.sidx.offset || a.sidx.length !== b.sidx.length)) {
return false;
} else if ((!a.sidx && b.sidx) || (a.sidx && !b.sidx)) {
return false;
}

// one or the other does not have segments
// there was a change.
if (a.segments && !b.segments || !a.segments && b.segments) {
return false;
}

// neither has segments nothing changed
if (!a.segments && !b.segments) {
return true;
}

// check segments themselves
for (let i = 0; i < a.segments.length; i++) {
const aSegment = a.segments[i];
const bSegment = b.segments[i];

// if uris are different between segments there was a change
if (aSegment.uri !== bSegment.uri) {
return false;
}

// neither segment has a byterange, there will be no byterange change.
if (!aSegment.byterange && !bSegment.byterange) {
continue;
}
const aByterange = aSegment.byterange;
const bByterange = bSegment.byterange;

// if byterange only exists on one of the segments, there was a change.
if ((aByterange && !bByterange) || (!aByterange && bByterange)) {
return false;
}

// if both segments have byterange with different offsets, there was a change.
if (aByterange.offset !== bByterange.offset || aByterange.length !== bByterange.length) {
return false;
}
}

// if everything was the same with segments, this is the same playlist.
return true;
};

/**
* Parses the master XML string and updates playlist URI references.
*
Expand Down Expand Up @@ -92,7 +154,7 @@ export const updateMaster = (oldMaster, newMaster, sidxMapping) => {
addSidxSegmentsToPlaylist(playlist, sidxMapping[sidxKey].sidx, playlist.sidx.resolvedUri);
}
}
const playlistUpdate = updatePlaylist(update, playlist, true);
const playlistUpdate = updatePlaylist(update, playlist, dashPlaylistUnchanged);

if (playlistUpdate) {
update = playlistUpdate;
Expand All @@ -104,7 +166,7 @@ export const updateMaster = (oldMaster, newMaster, sidxMapping) => {
forEachMediaGroup(newMaster, (properties, type, group, label) => {
if (properties.playlists && properties.playlists.length) {
const id = properties.playlists[0].id;
const playlistUpdate = updatePlaylist(update, properties.playlists[0], true);
const playlistUpdate = updatePlaylist(update, properties.playlists[0], dashPlaylistUnchanged);

if (playlistUpdate) {
update = playlistUpdate;
Expand Down
66 changes: 10 additions & 56 deletions src/playlist-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ export const resolveSegmentUris = (segment, baseUri) => {
}
};

// consider the playlist unchanged if the playlist object is the same or
// the number of segments is equal, the media sequence number is unchanged,
// and this playlist hasn't become the end of the playlist
export const isPlaylistUnchanged = (a, b) => a === b ||
(a.segments && b.segments && a.segments.length === b.segments.length &&
a.endList === b.endList &&
a.mediaSequence === b.mediaSequence);

/**
* Returns a new master playlist that is the result of merging an
* updated media playlist into the original version. If the
Expand All @@ -69,69 +77,15 @@ export const resolveSegmentUris = (segment, baseUri) => {
* master playlist with the updated media playlist merged in, or
* null if the merge produced no change.
*/
export const updateMaster = (master, media, dash = false) => {
export const updateMaster = (master, media, unchangedCheck = isPlaylistUnchanged) => {
const result = mergeOptions(master, {});
const playlist = result.playlists[media.id];

if (!playlist) {
return null;
}

// consider the playlist unchanged if the number of segments is equal, the media
// sequence number is unchanged, and this playlist hasn't become the end of the playlist
let unchanged = playlist.segments &&
media.segments &&
playlist.segments.length === media.segments.length &&
playlist.endList === media.endList &&
playlist.mediaSequence === media.mediaSequence;

// for dash mediaSequence and segment lengths will often match as
// mediaSequence is almost always 1 and the number of segments generated for a
// given time is often the same. So we need to make sure that the underlying segments are
// different.
if (dash && unchanged) {
const oldSidx = playlist.sidx;
const newSidx = media.sidx;

// if sidx changed then the playlists are different.
if (oldSidx && newSidx && (oldSidx.offset !== newSidx.offset || oldSidx.length !== newSidx.length)) {
unchanged = false;
} else if ((!oldSidx && newSidx) || (oldSidx && !newSidx)) {
unchanged = false;
} else {
for (let i = 0; i < playlist.segments.length; i++) {
const oldSegment = playlist.segments[i];
const newSegment = media.segments[i];

// if uris are different between segments there was a change
if (oldSegment.uri !== newSegment.uri) {
unchanged = false;
continue;
}

// neither segment has a byternage, there will be no byterange change.
if (!oldSegment.byterange && !newSegment.byterange) {
continue;
}
const oldByterange = oldSegment.byterange;
const newByterange = newSegment.byterange;

// if byterange only exists on one of the segments, there was a change.
if ((oldByterange && !newByterange) || (!oldByterange && newByterange)) {
unchanged = false;
continue;
}

// if both segments have byterange with different offsets, there was a change.
if (oldByterange.offset !== newByterange.offset || oldByterange.length !== newByterange.length) {
unchanged = false;
continue;
}
}
}
}

if (unchanged) {
if (unchangedCheck(playlist, media)) {
return null;
}

Expand Down

0 comments on commit ba36f53

Please sign in to comment.