e45497bc by Jon-Carlos Rivera

Percent buffered calculation now works correctly when the segment is not buffere…

…d and currentTime is within the segment (#715)
1 parent cc311ea3
......@@ -198,27 +198,58 @@ const bufferIntersection = function(bufferA, bufferB) {
* covers adjusted according to currentTime
* @param {TimeRanges} referenceRange - the original time range that the
* segment covers
* @param {Number} currentTime - time in seconds where the current playback
* is at
* @param {TimeRanges} buffered - the currently buffered time ranges
* @returns {Number} percent of the segment currently buffered
*/
const calculateBufferedPercent = function(segmentRange, referenceRange, buffered) {
const calculateBufferedPercent = function(adjustedRange,
referenceRange,
currentTime,
buffered) {
let referenceDuration = referenceRange.end(0) - referenceRange.start(0);
let segmentDuration = segmentRange.end(0) - segmentRange.start(0);
let intersection = bufferIntersection(segmentRange, buffered);
let count = intersection.length;
let adjustedDuration = adjustedRange.end(0) - adjustedRange.start(0);
let bufferMissingFromAdjusted = referenceDuration - adjustedDuration;
let adjustedIntersection = bufferIntersection(adjustedRange, buffered);
let referenceIntersection = bufferIntersection(referenceRange, buffered);
let adjustedOverlap = 0;
let referenceOverlap = 0;
let count = adjustedIntersection.length;
while (count--) {
segmentDuration -= intersection.end(count) - intersection.start(count);
adjustedOverlap += adjustedIntersection.end(count) -
adjustedIntersection.start(count);
// If the current overlap segment starts at currentTime, then increase the
// overlap duration so that it actually starts at the beginning of referenceRange
// by including the difference between the two Range's durations
// This is a work around for the way Flash has no buffer before currentTime
if (adjustedIntersection.start(count) === currentTime) {
adjustedOverlap += bufferMissingFromAdjusted;
}
}
return (referenceDuration - segmentDuration) / referenceDuration * 100;
count = referenceIntersection.length;
while (count--) {
referenceOverlap += referenceIntersection.end(count) -
referenceIntersection.start(count);
}
// Use whichever value is larger for the percentage-buffered since that value
// is likely more accurate because the only way
return Math.max(adjustedOverlap, referenceOverlap) / referenceDuration * 100;
};
/**
* Return the amount of a segment specified by the mediaIndex overlaps
* the current buffered content.
* Return the amount of a range specified by the startOfSegment and segmentDuration
* overlaps the current buffered content.
*
* @param {Number} startOfSegment - the time where the segment begins
* @param {Number} segmentDuration - the duration of the segment in seconds
* @param {Number} currentTime - time in seconds where the current playback
* is at
* @param {TimeRanges} buffered - the state of the buffer
* @returns {Number} percentage of the segment's time range that is
* already in `buffered`
......@@ -254,6 +285,7 @@ const getSegmentBufferedPercent = function(startOfSegment,
let percent = calculateBufferedPercent(adjustedSegmentRange,
originalSegmentRange,
currentTime,
buffered);
// If the segment is reported as having a zero duration, return 0%
......
......@@ -94,7 +94,7 @@ QUnit.test('detects time range end-point changed by updates', function() {
QUnit.module('Segment Percent Buffered Calculations');
QUnit.test('calculates the percent buffered for segments', function() {
QUnit.test('calculates the percent buffered for segments in the simple case', function() {
let segmentStart = 10;
let segmentDuration = 10;
let currentTime = 0;
......@@ -108,8 +108,8 @@ QUnit.test('calculates the percent buffered for segments', function() {
QUnit.equal(percentBuffered, 40, 'calculated the buffered amount correctly');
});
QUnit.test('calculates the percent buffered for segments taking into account ' +
'currentTime', function() {
QUnit.test('consider the buffer before currentTime to be filled if the segement begins at ' +
'or before the currentTime', function() {
let segmentStart = 10;
let segmentDuration = 10;
let currentTime = 15;
......@@ -123,6 +123,21 @@ QUnit.test('calculates the percent buffered for segments taking into account ' +
QUnit.equal(percentBuffered, 90, 'calculated the buffered amount correctly');
});
QUnit.test('does not consider the buffer before currentTime as filled if the segment ' +
'begins after the currentTime', function() {
let segmentStart = 10;
let segmentDuration = 10;
let currentTime = 18;
let buffered = createTimeRanges([[19, 30]]);
let percentBuffered = Ranges.getSegmentBufferedPercent(
segmentStart,
segmentDuration,
currentTime,
buffered);
QUnit.equal(percentBuffered, 10, 'calculated the buffered amount correctly');
});
QUnit.test('calculates the percent buffered for segments with multiple buffered ' +
'regions', function() {
let segmentStart = 10;
......@@ -166,3 +181,32 @@ QUnit.test('calculates the percent buffered as 0 for zero-length segments', func
QUnit.equal(percentBuffered, 0, 'calculated the buffered amount correctly');
});
QUnit.test('calculates the percent buffered as 0 for segments that do not overlap ' +
'buffered regions taking into account currentTime', function() {
let segmentStart = 10;
let segmentDuration = 10;
let currentTime = 19;
let buffered = createTimeRanges([[20, 30]]);
let percentBuffered = Ranges.getSegmentBufferedPercent(
segmentStart,
segmentDuration,
currentTime,
buffered);
QUnit.equal(percentBuffered, 0, 'calculated the buffered amount correctly');
});
QUnit.test('calculates the percent buffered for segments that end before currentTime', function() {
let segmentStart = 10;
let segmentDuration = 10;
let currentTime = 19.6;
let buffered = createTimeRanges([[0, 19.5]]);
let percentBuffered = Ranges.getSegmentBufferedPercent(
segmentStart,
segmentDuration,
currentTime,
buffered);
QUnit.equal(percentBuffered, 95, 'calculated the buffered amount correctly');
});
......