Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[video_player] Increase seeking performance #5145

Closed
wants to merge 4 commits into from

Conversation

henri2h
Copy link

@henri2h henri2h commented Apr 1, 2022

This PR prevents calling the seekTo functions when the player is already buffering due to a previous seekTo call, this should enhance the seeking experience by not blocking the preview.

Fix: flutter/flutter#101409

What does it do ?

To prevent the issue described in the related PR, we want to limit the number of buffer not leading to an image being displayed.
In order to do this, we just ignore seekTo calls when the player is not ready to play.

What if we ask for the final location when the preview is buffering ?

This is the reason we store the asked position when we ignore the seekTo call, thus,
when the play is ready, i.e. it has displayed the new frame, we check if the user have asked for a final location
and render it if needed.

This allow to keep the player responsive even if multiple locations have been asked really quickly.

Try proposed fix

Result

With optimisation Without
screen-20220331-182056 screen-20220331-181554
schnell langsam

List which issues are fixed by this PR. You must list at least one issue.

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the relevant style guides and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/plugins repo does use dart format.)
  • I signed the CLA.
  • The title of the PR starts with the name of the plugin surrounded by square brackets, e.g. [shared_preferences]
  • I listed at least one issue that this PR fixes in the description above.
  • I updated pubspec.yaml with an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.
  • I updated CHANGELOG.md to add a description of the change, following repository CHANGELOG style.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!).

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@google-cla
Copy link

google-cla bot commented Apr 1, 2022

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

For more information, open the CLA check for this pull request.

@henri2h henri2h changed the title Draft: [video_player] Increase seeking performance draft: [video_player] Increase seeking performance Apr 1, 2022
@henri2h henri2h changed the title draft: [video_player] Increase seeking performance Draft: [video_player] Increase seeking performance Apr 1, 2022
@henri2h henri2h changed the title Draft: [video_player] Increase seeking performance [video_player] Increase seeking performance Apr 1, 2022
@henri2h
Copy link
Author

henri2h commented Apr 1, 2022

For the tests, not sure how to test this :(

@stuartmorgan
Copy link
Contributor

This PR prevents calling the seekTo functions when the player is already buffering due to a previous seekTo call, this should enhance the seeking experience by not blocking the preview.

Could you elaborate on how this is desirable? If someone seeks to position A, then immediately to position B, why would waiting until buffering is complete at position A to update the seek position when anything buffered at A isn't going to be used?

I recommend filing an issue about the underlying issue, since more discussion is needed and it's not obvious that this is the right solution.

@henri2h
Copy link
Author

henri2h commented Apr 6, 2022

This PR prevents calling the seekTo functions when the player is already buffering due to a previous seekTo call, this should enhance the seeking experience by not blocking the preview.

Could you elaborate on how this is desirable? If someone seeks to position A, then immediately to position B, why would waiting until buffering is complete at position A to update the seek position when anything buffered at A isn't going to be used?

I recommend filing an issue about the underlying issue, since more discussion is needed and it's not obvious that this is the right solution.

  • create issue
  • better explain the proposed solution

@stuartmorgan
Copy link
Contributor

I'm confused about the relationship between the issue description and the PR. In the issue you describe the problem being about when the video renders, but here you're waiting on the buffer status. Those aren't the same thing. If the goal is to wait for a single frame to render before seeking again, why are you waiting for buffering to finish? Unless I'm missing something this will make seeking incredibly sluggish on slow network connections, and do a lot of pointless buffering (per my earlier comment).

@henri2h
Copy link
Author

henri2h commented Apr 8, 2022

Yes, you're right, I confused rendering and buffering in my explanation of the issue.

However, the player doesn't wait for the buffer to be full to generate the STATE_READY event (and in our case, unlocking the seekTo function).
playback-state-changes

I'm listening for this event, because, as far as I know, it's the only way to know that something has been paint on the screen.

Maybe, we could add a timeout function to unlock the seekTo function if the player didn't manage to buffer enough to be ready to play due to bad network connection ?

Concerning the pointless buffering, depends on what the user is doing

  • when the user seek location A, then B immediately, then, yes, the player is going to wait for the player to be ready before seeking to the next position. However, the timeout may help fix this issue to prevent the amount which will be buffered.
  • when the user is scrolling through the video, the player is just constantly trying to buffer and discarding immediately. In this case, there is little difference between this PR and the actual solution concerning pointeless buffering as in both cases, most of the buffering data is going to be discarded. However, this PR will help to not block the display totally and let the user know if he has to seek before or after when searching for a specific position by letting the player paint new content when seeking.

@stuartmorgan
Copy link
Contributor

I'm listening for this event, because, as far as I know, it's the only way to know that something has been paint on the screen.

Couldn't you interpose the Surface to monitor frame available callbacks?

  • when the user seek location A, then B immediately, then, yes, the player is going to wait for the player to be ready before seeking to the next position. However, the timeout may help fix this issue to prevent the amount which will be buffered.

It won't fix it, it will just cap it by the timeout. If it takes, on average, X ms to be able to start playing from a new position (or time out), then without your PR it will start playing from B in X ms, but with your PR it will take 2X ms instead.

  • when the user is scrolling through the video, the player is just constantly trying to buffer and discarding immediately. In this case, there is little difference between this PR and the actual solution concerning pointeless buffering as in both cases

It is still going to be the case that it will increase the amount of time it takes to play back from the position where the seek bar is finally released by 50% on average.

However, this PR will help to not block the display totally and let the user know if he has to seek before or after when searching for a specific position by letting the player paint new content when seeking.

Couldn't you get the same effect without the delay at the end by rate limiting seek frequency on the Dart side instead? I.e., instead of sending continual seek events while dragging, send them only:

  • at a throttled rate, and
  • on drag completion

(It wouldn't actually wait for paint events, but if you add a timeout that wouldn't always be the case for the native solution either.)

@henri2h
Copy link
Author

henri2h commented Apr 11, 2022

Couldn't you get the same effect without the delay at the end by rate limiting seek frequency on the Dart side instead? I.e., instead of sending continual seek events while dragging, send them only:

Well, you're totally right, it's a more elegant solution. Just implemented it in fluttercommunity/chewie#623 it's working great !
Thanks for your time.
I will close this PR has it's fix has been moved to the chewie plugin.

@henri2h henri2h closed this Apr 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
2 participants