This repository has been archived by the owner on Jan 12, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 793
More duration updates #339
Closed
Closed
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
97587b6
Fix possible seek issues in content where segment preciseDuration is …
mikrohard e6b6334
recalculate currentTime whenever seeking
dmlap 33dab8e
pull apart segmentsDuration
dmlap 83a1a33
calculate duration from the longest time range with PTS information
dmlap a2a57c3
Remove timestampOffset
dmlap a49772b
Remove getCurrentTimeByMediaIndex_
dmlap File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,130 @@ | |
'use strict'; | ||
|
||
var DEFAULT_TARGET_DURATION = 10; | ||
var duration, seekable, segmentsDuration; | ||
var accumulateDuration, ascendingNumeric, duration, intervalDuration, rangeDuration, seekable; | ||
|
||
// Array.sort comparator to sort numbers in ascending order | ||
ascendingNumeric = function(left, right) { | ||
return left - right; | ||
}; | ||
|
||
/** | ||
* Returns the media duration for the segments between a start and | ||
* exclusive end index. The start and end parameters are interpreted | ||
* as indices into the currently available segments. This method | ||
* does not calculate durations for segments that have expired. | ||
* @param playlist {object} a media playlist object | ||
* @param start {number} an inclusive lower boundary for the | ||
* segments to examine. | ||
* @param end {number} an exclusive upper boundary for the segments | ||
* to examine. | ||
* @param includeTrailingTime {boolean} if false, the interval between | ||
* the final segment and the subsequent segment will not be included | ||
* in the result | ||
* @return {number} the duration between the start index and end | ||
* index in seconds. | ||
*/ | ||
accumulateDuration = function(playlist, start, end, includeTrailingTime) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so all this stuff tries to find those overlapping ranges of audio and video durations and take the greatest of them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically, yes. It tries to find the longest span of segments that have PTS info available at the start and end. It does this by:
|
||
var | ||
ranges = [], | ||
rangeEnds = (playlist.discontinuityStarts || []).concat(end), | ||
result = 0, | ||
i; | ||
|
||
// short circuit if start and end don't specify a non-empty range | ||
// of segments | ||
if (start >= end) { | ||
return 0; | ||
} | ||
|
||
// create a range object for each discontinuity sequence | ||
rangeEnds.sort(ascendingNumeric); | ||
for (i = 0; i < rangeEnds.length; i++) { | ||
if (rangeEnds[i] > start) { | ||
ranges.push({ start: start, end: rangeEnds[i] }); | ||
i++; | ||
break; | ||
} | ||
} | ||
for (; i < rangeEnds.length; i++) { | ||
// ignore times ranges later than end | ||
if (rangeEnds[i] >= end) { | ||
ranges.push({ start: rangeEnds[i - 1], end: end }); | ||
break; | ||
} | ||
ranges.push({ start: ranges[ranges.length - 1].end, end: rangeEnds[i] }); | ||
} | ||
|
||
// add up the durations for each of the ranges | ||
for (i = 0; i < ranges.length; i++) { | ||
result += rangeDuration(playlist, | ||
ranges[i], | ||
i === ranges.length - 1 && includeTrailingTime); | ||
} | ||
|
||
return result; | ||
}; | ||
|
||
/** | ||
* Returns the duration of the specified range of segments. The | ||
* range *must not* cross a discontinuity. | ||
* @param playlist {object} a media playlist object | ||
* @param range {object} an object that specifies a starting and | ||
* ending index into the available segments. | ||
* @param includeTrailingTime {boolean} if false, the interval between | ||
* the final segment and the subsequent segment will not be included | ||
* in the result | ||
* @return {number} the duration of the range in seconds. | ||
*/ | ||
rangeDuration = function(playlist, range, includeTrailingTime) { | ||
var | ||
result = 0, | ||
targetDuration = playlist.targetDuration || DEFAULT_TARGET_DURATION, | ||
segment, | ||
left, right; | ||
|
||
// accumulate while searching for the earliest segment with | ||
// available PTS information | ||
for (left = range.start; left < range.end; left++) { | ||
segment = playlist.segments[left]; | ||
if (segment.minVideoPts !== undefined) { | ||
break; | ||
} | ||
result += segment.duration || targetDuration; | ||
} | ||
|
||
// see if there's enough information to include the trailing time | ||
if (includeTrailingTime) { | ||
segment = playlist.segments[range.end]; | ||
if (segment && segment.minVideoPts !== undefined) { | ||
result += 0.001 * | ||
(Math.min(segment.minVideoPts, segment.minAudioPts) - | ||
Math.min(playlist.segments[left].minVideoPts, | ||
playlist.segments[left].minAudioPts)); | ||
return result; | ||
} | ||
} | ||
|
||
// do the same thing while finding the latest segment | ||
for (right = range.end - 1; right >= left; right--) { | ||
segment = playlist.segments[right]; | ||
if (segment.maxVideoPts !== undefined) { | ||
break; | ||
} | ||
result += segment.duration || targetDuration; | ||
} | ||
|
||
// add in the PTS interval in seconds between them | ||
if (right >= left) { | ||
result += 0.001 * | ||
(Math.max(playlist.segments[right].maxVideoPts, | ||
playlist.segments[right].maxAudioPts) - | ||
Math.min(playlist.segments[left].minVideoPts, | ||
playlist.segments[left].minAudioPts)); | ||
} | ||
|
||
return result; | ||
}; | ||
|
||
/** | ||
* Calculate the media duration from the segments associated with a | ||
|
@@ -17,47 +140,28 @@ | |
* boundary for the playlist. Defaults to 0. | ||
* @param endSequence {number} (optional) an exclusive upper boundary | ||
* for the playlist. Defaults to playlist length. | ||
* @param includeTrailingTime {boolean} if false, the interval between | ||
* the final segment and the subsequent segment will not be included | ||
* in the result | ||
* @return {number} the duration between the start index and end | ||
* index. | ||
*/ | ||
segmentsDuration = function(playlist, startSequence, endSequence) { | ||
var targetDuration, i, j, segment, endSegment, expiredSegmentCount, result = 0; | ||
intervalDuration = function(playlist, startSequence, endSequence, includeTrailingTime) { | ||
var result = 0, targetDuration, expiredSegmentCount; | ||
|
||
startSequence = startSequence || 0; | ||
i = startSequence; | ||
endSequence = endSequence !== undefined ? endSequence : (playlist.segments || []).length; | ||
targetDuration = playlist.targetDuration || DEFAULT_TARGET_DURATION; | ||
|
||
// estimate expired segment duration using the target duration | ||
expiredSegmentCount = Math.max(playlist.mediaSequence - startSequence, 0); | ||
result += expiredSegmentCount * targetDuration; | ||
i += expiredSegmentCount; | ||
|
||
// accumulate the segment durations into the result | ||
for (; i < endSequence; i++) { | ||
segment = playlist.segments[i - playlist.mediaSequence]; | ||
|
||
// when PTS values aren't available, use information from the playlist | ||
if (segment.minVideoPts === undefined) { | ||
result += segment.duration || | ||
targetDuration; | ||
continue; | ||
} | ||
|
||
// find the last segment with PTS info and use that to calculate | ||
// the interval duration | ||
for(j = i; j < endSequence - 1; j++) { | ||
endSegment = playlist.segments[j - playlist.mediaSequence + 1]; | ||
if (endSegment.maxVideoPts === undefined || | ||
endSegment.discontinuity) { | ||
break; | ||
} | ||
} | ||
endSegment = playlist.segments[j - playlist.mediaSequence]; | ||
result += (Math.max(endSegment.maxVideoPts, endSegment.maxAudioPts) - | ||
Math.min(segment.minVideoPts, segment.minAudioPts)) * 0.001; | ||
i = j; | ||
} | ||
result += accumulateDuration(playlist, | ||
startSequence + expiredSegmentCount - playlist.mediaSequence, | ||
endSequence - playlist.mediaSequence, | ||
includeTrailingTime); | ||
|
||
return result; | ||
}; | ||
|
@@ -72,14 +176,21 @@ | |
* boundary for the playlist. Defaults to 0. | ||
* @param endSequence {number} (optional) an exclusive upper boundary | ||
* for the playlist. Defaults to playlist length. | ||
* @param includeTrailingTime {boolean} (optional) if false, the interval between | ||
* the final segment and the subsequent segment will not be included | ||
* in the result | ||
* @return {number} the duration between the start index and end | ||
* index. | ||
*/ | ||
duration = function(playlist, startSequence, endSequence) { | ||
duration = function(playlist, startSequence, endSequence, includeTrailingTime) { | ||
if (!playlist) { | ||
return 0; | ||
} | ||
|
||
if (includeTrailingTime === undefined) { | ||
includeTrailingTime = true; | ||
} | ||
|
||
// if a slice of the total duration is not requested, use | ||
// playlist-level duration indicators when they're present | ||
if (startSequence === undefined && endSequence === undefined) { | ||
|
@@ -95,9 +206,10 @@ | |
} | ||
|
||
// calculate the total duration based on the segment durations | ||
return segmentsDuration(playlist, | ||
return intervalDuration(playlist, | ||
startSequence, | ||
endSequence); | ||
endSequence, | ||
includeTrailingTime); | ||
}; | ||
|
||
/** | ||
|
@@ -119,8 +231,8 @@ | |
return videojs.createTimeRange(0, duration(playlist)); | ||
} | ||
|
||
start = segmentsDuration(playlist, 0, playlist.mediaSequence); | ||
end = start + segmentsDuration(playlist, | ||
start = intervalDuration(playlist, 0, playlist.mediaSequence); | ||
end = start + intervalDuration(playlist, | ||
playlist.mediaSequence, | ||
playlist.mediaSequence + playlist.segments.length); | ||
targetDuration = playlist.targetDuration || DEFAULT_TARGET_DURATION; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so
discontinuityStarts
end up being a list of indexes pointing at segments that begin a discontinuity?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. It makes splitting intervals into continuous spans a lot simpler.