Skip to content
This repository was archived by the owner on Jan 12, 2019. It is now read-only.

Commit 016d82f

Browse files
mjneildmlap
authored andcommitted
Use specified mediasequence for VOD expired sync instead of assuming 0 (#1097)
* use specified mediasequence for VOD expired sync instead of assuming 0 * use synccontroller for expired * target sync-point by index for expired instead of time 0 * minor fixes * add vod test for expired
1 parent 4daa28f commit 016d82f

File tree

6 files changed

+437
-137
lines changed

6 files changed

+437
-137
lines changed

src/master-playlist-controller.js

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,9 +1085,15 @@ export class MasterPlaylistController extends videojs.EventTarget {
10851085
return false;
10861086
}
10871087

1088+
let expired = this.syncController_.getExpiredTime(playlist, this.mediaSource.duration);
1089+
1090+
if (expired === null) {
1091+
return false;
1092+
}
1093+
10881094
// does not use the safe live end to calculate playlist end, since we
10891095
// don't want to say we are stuck while there is still content
1090-
let absolutePlaylistEnd = Hls.Playlist.playlistEnd(playlist);
1096+
let absolutePlaylistEnd = Hls.Playlist.playlistEnd(playlist, expired);
10911097
let currentTime = this.tech_.currentTime();
10921098
let buffered = this.tech_.buffered();
10931099

@@ -1251,27 +1257,42 @@ export class MasterPlaylistController extends videojs.EventTarget {
12511257
}
12521258

12531259
onSyncInfoUpdate_() {
1254-
let media;
12551260
let mainSeekable;
12561261
let audioSeekable;
12571262

12581263
if (!this.masterPlaylistLoader_) {
12591264
return;
12601265
}
12611266

1262-
media = this.masterPlaylistLoader_.media();
1267+
let media = this.masterPlaylistLoader_.media();
12631268

12641269
if (!media) {
12651270
return;
12661271
}
12671272

1268-
mainSeekable = Hls.Playlist.seekable(media);
1273+
let expired = this.syncController_.getExpiredTime(media, this.mediaSource.duration);
1274+
1275+
if (expired === null) {
1276+
// not enough information to update seekable
1277+
return;
1278+
}
1279+
1280+
mainSeekable = Hls.Playlist.seekable(media, expired);
1281+
12691282
if (mainSeekable.length === 0) {
12701283
return;
12711284
}
12721285

12731286
if (this.audioPlaylistLoader_) {
1274-
audioSeekable = Hls.Playlist.seekable(this.audioPlaylistLoader_.media());
1287+
media = this.audioPlaylistLoader_.media();
1288+
expired = this.syncController_.getExpiredTime(media, this.mediaSource.duration);
1289+
1290+
if (expired === null) {
1291+
return;
1292+
}
1293+
1294+
audioSeekable = Hls.Playlist.seekable(media, expired);
1295+
12751296
if (audioSeekable.length === 0) {
12761297
return;
12771298
}

src/playlist.js

Lines changed: 11 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -219,118 +219,33 @@ export const sumDurations = function(playlist, startIndex, endIndex) {
219219
return durations;
220220
};
221221

222-
/**
223-
* Returns an array with two sync points. The first being an expired sync point, which is
224-
* the most recent segment with timing sync data that has fallen off the playlist. The
225-
* second is a segment sync point, which is the first segment that has timing sync data in
226-
* the current playlist.
227-
*
228-
* @param {Object} playlist a media playlist object
229-
* @returns {Object} an object containing the two sync points
230-
* @returns {Object.expiredSync|null} sync point data from an expired segment
231-
* @returns {Object.segmentSync|null} sync point data from a segment in the playlist
232-
* @function getPlaylistSyncPoints
233-
*/
234-
const getPlaylistSyncPoints = function(playlist) {
235-
if (!playlist || !playlist.segments) {
236-
return [null, null];
237-
}
238-
let expiredSync = playlist.syncInfo || (playlist.endList ? { time: 0, mediaSequence: 0} : null);
239-
let segmentSync = null;
240-
241-
// Find the first segment with timing information
242-
for (let i = 0, l = playlist.segments.length; i < l; i++) {
243-
let segment = playlist.segments[i];
244-
245-
if (typeof segment.start !== 'undefined') {
246-
segmentSync = {
247-
mediaSequence: playlist.mediaSequence + i,
248-
time: segment.start
249-
};
250-
break;
251-
}
252-
}
253-
254-
return { expiredSync, segmentSync };
255-
};
256-
257-
/**
258-
* Calculates the amount of time expired from the playlist based on the provided
259-
* sync points.
260-
*
261-
* @param {Object} playlist a media playlist object
262-
* @param {Object|null} expiredSync sync point representing most recent segment with
263-
* timing sync data that has fallen off the playlist
264-
* @param {Object|null} segmentSync sync point representing the first segment that has
265-
* timing sync data in the playlist
266-
* @returns {Number} the amount of time expired from the playlist
267-
* @function calculateExpiredTime
268-
*/
269-
const calculateExpiredTime = function(playlist) {
270-
// If we have both an expired sync point and a segment sync point
271-
// determine which sync point is closest to the start of the playlist
272-
// so the minimal amount of timing estimation is done.
273-
let { expiredSync, segmentSync } = getPlaylistSyncPoints(playlist);
274-
275-
if (expiredSync && segmentSync) {
276-
let expiredDiff = expiredSync.mediaSequence - playlist.mediaSequence;
277-
let segmentDiff = segmentSync.mediaSequence - playlist.mediaSequence;
278-
let syncIndex;
279-
let syncTime;
280-
281-
if (Math.abs(expiredDiff) > Math.abs(segmentDiff)) {
282-
syncIndex = segmentDiff;
283-
syncTime = -segmentSync.time;
284-
} else {
285-
syncIndex = expiredDiff;
286-
syncTime = expiredSync.time;
287-
}
288-
289-
return Math.abs(syncTime + sumDurations(playlist, syncIndex, 0));
290-
}
291-
292-
// We only have an expired sync point, so base expired time on the expired sync point
293-
// and estimate the time from that sync point to the start of the playlist.
294-
if (expiredSync) {
295-
let syncIndex = expiredSync.mediaSequence - playlist.mediaSequence;
296-
297-
return expiredSync.time + sumDurations(playlist, syncIndex, 0);
298-
}
299-
300-
// We only have a segment sync point, so base expired time on the first segment we have
301-
// sync point data for and estimate the time from that media index to the start of the
302-
// playlist.
303-
if (segmentSync) {
304-
let syncIndex = segmentSync.mediaSequence - playlist.mediaSequence;
305-
306-
return segmentSync.time - sumDurations(playlist, syncIndex, 0);
307-
}
308-
return null;
309-
};
310-
311222
/**
312223
* Calculates the playlist end time
313224
*
314225
* @param {Object} playlist a media playlist object
226+
* @param {Number=} expired the amount of time that has
227+
* dropped off the front of the playlist in a live scenario
315228
* @param {Boolean|false} useSafeLiveEnd a boolean value indicating whether or not the playlist
316229
* end calculation should consider the safe live end (truncate the playlist
317230
* end by three segments). This is normally used for calculating the end of
318231
* the playlist's seekable range.
319232
* @returns {Number} the end time of playlist
320233
* @function playlistEnd
321234
*/
322-
export const playlistEnd = function(playlist, useSafeLiveEnd) {
235+
export const playlistEnd = function(playlist, expired, useSafeLiveEnd) {
323236
if (!playlist || !playlist.segments) {
324237
return null;
325238
}
326239
if (playlist.endList) {
327240
return duration(playlist);
328241
}
329-
let expired = calculateExpiredTime(playlist);
330242

331243
if (expired === null) {
332244
return null;
333245
}
246+
247+
expired = expired || 0;
248+
334249
let endSequence = useSafeLiveEnd ? Math.max(0, playlist.segments.length - Playlist.UNSAFE_LIVE_SEGMENTS) :
335250
Math.max(0, playlist.segments.length);
336251

@@ -349,13 +264,15 @@ export const playlistEnd = function(playlist, useSafeLiveEnd) {
349264
*
350265
* @param {Object} playlist a media playlist object
351266
* dropped off the front of the playlist in a live scenario
267+
* @param {Number=} expired the amount of time that has
268+
* dropped off the front of the playlist in a live scenario
352269
* @return {TimeRanges} the periods of time that are valid targets
353270
* for seeking
354271
*/
355-
export const seekable = function(playlist) {
272+
export const seekable = function(playlist, expired) {
356273
let useSafeLiveEnd = true;
357-
let seekableStart = calculateExpiredTime(playlist);
358-
let seekableEnd = playlistEnd(playlist, useSafeLiveEnd);
274+
let seekableStart = expired || 0;
275+
let seekableEnd = playlistEnd(playlist, expired, useSafeLiveEnd);
359276

360277
if (seekableEnd === null) {
361278
return createTimeRange();

0 commit comments

Comments
 (0)