Skip to content

Commit

Permalink
bugfix/ll-hls-endofstream: Add check for at least one part for endofs…
Browse files Browse the repository at this point in the history
…tream partList check. Add tests. Create simple mock for TimeRanges for tests.
  • Loading branch information
cjpillsbury committed Jan 20, 2022
1 parent 604bdac commit 1de06e9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/controller/base-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export default class BaseStreamController
) {
const partList = (levelDetails as LevelDetails).partList;
// Since the last part isn't guaranteed to correspond to fragCurrent for ll-hls, check instead if the last part is buffered.
if (partList) {
if (partList && partList.length) {
const lastPart = partList[partList.length - 1];

// Checking the midpoint of the part for potential margin of error and related issues.
Expand Down
36 changes: 36 additions & 0 deletions tests/mocks/time-ranges.mock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const assertValidRange = (name, length, index) => {
if (index >= length || index < 0) {
throw new DOMException(
`Failed to execute '${name}' on 'TimeRanges': The index provided (${index}) is greater than the maximum bound (${length}).`
);
}
return true;
};

export class TimeRangesMock {
_ranges = [];

// Accepts an argument list of [start, end] tuples or { start: number, end: number } objects
constructor(...ranges) {
this._ranges = ranges.map((range) =>
Array.isArray(range) ? range : [range.start, range.end]
);
}

get length() {
const { _ranges: ranges } = this;
return ranges.length;
}

start(i) {
const { _ranges: ranges, length } = this;
assertValidRange('start', length, i);
return ranges[i] && ranges[i][0];
}

end(i) {
const { _ranges: ranges, length } = this;
assertValidRange('end', length, i);
return ranges[i] && ranges[i][1];
}
}
21 changes: 21 additions & 0 deletions tests/unit/controller/base-stream-controller.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BaseStreamController from '../../../src/controller/stream-controller';
import Hls from '../../../src/hls';
import { FragmentState } from '../../../src/controller/fragment-tracker';
import { TimeRangesMock } from '../../mocks/time-ranges.mock';

describe('BaseStreamController', function () {
let baseStreamController;
Expand Down Expand Up @@ -75,5 +76,25 @@ describe('BaseStreamController', function () {
`fragState is ${fragmentTracker.getState()}, expecting OK`
).to.be.true;
});

it('returns true if parts are buffered for low latency content', function () {
media.buffered = new TimeRangesMock([0, 1]);
baseStreamController.fragCurrent = { sn: 10 };
levelDetails.endSN = 10;
levelDetails.partList = [{ start: 0, duration: 1 }];

expect(baseStreamController._streamEnded(bufferInfo, levelDetails)).to.be
.true;
});

it('returns true even if fragCurrent is after the last fragment due to low latency content modeling', function () {
media.buffered = new TimeRangesMock([0, 1]);
baseStreamController.fragCurrent = { sn: 11 };
levelDetails.endSN = 10;
levelDetails.partList = [{ start: 0, duration: 1 }];

expect(baseStreamController._streamEnded(bufferInfo, levelDetails)).to.be
.true;
});
});
});

0 comments on commit 1de06e9

Please sign in to comment.