From d2fecc5cd74a1278a69ed60e0799025a77082409 Mon Sep 17 00:00:00 2001 From: Rob Walch Date: Thu, 8 Oct 2020 17:51:37 -0400 Subject: [PATCH 1/3] Merge pull request #3063 from netTrekfd/bugfix/subtitle-loading-after-stopload Bugfix for subtitle loading after hls.stopload() was used (cherry picked from commit c579fea5359851d9b059b0d2a5dc3276eeb25c10) --- src/controller/subtitle-stream-controller.js | 42 +++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/controller/subtitle-stream-controller.js b/src/controller/subtitle-stream-controller.js index 65b8d68b297..6d4984ce04e 100644 --- a/src/controller/subtitle-stream-controller.js +++ b/src/controller/subtitle-stream-controller.js @@ -40,6 +40,18 @@ export class SubtitleStreamController extends BaseStreamController { this._onMediaSeeking = this.onMediaSeeking.bind(this); } + startLoad () { + this.stopLoad(); + this.state = State.IDLE; + + // Check if we already have a track with necessary details to load fragments + const currentTrack = this.tracks[this.currentTrackId]; + if (currentTrack && currentTrack.details) { + this.setInterval(TICK_INTERVAL); + this.tick(); + } + } + onSubtitleFragProcessed (data) { const { frag, success } = data; this.fragPrevious = frag; @@ -103,6 +115,11 @@ export class SubtitleStreamController extends BaseStreamController { if (!frag || frag.type !== 'subtitle') { return; } + + if (this.fragCurrent && this.fragCurrent.loader) { + this.fragCurrent.loader.abort(); + } + this.state = State.IDLE; } @@ -237,6 +254,7 @@ export class SubtitleStreamController extends BaseStreamController { stopLoad () { this.lastAVStart = 0; + this.fragPrevious = null; super.stopLoad(); } @@ -245,6 +263,28 @@ export class SubtitleStreamController extends BaseStreamController { } onMediaSeeking () { - this.fragPrevious = null; + if (this.fragCurrent) { + const currentTime = this.media ? this.media.currentTime : null; + const tolerance = this.config.maxFragLookUpTolerance; + const fragStartOffset = this.fragCurrent.start - tolerance; + const fragEndOffset = this.fragCurrent.start + this.fragCurrent.duration + tolerance; + + // check if position will be out of currently loaded frag range after seeking : if out, cancel frag load, if in, don't do anything + if (currentTime < fragStartOffset || currentTime > fragEndOffset) { + if (this.fragCurrent.loader) { + this.fragCurrent.loader.abort(); + } + + this.fragmentTracker.removeFragment(this.fragCurrent); + this.fragCurrent = null; + this.fragPrevious = null; + + // switch to IDLE state to load new fragment + this.state = State.IDLE; + + // speed up things + this.tick(); + } + } } } From aa75370f02b0dd90d0f9f7b39117c104468f0bd3 Mon Sep 17 00:00:00 2001 From: Rob Walch Date: Thu, 8 Oct 2020 18:05:27 -0400 Subject: [PATCH 2/3] Fix test failing with #3063 (cherry picked from commit a6943fc55b149897ba8cdaad85c236272bbfd4cd) --- src/controller/subtitle-stream-controller.js | 2 +- tests/unit/controller/subtitle-stream-controller.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/controller/subtitle-stream-controller.js b/src/controller/subtitle-stream-controller.js index 6d4984ce04e..360a2e2db6c 100644 --- a/src/controller/subtitle-stream-controller.js +++ b/src/controller/subtitle-stream-controller.js @@ -264,7 +264,7 @@ export class SubtitleStreamController extends BaseStreamController { onMediaSeeking () { if (this.fragCurrent) { - const currentTime = this.media ? this.media.currentTime : null; + const currentTime = this.media ? this.media.currentTime : 0; const tolerance = this.config.maxFragLookUpTolerance; const fragStartOffset = this.fragCurrent.start - tolerance; const fragEndOffset = this.fragCurrent.start + this.fragCurrent.duration + tolerance; diff --git a/tests/unit/controller/subtitle-stream-controller.js b/tests/unit/controller/subtitle-stream-controller.js index 37c33a13887..27ec3f85952 100644 --- a/tests/unit/controller/subtitle-stream-controller.js +++ b/tests/unit/controller/subtitle-stream-controller.js @@ -130,7 +130,8 @@ describe('SubtitleStreamController', function () { }); describe('onMediaSeeking', function () { - it('nulls fragPrevious', function () { + it('nulls fragPrevious when seeking away from fragCurrent', function () { + subtitleStreamController.fragCurrent = { start: 1000, duration: 10 }; subtitleStreamController.fragPrevious = {}; subtitleStreamController.onMediaSeeking(); expect(subtitleStreamController.fragPrevious).to.not.exist; From f4a86e411977834ebca934313447c5c88c692b22 Mon Sep 17 00:00:00 2001 From: Rob Walch Date: Thu, 8 Oct 2020 17:25:02 -0400 Subject: [PATCH 3/3] Handle PTS rollover on initial sample of video or audio #3082 (cherry picked from commit 1c57a0908c546ef3abdc33862828f1b67e407448) --- src/remux/mp4-remuxer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/remux/mp4-remuxer.js b/src/remux/mp4-remuxer.js index 545f754ccfd..3260aad4d7e 100644 --- a/src/remux/mp4-remuxer.js +++ b/src/remux/mp4-remuxer.js @@ -52,7 +52,7 @@ class MP4Remuxer { } else { return sample.pts; } - }, videoSamples[0].pts); + }, PTSNormalize(videoSamples[0].pts, 0)); if (rolloverDetected) { logger.debug('PTS rollover detected'); } @@ -76,7 +76,7 @@ class MP4Remuxer { // when providing timeOffset to remuxAudio / remuxVideo. if we don't do that, there might be a permanent / small // drift between audio and video streams const startPTS = this.getVideoStartPts(videoTrack.samples); - const tsDelta = audioTrack.samples[0].pts - startPTS; + const tsDelta = PTSNormalize(audioTrack.samples[0].pts, 0) - startPTS; const audiovideoTimestampDelta = tsDelta / videoTrack.inputTimeScale; audioTimeOffset += Math.max(0, audiovideoTimestampDelta); videoTimeOffset += Math.max(0, -audiovideoTimestampDelta); @@ -190,7 +190,7 @@ class MP4Remuxer { if (computePTSDTS) { const startPTS = this.getVideoStartPts(videoSamples); const startOffset = Math.round(inputTimeScale * timeOffset); - initDTS = Math.min(initDTS, videoSamples[0].dts - startOffset); + initDTS = Math.min(initDTS, PTSNormalize(videoSamples[0].dts, 0) - startOffset); initPTS = Math.min(initPTS, startPTS - startOffset); this.observer.trigger(Event.INIT_PTS_FOUND, { initPTS }); }