From 7477bd87635568a5564cab3d22bb97943be538b6 Mon Sep 17 00:00:00 2001 From: brandonocasey Date: Thu, 25 Mar 2021 15:10:50 -0400 Subject: [PATCH] fix: correct playlist end logic for live playlists --- src/playlist.js | 16 +++++++++++----- src/sync-controller.js | 21 +++++++++++++++------ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/playlist.js b/src/playlist.js index 59a236157..05f648cfb 100644 --- a/src/playlist.js +++ b/src/playlist.js @@ -37,6 +37,7 @@ const backwardDuration = function(playlist, endSequence) { }; } } + while (i--) { segment = playlist.segments[i]; if (typeof segment.end !== 'undefined') { @@ -104,7 +105,7 @@ const forwardDuration = function(playlist, endSequence) { */ const intervalDuration = function(playlist, endSequence, expired) { if (typeof endSequence === 'undefined') { - endSequence = playlist.mediaSequence + playlist.segments.length; + endSequence = playlist.mediaSequence + (playlist.segments.length - 1); } if (endSequence < playlist.mediaSequence) { @@ -293,13 +294,18 @@ export const playlistEnd = function(playlist, expired, useSafeLiveEnd, liveEdgeP expired = expired || 0; - const endSequence = useSafeLiveEnd ? safeLiveIndex(playlist, liveEdgePadding) : playlist.segments.length; - - return intervalDuration( + let lastSegmentTime = intervalDuration( playlist, - playlist.mediaSequence + endSequence, + playlist.mediaSequence + playlist.segments.length - 1, expired ); + + if (useSafeLiveEnd) { + liveEdgePadding = typeof liveEdgePadding === 'number' ? liveEdgePadding : playlist.targetDuration * 3; + lastSegmentTime -= (playlist.targetDuration * 3); + } + + return lastSegmentTime; }; /** diff --git a/src/sync-controller.js b/src/sync-controller.js index 9c215b613..b90878e47 100644 --- a/src/sync-controller.js +++ b/src/sync-controller.js @@ -6,6 +6,12 @@ import {sumDurations} from './playlist'; import videojs from 'video.js'; import logger from './util/logger'; +const getSegmentIndex = (i, playlist, currentTime = 0) => { + const segments = playlist.segments; + + return (playlist.endList || currentTime === 0) ? i : segments.length - (i + 1); +}; + export const syncPointStrategies = [ // Stategy "VOD": Handle the VOD-case where the sync-point is *always* // the equivalence display-time 0 === segment-index 0 @@ -38,7 +44,8 @@ export const syncPointStrategies = [ currentTime = currentTime || 0; for (let i = 0; i < segments.length; i++) { - const segment = segments[i]; + const segmentIndex = getSegmentIndex(i, playlist, currentTime); + const segment = segments[segmentIndex]; const datetimeMapping = syncController.timelineToDatetimeMappings[segment.timeline]; @@ -49,21 +56,23 @@ export const syncPointStrategies = [ if (segment.dateTimeObject) { const segmentTime = segment.dateTimeObject.getTime() / 1000; const segmentStart = segmentTime + datetimeMapping; + const distance = Math.abs(currentTime - segmentStart); // Once the distance begins to increase, or if distance is 0, we have passed // currentTime and can stop looking for better candidates - if (lastDistance !== null && (distance === 0 || lastDistance < distance)) { + if (lastDistance !== null && lastDistance < distance) { break; } lastDistance = distance; syncPoint = { time: segmentStart, - segmentIndex: i + segmentIndex }; } } + return syncPoint; } }, @@ -79,7 +88,8 @@ export const syncPointStrategies = [ currentTime = currentTime || 0; for (let i = 0; i < segments.length; i++) { - const segment = segments[i]; + const segmentIndex = getSegmentIndex(i, playlist, currentTime); + const segment = segments[segmentIndex]; if (segment.timeline === currentTimeline && typeof segment.start !== 'undefined') { @@ -95,10 +105,9 @@ export const syncPointStrategies = [ lastDistance = distance; syncPoint = { time: segment.start, - segmentIndex: i + segmentIndex }; } - } } return syncPoint;