Skip to content

Commit

Permalink
Merge pull request video-dev#3852 from video-dev/bugfix/async-frag-lo…
Browse files Browse the repository at this point in the history
…ad-abort-loop

Prevent async abort handler from causing current fragment to be reloaded
  • Loading branch information
robwalch authored May 4, 2021
2 parents 46d12a3 + cb34a0f commit 5134f43
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 9 deletions.
16 changes: 10 additions & 6 deletions src/controller/base-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,10 @@ export default class BaseStreamController
const fragStartOffset = fragCurrent.start - tolerance;
const fragEndOffset =
fragCurrent.start + fragCurrent.duration + tolerance;
// check if the seek position will be out of currently loaded frag range : if out cancel frag load, if in, don't do anything
if (currentTime < fragStartOffset || currentTime > fragEndOffset) {
if (fragCurrent.loader) {
const pastFragment = currentTime > fragEndOffset;
// check if the seek position is past current fragment, and if so abort loading
if (currentTime < fragStartOffset || pastFragment) {
if (pastFragment && fragCurrent.loader) {
this.log(
'seeking outside of buffer while fragment load in progress, cancel fragment load'
);
Expand All @@ -226,8 +227,8 @@ export default class BaseStreamController
this.nextLoadPosition = this.startPosition = currentTime;
}

// tick to speed up processing
this.tick();
// Async tick to speed up processing
this.tickImmediate();
}

protected onMediaEnded() {
Expand Down Expand Up @@ -356,6 +357,9 @@ export default class BaseStreamController
endOffset: number,
type: SourceBufferName | null = null
) {
if (!(startOffset - endOffset)) {
return;
}
// When alternate audio is playing, the audio-stream-controller is responsible for the audio buffer. Otherwise,
// passing a null type flushes both buffers
const flushScope: BufferFlushingData = { startOffset, endOffset, type };
Expand Down Expand Up @@ -1111,7 +1115,7 @@ export default class BaseStreamController
}

private handleFragLoadAborted(frag: Fragment, part: Part | undefined) {
if (this.transmuxer && frag.sn !== 'initSegment') {
if (this.transmuxer && frag.sn !== 'initSegment' && frag.stats.aborted) {
this.warn(
`Fragment ${frag.sn}${part ? ' part' + part.index : ''} of level ${
frag.level
Expand Down
8 changes: 6 additions & 2 deletions src/task-loop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,17 @@ export default class TaskLoop {
// -> schedule a call on the next main loop iteration to process this task processing request
if (this._tickCallCount > 1) {
// make sure only one timer exists at any time at max
this.clearNextTick();
this._tickTimer = self.setTimeout(this._boundTick, 0);
this.tickImmediate();
}
this._tickCallCount = 0;
}
}

public tickImmediate(): void {
this.clearNextTick();
this._tickTimer = self.setTimeout(this._boundTick, 0);
}

/**
* For subclass to implement task logic
* @abstract
Expand Down
14 changes: 13 additions & 1 deletion tests/unit/controller/subtitle-stream-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ describe('SubtitleStreamController', function () {

beforeEach(function () {
hls = new Hls({});
mediaMock.currentTime = 0;
fragmentTracker = new FragmentTracker(hls);
subtitleStreamController = new SubtitleStreamController(
hls,
Expand Down Expand Up @@ -126,7 +127,18 @@ describe('SubtitleStreamController', function () {

describe('onMediaSeeking', function () {
it('nulls fragPrevious when seeking away from fragCurrent', function () {
subtitleStreamController.fragCurrent = { start: 1000, duration: 10 };
subtitleStreamController.fragCurrent = {
start: 1000,
duration: 10,
loader: {
abort: () => {
this.state.aborted = true;
},
stats: {
aborted: false,
},
},
};
subtitleStreamController.fragPrevious = {};
subtitleStreamController.onMediaSeeking();
expect(subtitleStreamController.fragPrevious).to.not.exist;
Expand Down

0 comments on commit 5134f43

Please sign in to comment.