Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Seek bar smooth seeking #8287

Merged

Conversation

amtins
Copy link
Contributor

@amtins amtins commented May 21, 2023

Description

This PR adds a player option called enableSmoothSeeking, which is false by default, to provide a smoother seeking experience on mobile and desktop devices.

player-smooth-seek.webm

This PR includes the fix #8285 and should fix #8283.

How to use it?

// Enables the smooth seeking
const player = videojs('player', {enableSmoothSeeking: true});

// Disable the smooth seeking
player.options({enableSmoothSeeking: false});

Specific Changes proposed

  • player.js add an option called enableSmoothSeeking
  • time-display.js add a listener to the seeking event if enableSmoothSeeking is true allowing to update the CurrentTimeDisplay and RemainingTimeDisplay in real time
  • seek-bar.js update the seek bar on mousemove event if enableSmoothSeeking is true
  • add test cases
  • refer to fix(player): cache_.currentTime is not updated when the current time is set #8285 for the player.currentTime modification

Benchmark

The number of calls to the update method when the player is playing versus when seeking with smooth seeking enabled. The test was performed 10 times in a row and consisted of a counter that incremented by one on each call. It was inserted in the anonymous function provided to requestNamedAnimationFrame of the update method.

The duration of each round was 5 seconds. The enableInterval_ it started when the play button was clicked and stopped at the end of the setTimeout. The handleMouseMove it started on the mousedown, then was followed by frantic movement on the seek bar and stopped at the end of the setTimeout.

enableInterval_ handleMouseMove
Round 1 142 114
Round 2 144 133
Round 3 145 126
Round 4 152 114
Round 5 144 122
Round 6 150 119
Round 7 146 112
Round 8 155 133
Round 9 144 131
Round 10 133 121

Requirements Checklist

  • Feature implemented / Bug fixed
  • If necessary, more likely in a feature request than a bug fix
    • Change has been verified in an actual browser (Chrome, Firefox, IE)
    • Unit Tests updated or fixed
    • Docs/guides updated
    • Example created (starter template on JSBin)
  • Reviewed by Two Core Contributors

@amtins amtins changed the title Feat seek bar smooth seeking Seek bar smooth seeking May 21, 2023
@amtins amtins marked this pull request as draft May 21, 2023 10:17
@codecov
Copy link

codecov bot commented May 21, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (7972c23) 82.71% compared to head (5b8b883) 82.77%.
Report is 11 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8287      +/-   ##
==========================================
+ Coverage   82.71%   82.77%   +0.05%     
==========================================
  Files         113      113              
  Lines        7592     7600       +8     
  Branches     1826     1829       +3     
==========================================
+ Hits         6280     6291      +11     
+ Misses       1312     1309       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@amtins amtins marked this pull request as ready for review May 21, 2023 10:52
@amtins
Copy link
Contributor Author

amtins commented May 21, 2023

Observation

@amtins amtins changed the title Seek bar smooth seeking feat: Seek bar smooth seeking May 21, 2023
Copy link
Contributor

@mister-ben mister-ben left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good and is more in line with other players' behaviour. Thanks!. One observation is that you no longer have an indication of where you were in the video when you started seeking, if that matters.

@mister-ben mister-ben added the needs: LGTM Needs one or more additional approvals label May 23, 2023
Copy link
Member

@gkatsev gkatsev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At first, I was worried about this change because the original reason we didn't update this is that internally we are still seeking directly and basically relying on it for the preview and we were worried about the potential jump it a seek failed and the mismatch between the preview and the seek bar. However, at least on desktop, it seems to be working well enough and I actually think this behavior feels a bit better. Keeping it as an option (and perhaps enabling it by default later on) makes sense to me, though, still.

Overall, this looks good to me, but I had one suggestion about the option.

Comment on lines 43 to 49
const options_ = merge({
playerOptions: {
enableSmoothSeeking: false
}
}, options);

super(player, options_);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while it makes sense for this to be a player option, I think that rather than setting a default player option here, we should have it be translated into a seek-bar option called enableSmoothSeeking.

Maybe something like this (I didn't verify this works)

Suggested change
const options_ = merge({
playerOptions: {
enableSmoothSeeking: false
}
}, options);
super(player, options_);
const opts = merge({
enableSmoothSeeking: options.playerOptions.enableSmoothSeeking ?? false
}, options);
super(player, opts);

Then below, it could use this.options_.enableSmoothSeeking

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the alternative would be to always do this.player().options().enableSmoothSeeking (then someone could more easily update this on the fly and won't need to drill down to the seek bar via player.controlBar.progressControl.seekBar.options_.playerOptions.enableSmoothSeeking = true, which I had to do to test this out. However, I think making it a seek-bar option is fine and makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gkatsev thanks for the suggestion.

I guess the alternative would be to always do this.player().options().enableSmoothSeeking (then someone could more easily update this on the fly and won't need to drill down to the seek bar

Your suggestion is much better because it offers a nicer developer experience.

Here's what the changes could look like:

seek-bar.js

  constructor(player, options) {
    super(player, options);
    this.setEventHandlers_();
  }

  handleMouseMove(event, mouseDown = false) {
     // ...
     if (this.player_.options_.enableSmoothSeeking) {
      this.update();
    }
  }

time-display.js

  constructor(player, options) {
    super(player, options);

    this.on(player, ['timeupdate', 'ended', 'seeking'], (e) => this.update(e));
    this.updateTextNode_();
  }

  update(event) {
    if (!this.player_.options_.enableSmoothSeeking && event.type === 'seeking') {
      return;
    }

    this.updateContent(event);
  }

These changes remove merge options, reducing the number of lines of code to maintain. As a result, a developer will be able to toggle the smooth seeking on the fly:

player.options({enableSmoothSeeking : true});
player.options({enableSmoothSeeking : false});

Finally, relying directly on player options is something already done for other components: clickable-component, live-tracker, poster-image and picture-in-picture-toggle.

What do you think about these changes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me!

Copy link
Contributor Author

@amtins amtins Jun 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@misteroneill thank you for the feedback, I'll try to make the changes by the end of the week.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed the changes. However, I don't see where I can add the documentation for this new option.

@gkatsev
Copy link
Member

gkatsev commented May 24, 2023

Also, appreciate all the PRs you've been opening, thanks!

@amtins
Copy link
Contributor Author

amtins commented May 26, 2023

Also, appreciate all the PRs you've been opening, thanks!

@gkatsev thank you all for taking the time to review these PRs, and if it benefits the community, all the better.

@misteroneill misteroneill added needs: updates and removed needs: LGTM Needs one or more additional approvals labels Jun 1, 2023
@misteroneill
Copy link
Member

Echoing what @gkatsev said, it's a huge help and great to see such active contribution from a community member! Thanks!

@amtins amtins force-pushed the feat/seek-bar-smooth-seeking branch 2 times, most recently from 11de73b to 396e196 Compare June 2, 2023 20:15
…is set

Updating cache_.currentTime as soon as the currentTime is set avoids having to wait for the timeupdate event, which results in:

- making cache_.currentTime more reliable
- updating the progress bar on mouse up after dragging when the media is paused.

See also: videojs#6232, videojs#6234, videojs#6370, videojs#6372
Adds a player option called enableSmoothSeeking, which is false by default,
to provide a smoother seeking experience on mobile and desktop devices.

Usage:
```javascript
// Enables the smooth seeking
const player = videojs('player', {enableSmoothSeeking: true});

// Disable the smooth seeking
player.options({enableSmoothSeeking: false});
```

- **player.js** add an `option` called `enableSmoothSeeking`
- **time-display.js** add a listener to the `seeking` event if `enableSmoothSeeking` is `true` allowing to update the `CurrentTimeDisplay` and `RemainingTimeDisplay` in real time
- **seek-bar.js** `update` the seek bar on `mousemove` event  if `enableSmoothSeeking` is `true`
- add test cases
@mister-ben
Copy link
Contributor

Should this still have the needs-updates tag?

@amtins
Copy link
Contributor Author

amtins commented Dec 14, 2023

@mister-ben I've implemented @gkatsev's suggestions (thanks again), which improves the developer experience. From my point of view, it looks like everything has been addressed.

@mister-ben mister-ben added minor This PR can be added to a minor release. It should not be added to a patch release. and removed needs: updates labels Dec 14, 2023
@mister-ben
Copy link
Contributor

Great, let's get this merged before the next minor release then. We'll need to add it to the options guide in the videos.com repo too.

@amtins amtins mentioned this pull request Dec 16, 2023
7 tasks
@dzianis-dashkevich dzianis-dashkevich merged commit 608a585 into videojs:main Jan 2, 2024
10 checks passed
amtins added a commit to amtins/videojs.com that referenced this pull request Jan 7, 2024
Documents the `enableSmoothSeeking` option introduced in videojs 8.9.0.

Refers videojs/video.js#8287
@phloxic phloxic mentioned this pull request Jan 18, 2024
5 tasks
mister-ben pushed a commit to videojs/videojs.com that referenced this pull request Feb 3, 2024
Documents the `enableSmoothSeeking` option introduced in videojs 8.9.0.

Refers videojs/video.js#8287
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
minor This PR can be added to a minor release. It should not be added to a patch release.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Slider does not follow the mouse.
5 participants