Skip to content

Commit

Permalink
feat: support suggestedPresentationDelay in DASH manifests (#698)
Browse files Browse the repository at this point in the history
  • Loading branch information
gkatsev authored Feb 4, 2020
1 parent 8b3bcff commit c14fb43
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 26 deletions.
66 changes: 51 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"aes-decrypter": "3.0.0",
"global": "^4.3.0",
"m3u8-parser": "4.4.0",
"mpd-parser": "0.8.1",
"mpd-parser": "0.10.0",
"mux.js": "5.4.0",
"url-toolkit": "^2.1.3",
"video.js": "^6.8.0 || ^7.0.0"
Expand Down
6 changes: 4 additions & 2 deletions src/master-playlist-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,9 @@ export class MasterPlaylistController extends videojs.EventTarget {
return;
}

mainSeekable = Hls.Playlist.seekable(media, expired);
const suggestedPresentationDelay = this.masterPlaylistLoader_.master.suggestedPresentationDelay

mainSeekable = Hls.Playlist.seekable(media, expired, suggestedPresentationDelay);

if (mainSeekable.length === 0) {
return;
Expand All @@ -951,7 +953,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
return;
}

audioSeekable = Hls.Playlist.seekable(media, expired);
audioSeekable = Hls.Playlist.seekable(media, expired, suggestedPresentationDelay);

if (audioSeekable.length === 0) {
return;
Expand Down
39 changes: 31 additions & 8 deletions src/playlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,21 +216,36 @@ export const sumDurations = function(playlist, startIndex, endIndex) {
* window which is the duration of the last segment plus 2 target durations from the end
* of the playlist.
*
* A liveEdgePadding can be provided which will be used instead of calculating the safe live edge.
* This corresponds to suggestedPresentationDelay in DASH manifests.
*
* @param {Object} playlist
* a media playlist object
* @param {Number} [liveEdgePadding]
* A number in seconds indicating how far from the end we want to be.
* If provided, this value is used instead of calculating the safe live index from the target durations.
* Corresponds to suggestedPresentationDelay in DASH manifests.
* @return {Number}
* The media index of the segment at the safe live point. 0 if there is no "safe"
* point.
* @function safeLiveIndex
*/
export const safeLiveIndex = function(playlist) {
export const safeLiveIndex = function(playlist, liveEdgePadding) {
if (!playlist.segments.length) {
return 0;
}

let i = playlist.segments.length - 1;
let distanceFromEnd = playlist.segments[i].duration || playlist.targetDuration;
const safeDistance = distanceFromEnd + playlist.targetDuration * 2;
let i = playlist.segments.length;
let lastSegmentDuration = playlist.segments[i - 1].duration || playlist.targetDuration;
const safeDistance = typeof liveEdgePadding === 'number' ?
liveEdgePadding :
lastSegmentDuration + playlist.targetDuration * 2;

if (safeDistance === 0) {
return i;
}

let distanceFromEnd = 0;

while (i--) {
distanceFromEnd += playlist.segments[i].duration;
Expand All @@ -253,10 +268,16 @@ export const safeLiveIndex = function(playlist) {
* playlist end calculation should consider the safe live end
* (truncate the playlist end by three segments). This is normally
* used for calculating the end of the playlist's seekable range.
* This takes into account the value of liveEdgePadding.
* Setting liveEdgePadding to 0 is equivalent to setting this to false.
* @param {Number} liveEdgePadding a number indicating how far from the end of the playlist we should be in seconds.
* If this is provided, it is used in the safe live end calculation.
* Setting useSafeLiveEnd=false or liveEdgePadding=0 are equivalent.
* Corresponds to suggestedPresentationDelay in DASH manifests.
* @returns {Number} the end time of playlist
* @function playlistEnd
*/
export const playlistEnd = function(playlist, expired, useSafeLiveEnd) {
export const playlistEnd = function(playlist, expired, useSafeLiveEnd, liveEdgePadding) {
if (!playlist || !playlist.segments) {
return null;
}
Expand All @@ -270,7 +291,7 @@ export const playlistEnd = function(playlist, expired, useSafeLiveEnd) {

expired = expired || 0;

const endSequence = useSafeLiveEnd ? safeLiveIndex(playlist) : playlist.segments.length;
const endSequence = useSafeLiveEnd ? safeLiveIndex(playlist, liveEdgePadding) : playlist.segments.length;

return intervalDuration(playlist,
playlist.mediaSequence + endSequence,
Expand All @@ -289,13 +310,15 @@ export const playlistEnd = function(playlist, expired, useSafeLiveEnd) {
* dropped off the front of the playlist in a live scenario
* @param {Number=} expired the amount of time that has
* dropped off the front of the playlist in a live scenario
* @param {Number} liveEdgePadding how far from the end of the playlist we should be in seconds.
* Corresponds to suggestedPresentationDelay in DASH manifests.
* @return {TimeRanges} the periods of time that are valid targets
* for seeking
*/
export const seekable = function(playlist, expired) {
export const seekable = function(playlist, expired, liveEdgePadding) {
let useSafeLiveEnd = true;
let seekableStart = expired || 0;
let seekableEnd = playlistEnd(playlist, expired, useSafeLiveEnd);
let seekableEnd = playlistEnd(playlist, expired, useSafeLiveEnd, liveEdgePadding);

if (seekableEnd === null) {
return createTimeRange();
Expand Down
2 changes: 2 additions & 0 deletions test/master-playlist-controller.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1839,6 +1839,7 @@ function(assert) {
let mainTimeRanges = [];
let audioTimeRanges = [];

this.masterPlaylistController.masterPlaylistLoader_.master = {};
this.masterPlaylistController.masterPlaylistLoader_.media = () => mainMedia;
this.masterPlaylistController.syncController_.getExpiredTime = () => 0;

Expand Down Expand Up @@ -1973,6 +1974,7 @@ function(assert) {
Playlist.seekable = () => {
return videojs.createTimeRanges(mainTimeRanges);
};
this.masterPlaylistController.masterPlaylistLoader_.master = {};
this.masterPlaylistController.masterPlaylistLoader_.media = () => media;
this.masterPlaylistController.syncController_.getExpiredTime = () => 0;

Expand Down
Loading

0 comments on commit c14fb43

Please sign in to comment.