-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[video_player] Fix pause infinite loop on completed #5920
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
[video_player] Fix pause infinite loop on completed #5920
Conversation
|
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 "@test-exemption-reviewer" in the #hackers channel in Chat (don't just cc them here, they won't see it! Use 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. |
tarrinneal
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple nits here.
I'm not certain if this will break the work-around for the video completing but not truly reaching the last frame or not. Maybe @stuartmorgan has some insight.
| ## NEXT | ||
|
|
||
| * Description of the change. | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be removed
| * Updates support matrix in README to indicate that iOS 11 is no longer supported. | ||
| * Clients on versions of Flutter that still support iOS 11 can continue to use this | ||
| package with iOS 11, but will not receive any further updates to the iOS implementation. | ||
| * Fix infinite pause loop caused by on completed to call pause even when video is pause. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes infinite pause loop caused by call to pause even when video is already paused.
There are a couple of other ways we could do this if your not sure and think they will be better. |
| pause().then((void pauseResult) => seekTo(value.duration)); | ||
| if (value.isPlaying) { | ||
| pause().then((void pauseResult) => seekTo(value.duration)); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changed logic would definitely not be guaranteed to actually do what this code is supposed to be doing; if the native side reported reaching the end as:
- playback stopped
- video completed
then the seek code would never run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@stuartmorgan have updated the logic to account for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I believe this infinite loop issue is only seen on web for some reason
tarrinneal
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change tracks for me, approved pending @stuartmorgan review.
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the code more deeply here, it's not clear to me what the reason for this change is. Why is calling pause while paused a problem? The PR description just says that it's a problem because it calls _applyPlayPause(), but with the paused value state, that will call _videoPlayerPlatform.pause. If calling pause on the platform object will start playing a video, that seems like a platform bug.
Could you file an issue with clear repro steps and an explanation of what exactly is happening?
| }); | ||
|
|
||
| test( | ||
| 'isCompleted seeks position to max duration and pauses the video first if is playing', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't the thing you want to fix that you want to not call pause if it's not playing? That path would also need a test.
|
Thanks for filing the issue. Could you elaborate, either here or (preferably) in the issue about what exactly is going wrong? It's not clear to me how the change in this PR relates to the problem shown in the issue. What exactly is happening in the web implementation that is causing the incorrect behavior? |
The listener when completed goes into an infinite loop which continuously calls any functions in the onCompleted switch case statement. |
It's not clear to me why this would be the case. Could you provide the specific call sequence in the infinite loop? In other words, when you say:
what code is repeatedly calling that? |
This is the code which seems to be repeatedly calling it /.pub-cache/hosted/pub.dev/video_player_web-2.1.3/lib/src/video_player.dart
|
|
It seems like more root-causing is still needed here. As far as I can see the only change the current version of the PR makes is not calling
Are those docs incorrect? Is calling |
|
The infinite loop must be coming from the html code
But I believe this issue is coming from the _applyPlayPause function in the
video_player
Which while in the infinite loop, will actually instantly cancel the timer
which is used for the video playing
…On Fri, 9 Feb 2024, 10:21 am stuartmorgan, ***@***.***> wrote:
It seems like more root-causing is still needed here. As far as I can see
the only change the current version of the PR makes is not calling pause()
when paused, but pause() on web just calls pause() on the <video>
element, and according to MDN:
The HTMLMediaElement.pause() method will pause playback of the media, if
the media is already in a paused state this method will have no effect.
Are those docs incorrect? Is calling pause() when already paused at the
end of the video triggering an onEnded event? That seems very surprising
if so, but if not I don't see how this PR would fix the behavior.
—
Reply to this email directly, view it on GitHub
<#5920 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A4WXA3VIXNG2UQUBXEDBCVTYSU6W5AVCNFSM6AAAAABB7SU7AOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZUHE2TENJWGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
|
So this PR doesn't fix the infinite loop, just removes one side effect of the infinite loop? If there's an infinite loop, we should root cause and fix the loop itself, not the side effect. |
|
Yes that's correct,
Olay I will need to look into that then as from a quick look I couldn't
work out where the 'ended' event was getting added to the video event
stream in the web package.
…On Fri, 9 Feb 2024, 10:38 am stuartmorgan, ***@***.***> wrote:
So this PR doesn't fix the infinite loop, just removes one side effect of
the infinite loop?
If there's an infinite loop, we should root cause and fix the loop itself,
not the side effect.
—
Reply to this email directly, view it on GitHub
<#5920 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/A4WXA3T5FPBHCYDGKU7WF3DYSVAW7AVCNFSM6AAAAABB7SU7AOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZUHE3TINJQG4>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
|
The loop is coming from This is used in video_player_web
I can't find the code where the event is added to the stream, I'm not sure this is even in our control ? |
|
The creation of the event is done by the browser, but it is likely the result of something the plugin is doing; it's extremely unlikely that browser behavior is to create an infinite stream of Is seeking to the end when already at the end creating a new |
|
Thanks, have updated now |
| * Updates support matrix in README to indicate that iOS 11 is no longer supported. | ||
| * Clients on versions of Flutter that still support iOS 11 can continue to use this | ||
| package with iOS 11, but will not receive any further updates to the iOS implementation. | ||
| * Web, Fix infinite pause loop caused by seekTo marking the video as completed when already completed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, revert all changes to the video_player package, they're not needed.
flutter pub get (or flutter pub upgrade) will take care of fetching the fixed version of video_player_web once the fix is published.
(Sorry I wasn't clearer before!)
|
Thanks for all the help guys, should be all done now! |
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments; I'll leave final approval for @ditman since this is now web-only.
| ## NEXT | ||
| ## 2.1.4 | ||
|
|
||
| * Fixes infinite pause loop caused by seekTo marking the video as completed when already completed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Please use backticks on seekTo to mark it as code.
| void seekTo(Duration position) { | ||
| assert(!position.isNegative); | ||
| // Don't seek if video is already at position. | ||
| // As seeking when completed will trigger another completed event ('onEnded') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a sentence fragment; please combine it with the line above: "Don't seek if the video is already at the target position, as seeking when completed [...]"
| assert(!position.isNegative); | ||
| // Don't seek if video is already at position. | ||
| // As seeking when completed will trigger another completed event ('onEnded') | ||
| // to avoid potentially firing extra 'onEnded' events when the video is already over |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"when the video is already over" is redundant with the earlier "when completed", so should be removed.
| assert(!position.isNegative); | ||
| // Don't seek if video is already at position. | ||
| // As seeking when completed will trigger another completed event ('onEnded') | ||
| // to avoid potentially firing extra 'onEnded' events when the video is already over |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a period at the end of the sentence, since comments should be properly punctuated sentences.
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Fixing review state; I thought I could clear my request without approving, but apparently not.)
|
|
|
Thanks for the review, updated now. |
ditman
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a test, I think we can write one easily by listening to the events coming from the videoplayer (two seeks to the same position should only yield a single seek event to the core plugin)
packages/video_player/video_player_web/lib/src/video_player.dart
Outdated
Show resolved
Hide resolved
Co-authored-by: David Iglesias <[email protected]>
|
Okay where do we put tests for this package ? |
|
@ToddZeil there's already several tests here: TL;DR: Assuming that PLUGIN_TOOLS=/work/flutter/packages/script/tool/bin/flutter_plugin_tools.dart # Adjust this
dart $PLUGIN_TOOLS drive-examples --current-package --web --run-chromedriver(I normally use Linux) There's more instructions on how to run tests in the README.md of the example |
|
I have set up the integration tests, not sure exactly how these work but the current seekTo doesn't seem to check for anything other than completion ?
But when I comment out the new code it doesn't seem to effect anything with in the test? |
@ToddZeil can you share the code of the test that you've written? Or I can try and write one tomorrow :) My plan is to:
I that test should fail if we comment out the fix (?) |
|
Your test sounds like it should work! I was just trying to find out what events the This is the test I was trying: |
|
Did get a chance to look into this test ? Or have further hints or advice ? Thanks |
|
@ToddZeil I didn't have time to look at the test, but I'm going to work next in migrating the The problem is that we don't have any "seek" event that we can check that wasn't propagated: (We could maybe inject a fake video player and ensure we don't call "seek" multiple times, but I'm not sure... I'll try to add you as a Co-Author in the migration PR!) |
|
Okay interesting! Cool hopefully we can get it in, thanks for that :) |
|
This fix has landed alongside #5800! Closing. |
|
Great thank you! |
|
@ToddZeil thanks for taking the time to report and fix this, keep it coming! |
When a video is complete, and not on a loop setting.
Pause() function is called even if video is already paused.
(_applyPlayPause() function is used for play and pause which can lead to playing a video when attempting to restart)
Fixes flutter/flutter#143141
Edited: Also this may only be an issue on web
Pre-launch Checklist
dart format.)[shared_preferences]pubspec.yamlwith an appropriate new version according to the pub versioning philosophy, or this PR is exempt from version changes.CHANGELOG.mdto add a description of the change, following repository CHANGELOG style.///).If you need help, consider asking for advice on the #hackers-new channel on Discord.