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

Conversation

@alexagat
Copy link

@alexagat alexagat commented Sep 10, 2021

This stabilizes the behavior of the video_player package such that calling seekTo does not reset the playback speed to 1.0 on the iOS platform.

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. (Note that 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.
  • I updated CHANGELOG.md to add a description of the change.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the 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.

@google-cla
Copy link

google-cla bot commented Sep 10, 2021

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

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here with @googlebot I signed it! and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@alexagat
Copy link
Author

alexagat commented Sep 10, 2021

@googlebot I fixed it!

…copy of playback speed setting it on player to preserve value
@alexagat alexagat force-pushed the video_player/pr-playback-rate branch from b64345d to 3d62e8e Compare September 10, 2021 04:12
Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution!

Comments inline, but this will also need tests (and a version update), per the checklist and contribution guide.

[_player play];

// fix to always set playback speed accurately
[self setPlaybackSpeed:_internalPlaybackSpeed];
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this always needed here? My impression from comments in the issue was that calling it from the completion handler of the seek method would likely be enough.

Copy link
Author

Choose a reason for hiding this comment

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

@stuartmorgan which completion handler are you referring to? I only see a seekTo method in the file.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

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

@stuartmorgan I see. I tried moving the call inside the completionHandler block of the seekTo method as follows:

[_player seekToTime:CMTimeMake(location, 1000)
      toleranceBefore:kCMTimeZero
       toleranceAfter:kCMTimeZero
    completionHandler:^(BOOL finished) {
    [self setPlaybackSpeed:_internalPlaybackSpeed];
  }];

but the issue of the playback speed resetting to 1.0 came back. Therefore that is not equivalent.

Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting. So presumably then it's the playbackLikelyToKeepUpContext and/or AVPlayerItemStatusReadyToPlay codepath that's resolving this? In which case perhaps the underlying issue is that AVPlayer automatically resets the playback speed when the buffer is insufficient.

@alexagat alexagat force-pushed the video_player/pr-playback-rate branch from 96e69d4 to 3d62e8e Compare September 16, 2021 23:46
@alexagat
Copy link
Author

@stuartmorgan / @creativecreatorormaybenot I've realized that while this modification fixes the playback speed issue it causes a negative side-effect. When an unbuffered range of the video stream is played back, the video player can lose volume (go mute) and become unstable. Once it gets in this state it does not recover. Therefore looks like there's still more work, unfortunately.

@creativecreatorormaybenot
Copy link
Contributor

@alexagat if you take a look at my PR (#3404), it does fix the issue. Can we not just perform the same action on the native side?

Because at the end of the day, I am only making a method channel call..

@stuartmorgan-g
Copy link
Contributor

When an unbuffered range of the video stream is played back, the video player can lose volume (go mute) and become unstable.

Does setting it back only for playbackLikelyToKeepUpContext work better, or is that already the only place it was being called in practice?

@alexagat if you take a look at my PR (#3404), it does fix the issue.

It is very likely that your approach would racily have the same behavior. There's no guarantee that some fraction of 500ms is enough time to create sufficient buffer to avoid an overrun.

@alexagat
Copy link
Author

@creativecreatorormaybenot you are correct your PR does fix this issue on the iOS platform and does not add any of the negative side-effects the native fix above introduced. I played around for a bit but didn't come up with a native-only solution here. For now I've added your code to my fork so we can patch this issue for users.

@creativecreatorormaybenot
Copy link
Contributor

@alexagat yeah, that is what we are also doing in production, using our own fork of the plugin.

@stuartmorgan-g
Copy link
Contributor

If there's no way to automatically handle this in the plugin that doesn't have the potential to cause playback issues, the other option would be to add an event that would report playback speed changes back to the Dart side, so that UIs could update, and users could change it back themselves.

But I would expect that there's a way to determine the relevant state to handle this correctly. Does observing timeControlStatus give any indication as to what's happening?

@creativecreatorormaybenot
Copy link
Contributor

@stuartmorgan I have one concern with this part:

If there's no way to automatically handle this in the plugin that doesn't have the potential to cause playback issues, the other option would be to add an event that would report playback speed changes back to the Dart side, so that UIs could update, and users could change it back themselves.

You were saying that my fix was a hack. But your proposal is not? If I look at this from a different perspective, this means that users of the problem would need to integrate the hack (changing the playback speed after the change has been reported to the Dart side).
I see how this would be better in some odd way, but then again I really feel like this is even worse than just using the not-so-great fix because it also makes for a very bad API IMHO.

But I would expect that there's a way to determine the relevant state to handle this correctly.

That would be my preferred choice as well..

@stuartmorgan-g
Copy link
Contributor

You were saying that my fix was a hack. But your proposal is not?

There are two possibilities here:

  1. There is a reliable programatic way to determine when it is safe to automatically set the playback rate back to the desired value. If there is, we should do that.
  2. There is no reliable way to do it automatically, such that any attempt to do so may break playback in the way described above. In this case I don't see any alternative to simply communicating the state back to the UI so that users can control it.

Your PR was sort of attempting to do 1, but in a very hacky way. I'm saying that either we need to do 1 correctly, or if 1 is impossible we should do 2. If 2 is the only option it's not a hack, it a reflection of the limitations of the platform that the plugin is wrapping.

@stuartmorgan-g
Copy link
Contributor

@alexagat Are you still planning on updating this PR based on the discussion above?

@alexagat
Copy link
Author

alexagat commented Nov 1, 2021

@stuartmorgan I am not planning to update this PR and it should probably be closed. I never got the iOS implementation to work as desired and ended up using the code change from #3404 to resolve the bug.

@creativecreatorormaybenot
Copy link
Contributor

Which is why is still think it should be merged 👍 It is not perfect but the best from a cost <> value perspective.

@stuartmorgan-g
Copy link
Contributor

Closing per the above; thanks for the investigation so far. This should serve as a good starting point for future attempts to fix the issue.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants