From 1eac68f7c558d0b5fc8e1e150598f5b775e750ff Mon Sep 17 00:00:00 2001 From: vlazh Date: Thu, 14 Mar 2024 23:07:37 +0600 Subject: [PATCH] fix: Fix playback stuck on initial gap (#6340) Fixes #6339 --- karma.conf.js | 1 + lib/player.js | 12 ++++++++++ test/player_integration.js | 13 +++++++++++ test/test/assets/6339/a.mp4 | Bin 0 -> 28800 bytes test/test/assets/6339/master.mpd | 37 +++++++++++++++++++++++++++++++ test/test/assets/6339/v.mp4 | Bin 0 -> 73980 bytes 6 files changed, 63 insertions(+) create mode 100644 test/test/assets/6339/a.mp4 create mode 100644 test/test/assets/6339/master.mpd create mode 100644 test/test/assets/6339/v.mp4 diff --git a/karma.conf.js b/karma.conf.js index 6574d2dd09..542c5c73f2 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -235,6 +235,7 @@ module.exports = (config) => { {pattern: 'test/test/assets/*', included: false}, {pattern: 'test/test/assets/dash-multi-codec/*', included: false}, {pattern: 'test/test/assets/3675/*', included: false}, + {pattern: 'test/test/assets/6339/*', included: false}, {pattern: 'test/test/assets/dash-aes-128/*', included: false}, {pattern: 'test/test/assets/hls-raw-aac/*', included: false}, {pattern: 'test/test/assets/hls-raw-ac3/*', included: false}, diff --git a/lib/player.js b/lib/player.js index e0dfdc95e4..ef5dbe7bc0 100644 --- a/lib/player.js +++ b/lib/player.js @@ -6099,6 +6099,18 @@ shaka.Player = class extends shaka.util.FakeEventTarget { // change. if (this.playhead_) { this.playhead_.notifyOfBufferingChange(); + // Skip the initial buffer gap + const startTime = this.mediaSourceEngine_.bufferStart(contentType); + if ( + !this.isLive() && + // If not paused then GapJumpingController will handle this gap. + this.video_.paused && + startTime != null && + startTime > 0 && + this.playhead_.getTime() < startTime + ) { + this.playhead_.setStartTime(startTime); + } } this.pollBufferState_(); diff --git a/test/player_integration.js b/test/player_integration.js index b4cbdce984..abea298d70 100644 --- a/test/player_integration.js +++ b/test/player_integration.js @@ -1382,4 +1382,17 @@ describe('Player', () => { expect(thumbnails.length).toBe(3); }); }); // describe('addThumbnailsTrack') + + describe('buffer gap', () => { + // Regression test for issue #6339. + it('skip initial buffer gap', async () => { + if (window.ManagedMediaSource) { + pending('Skipping test, only runs on MSE'); + } + // Ensure the video has loaded. + await player.load('/base/test/test/assets/6339/master.mpd'); + await waiter.timeoutAfter(10).waitForEvent(video, 'loadeddata'); + expect(video.currentTime).toBeGreaterThanOrEqual(0); + }); + }); }); diff --git a/test/test/assets/6339/a.mp4 b/test/test/assets/6339/a.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..cd2d1af4676eec2bf0304998a37905c17f4ea11e GIT binary patch literal 28800 zcmeHPzi-n(6uvk=D5XfIN~N?)B?Cb)Ath>2*&>7lh!HUXgPU{IsJ^(euMsdYG9t0E zvlNLxA_IQ{6H6Bc{s0D~@}8YEPKZn0E%tY+Gc;-jl8$#^@vP4*TOc-yb-A?QL1lNGz?#c3-+qSoT=;`d!L512xrnLq_tt z^c~LUz>l+X=)2Y^{yEUQF2!F2Iv7t1mw8GP#}CYb(@`*l$&u)h#cd~${NkdxP9LRf z?KMt_lUIC|ja9Q!;4wA>9ga_!8Kr~HI6?O+b^SJ$<|x(acrn?I8aS_6uAJxED=SMbS@kk)jb^=Dr5X6yGdAD_+Ru=KmDz(I;>*C1=V_n>QhX@7% zngA<+739qdh}cx;kR~EW#-CKA$@of`Xb=HEB~4$b?fPN>B?t}XDXs&RO(ssj1K>g4 z@Blgworlh!VFd|ZrXrD_bY7-1``_kznc!i9mu-P`pi%`{f*%b&L^x7m1+W6Pf&`94 zzeA+tNJ~|4Bygbx;zDsJQalchbjDXIWWnbEp98EQS5}a~k;Px# literal 0 HcmV?d00001 diff --git a/test/test/assets/6339/master.mpd b/test/test/assets/6339/master.mpd new file mode 100644 index 0000000000..1f259f04ad --- /dev/null +++ b/test/test/assets/6339/master.mpd @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/test/assets/6339/v.mp4 b/test/test/assets/6339/v.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..49df181c379c76e1d5a3606cc95bfd8f822e560a GIT binary patch literal 73980 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