diff --git a/src/js/control-bar/progress-control/seek-bar.js b/src/js/control-bar/progress-control/seek-bar.js index 51cd902456..1e86dd5a7b 100644 --- a/src/js/control-bar/progress-control/seek-bar.js +++ b/src/js/control-bar/progress-control/seek-bar.js @@ -10,6 +10,7 @@ import {formatTime} from '../../utils/time.js'; import {silencePromise} from '../../utils/promise'; import keycode from 'keycode'; import document from 'global/document'; +import { merge } from '../../utils/obj.js'; import './load-progress-bar.js'; import './play-progress-bar.js'; @@ -39,7 +40,13 @@ class SeekBar extends Slider { * The key/value store of player options. */ constructor(player, options) { - super(player, options); + const options_ = merge({ + playerOptions: { + enableSmoothSeeking: false + } + }, options); + + super(player, options_); this.setEventHandlers_(); } @@ -324,6 +331,10 @@ class SeekBar extends Slider { // Set new time (tell player to seek to new time) this.userSeek_(newTime); + + if (this.options_.playerOptions.enableSmoothSeeking) { + this.update(); + } } enable() { diff --git a/src/js/control-bar/time-controls/time-display.js b/src/js/control-bar/time-controls/time-display.js index fb9a0ffeeb..38fe5b56a6 100644 --- a/src/js/control-bar/time-controls/time-display.js +++ b/src/js/control-bar/time-controls/time-display.js @@ -6,6 +6,7 @@ import Component from '../../component.js'; import * as Dom from '../../utils/dom.js'; import {formatTime} from '../../utils/time.js'; import log from '../../utils/log.js'; +import { merge } from '../../utils/obj.js'; /** * Displays time information about the video @@ -24,9 +25,21 @@ class TimeDisplay extends Component { * The key/value store of player options. */ constructor(player, options) { - super(player, options); + const options_ = merge({ + playerOptions: { + enableSmoothSeeking: false + } + }, options); + + super(player, options_); + + const types = ['timeupdate', 'ended']; + + if (options_.playerOptions.enableSmoothSeeking) { + types.push('seeking'); + } - this.on(player, ['timeupdate', 'ended'], (e) => this.updateContent(e)); + this.on(player, types, (e) => this.updateContent(e)); this.updateTextNode_(); } diff --git a/src/js/player.js b/src/js/player.js index 6927f1723e..050296fbdc 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -5255,7 +5255,9 @@ Player.prototype.options_ = { breakpoints: {}, responsive: false, audioOnlyMode: false, - audioPosterMode: false + audioPosterMode: false, + // Default smooth seeking to false + enableSmoothSeeking: false }; [ diff --git a/test/unit/player.test.js b/test/unit/player.test.js index 24830bb818..17fc02a2b2 100644 --- a/test/unit/player.test.js +++ b/test/unit/player.test.js @@ -3244,3 +3244,65 @@ QUnit.test('turning on audioPosterMode when audioOnlyMode is already on will tur assert.notOk(player.audioOnlyMode(), 'audioOnlyMode is false'); }); }); + +QUnit.test('smooth seeking set to false should not update the display time components or the seek bar', function(assert) { + const player = TestHelpers.makePlayer({}); + const { + currentTimeDisplay, + remainingTimeDisplay, + progressControl: { + seekBar + } + } = player.controlBar; + const currentTimeDisplayUpdateContent = sinon.spy(currentTimeDisplay, 'updateContent'); + const remainingTimeDisplayUpdateContent = sinon.spy(remainingTimeDisplay, 'updateContent'); + const seekBarUpdate = sinon.spy(seekBar, 'update'); + + assert.false(player.options().enableSmoothSeeking, 'enableSmoothSeeking is false by default'); + + player.trigger('seeking'); + + assert.ok(currentTimeDisplayUpdateContent.notCalled, 'currentTimeDisplay updateContent was not called'); + assert.ok(remainingTimeDisplayUpdateContent.notCalled, 'currentTimeDisplay updateContent was not called'); + + seekBar.trigger('mousedown'); + seekBar.trigger('mousemove'); + + assert.ok(seekBarUpdate.notCalled, 'seekBar update was not called'); + + currentTimeDisplayUpdateContent.restore(); + remainingTimeDisplayUpdateContent.restore(); + seekBarUpdate.restore(); + player.dispose(); +}); + +QUnit.test('smooth seeking set to true should update the display time components and the seek bar', function(assert) { + const player = TestHelpers.makePlayer({enableSmoothSeeking: true}); + const { + currentTimeDisplay, + remainingTimeDisplay, + progressControl: { + seekBar + } + } = player.controlBar; + const currentTimeDisplayUpdateContent = sinon.spy(currentTimeDisplay, 'updateContent'); + const remainingTimeDisplayUpdateContent = sinon.spy(remainingTimeDisplay, 'updateContent'); + const seekBarUpdate = sinon.spy(seekBar, 'update'); + + assert.true(player.options().enableSmoothSeeking, 'enableSmoothSeeking is true'); + + player.trigger('seeking'); + + assert.ok(currentTimeDisplayUpdateContent.called, 'currentTimeDisplay updateContent was called'); + assert.ok(remainingTimeDisplayUpdateContent.called, 'currentTimeDisplay updateContent was called'); + + seekBar.trigger('mousedown'); + seekBar.trigger('mousemove'); + + assert.ok(seekBarUpdate.called, 'seekBar update was called'); + + currentTimeDisplayUpdateContent.restore(); + remainingTimeDisplayUpdateContent.restore(); + seekBarUpdate.restore(); + player.dispose(); +});