[video_player] fix: add missing isPlaybackLikelyToKeepUp check.#3826
Conversation
|
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). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
|
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. |
58347f9 to
92a6dce
Compare
tarrinneal
left a comment
There was a problem hiding this comment.
Seems you're still working on this, but I'll just reiterate what the bot already said. You'll need to add some tests to this pr before we can merge it.
|
Hi @tarrinneal , I've added the necessary test case and all tests have passed, both for replay and livestream. |
d11eec0 to
20dc1c6
Compare
tarrinneal
left a comment
There was a problem hiding this comment.
Seems good to me, I'll let @hellohuanlin do final review.
hellohuanlin
left a comment
There was a problem hiding this comment.
I'm not sure if isPlaybackLikelyToKeepUp is a good indicator for bufferingStart and bufferingEnd events. From the doc this flag is just a "prediction", which may not be correct.
There was a problem hiding this comment.
did you hit this call? When playback buffer is empty, is it possible for isPlaybackLikelyToKeepUp to be true at all?
There was a problem hiding this comment.
I have tested this with below code and through OBS livestreaming, and have found that it is possible for both the 'isPlaybackLikelyToKeepUp' flag to be true and for the playback buffer to be empty at the same time while watching a livestream.
import AVKit
import UIKit
class ViewController: UIViewController {
var isPlaybackBufferEmptyListener: NSKeyValueObservation?
var isPlaybackBufferFullListener: NSKeyValueObservation?
var isPlaybackLikelyToKeepUpListener: NSKeyValueObservation?
@IBAction func onClickPlay(_ sender: Any) {
/// Test with a live stream URL, it's m3u8 has no end tag
guard let url = URL(string: "Test with a live stream URL") else { return }
// guard let url = URL(string: "https://flutter.github.io/assets-for-api-docs/assets/videos/hls/bee.m3u8") else { return }
let item = AVPlayerItem(url: url)
isPlaybackBufferEmptyListener?.invalidate()
isPlaybackBufferEmptyListener = item.observe(\.isPlaybackBufferEmpty, options: [.initial, .new]) { _, change in
guard let new = change.newValue else { return }
print("isPlaybackBufferEmpty ---> \(new)")
}
isPlaybackBufferFullListener?.invalidate()
isPlaybackBufferFullListener = item.observe(\.isPlaybackBufferFull, options: [.initial, .new]) { _, change in
guard let new = change.newValue else { return }
print("isPlaybackBufferFull ---> \(new)")
}
isPlaybackLikelyToKeepUpListener?.invalidate()
isPlaybackLikelyToKeepUpListener = item.observe(\.isPlaybackLikelyToKeepUp, options: [.initial, .new]) { _, change in
guard let new = change.newValue else { return }
print("isPlaybackLikelyToKeepUp ---> \(new)")
}
let player = AVPlayer(playerItem: item)
let controller = AVPlayerViewController()
controller.player = player
present(controller, animated: true) {
player.play()
}
}
}There was a problem hiding this comment.
Could you post your log here? Thanks!
There was a problem hiding this comment.
Yes. the the log,
isPlaybackBufferFull ---> false
isPlaybackLikelyToKeepUp ---> false
isPlaybackBufferFull ---> true
isPlaybackBufferFull ---> false
isPlaybackLikelyToKeepUp ---> true
>>>>>>> SEEK BEGIN >>>>>>>
isPlaybackLikelyToKeepUp ---> false
<<<<<<<< SEEK END <<<<<<<<
isPlaybackLikelyToKeepUp ---> true
>>>>>>> SEEK BEGIN >>>>>>>
isPlaybackLikelyToKeepUp ---> false
<<<<<<<< SEEK END <<<<<<<<
isPlaybackLikelyToKeepUp ---> true
Based on the aforementioned logs, it is evident that the isPlaybackBufferFull consistently remains false, while the isPlaybackLikelyToKeepUp can be either true or false during seeking. I have uploaded the testing project to AVPlayer_livestream. Please feel free to run it and review the provided logs.
There was a problem hiding this comment.
i was asking the opposite situation - isPlaybackBufferEmpty
There was a problem hiding this comment.
Sorry, @hellohuanlin, I realized that I missed including the first line of the log. Here's the revised version:
isPlaybackBufferEmpty ---> true
isPlaybackBufferFull ---> false
isPlaybackLikelyToKeepUp ---> false
isPlaybackBufferFull ---> true
isPlaybackBufferFull ---> false
isPlaybackLikelyToKeepUp ---> true
>>>>>>> SEEK BEGIN >>>>>>>
isPlaybackLikelyToKeepUp ---> false
<<<<<<<< SEEK END <<<<<<<<
isPlaybackLikelyToKeepUp ---> true
Please note that the isPlaybackBufferEmpty always remains true, while the isPlaybackLikelyToKeepUp can be either true or false during seeking.
There was a problem hiding this comment.
this is surprising. i'd expect isPlaybackBufferEmpty to be false most of the time. Do you have some insight on this?
There was a problem hiding this comment.
It seems like there is a bug in AVFoundation related to the isPlaybackBufferEmpty key-value observing (KVO) not being triggered when its value changes. As a workaround for now, we may check the isPlaybackLikelyToKeepUp property within the playbackBufferEmptyContext and playbackBufferFullContext. refer log:
[KVO] isPlaybackBufferEmpty ---> true
[KVO] isPlaybackBufferFull ---> false
[KVO] isPlaybackLikelyToKeepUp ---> false (crrent isPlaybackBufferEmpty ---> true)
2023-05-25 13:26:31.528310+0900 Lab_AVPlayer_livestream[1757:465625] Metal API Validation Enabled
[KVO] isPlaybackBufferFull ---> true
[KVO] isPlaybackBufferFull ---> false
[KVO] isPlaybackLikelyToKeepUp ---> true (crrent isPlaybackBufferEmpty ---> false)
I tested this behavior on iPadOS 16.5 using a real device. You can also check the provided demo AVPlayer_livestream for further reference.
There was a problem hiding this comment.
This behavior needs to be heavily documented in our code (since it's not mentioned in apple's doc), otherwise it's too hard to understand in the future. Could you add some comments explaining why we need this workaround?
There was a problem hiding this comment.
Hello @hellohuanlin Before I proceed with adding comments about the necessity of the isPlaybackLikelyToKeepUp check when observing isPlaybackBufferFull and isPlaybackBufferEmpty using KVO, I would like to seek clarification on the exact meaning of isBuffering within the video_player module. I have raised this question in detail here.
Based on my understanding, the evaluation of isBuffering relies on the Key-Value Observing (KVO) of isPlaybackBufferFull, isPlaybackBufferEmpty, and isPlaybackLikelyToKeepUp.
There was a problem hiding this comment.
from the doc, when buffer is full, it's still possible for isPlaybackLikelyToKeepUp to return NO. Do we want to emit bufferingStart then?
There was a problem hiding this comment.
Yes, that is correct. Since the KVO code related to 'playbackBufferEmptyContext' is already responsible for emitting the 'bufferingStart' event, there is no need to emit it here.
There was a problem hiding this comment.
I meant, do we need an else statement here (similar to playbackBufferEmptyContext)? I am having some trouble understanding why these 2 are different.
There was a problem hiding this comment.
|
As stated in the doc the |
|
Based on the code in |
The line may have changed. could you link here? Thanks! |
|
Hello @hellohuanlin, the link FLTVideoPlayerPlugin.m#LL332C4-L339C4 |
I'm a bit confused here. Simply observing |
|
@hellohuanlin, based on my testing log, it appears that simply observing isPlaybackLikelyToKeepUp is sufficient for checking if playback is stalling or not. However, the Key-Value Observing (KVO) for isPlaybackBufferEmpty or isPlaybackBufferFull does not always work correctly. It's a bug. There is a related issue: https://developer.apple.com/forums/thread/669541 Here is the log snippet from my test: I conducted this test on iPadOS 16.5 using a real device. You can also refer to the provided demo AVPlayer_livestream for further clarification. |
…elyToKeepUp` over `isPlaybackBufferFull` or `isPlaybackLikelyToKeepUp` for determining playback stall status
02f3102 to
39b3e5c
Compare
…aybackLikelyToKeepUp` for determining `isBuffering` status. `isBuffering` servea a singular purpose, indicating whether the playback is likely to proceed without stalling. Relying solely on `isPlaybackLikelyToKeepUp` is sufficient, as [discussion](flutter#3826 (comment)). Therefore, the code listening to `isPlaybackBufferEmpty` or `isPlaybackBufferFull` should be removed.
|
auto label is removed for flutter/packages, pr: 3826, due to - The status or check suite Linux repo_tools_tests has failed. Please fix the issues identified (or deflake) before re-applying this label. |
|
auto label is removed for flutter/packages, pr: 3826, due to - The status or check suite repo_checks has failed. Please fix the issues identified (or deflake) before re-applying this label. |
flutter/packages@6889cca...3e8b813 2023-07-18 jkbturek@gmail.com [video_player] Fix iOS crash with multiple players (flutter/packages#4202) 2023-07-17 stuartmorgan@google.com [pigeon] Enable Android emulator tests in CI (flutter/packages#4484) 2023-07-17 defuncart@gmail.com [video_player] Add optional web options [Platform interface] (flutter/packages#4433) 2023-07-17 rexios@rexios.dev [google_maps_flutter_platform_interface] Platform interface changes for #3258 (flutter/packages#4478) 2023-07-17 yan.outside@gmail.com [video_player] fix: add missing isPlaybackLikelyToKeepUp check. (flutter/packages#3826) 2023-07-17 43054281+camsim99@users.noreply.github.com [camerax] Add flash configuration for image capture (flutter/packages#3800) 2023-07-17 stuartmorgan@google.com Remove `equatable` and `xml` allowances (flutter/packages#4489) 2023-07-17 stuartmorgan@google.com [ci] Switch Linux platform tests to LUCI (flutter/packages#4479) 2023-07-17 stuartmorgan@google.com [ci] Adjust bot configurations (flutter/packages#4485) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
flutter/packages@6889cca...3e8b813 2023-07-18 jkbturek@gmail.com [video_player] Fix iOS crash with multiple players (flutter/packages#4202) 2023-07-17 stuartmorgan@google.com [pigeon] Enable Android emulator tests in CI (flutter/packages#4484) 2023-07-17 defuncart@gmail.com [video_player] Add optional web options [Platform interface] (flutter/packages#4433) 2023-07-17 rexios@rexios.dev [google_maps_flutter_platform_interface] Platform interface changes for flutter#3258 (flutter/packages#4478) 2023-07-17 yan.outside@gmail.com [video_player] fix: add missing isPlaybackLikelyToKeepUp check. (flutter/packages#3826) 2023-07-17 43054281+camsim99@users.noreply.github.com [camerax] Add flash configuration for image capture (flutter/packages#3800) 2023-07-17 stuartmorgan@google.com Remove `equatable` and `xml` allowances (flutter/packages#4489) 2023-07-17 stuartmorgan@google.com [ci] Switch Linux platform tests to LUCI (flutter/packages#4479) 2023-07-17 stuartmorgan@google.com [ci] Adjust bot configurations (flutter/packages#4485) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com,rmistry@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…ter#3826) When watching a live stream, if the playback buffers but the AVPlayerItem is likely to keep up, it is necessary to recheck AVPlayerItem.isPlaybackLikelyToKeepUp. If isPlaybackLikelyToKeepUp, a bufferingEnd event should be immediately triggered. I am encountering an issue with my product where, when watching a live stream, if I seek to the latest time, it continuously `bufferingStart` and does not come to an `bufferingEnd`.
…ter#3826) When watching a live stream, if the playback buffers but the AVPlayerItem is likely to keep up, it is necessary to recheck AVPlayerItem.isPlaybackLikelyToKeepUp. If isPlaybackLikelyToKeepUp, a bufferingEnd event should be immediately triggered. I am encountering an issue with my product where, when watching a live stream, if I seek to the latest time, it continuously `bufferingStart` and does not come to an `bufferingEnd`.
When watching a live stream, if the playback buffers but the AVPlayerItem is likely to keep up, it is necessary to recheck AVPlayerItem.isPlaybackLikelyToKeepUp. If isPlaybackLikelyToKeepUp, a bufferingEnd event should be immediately triggered. I am encountering an issue with my product where, when watching a live stream, if I seek to the latest time, it continuously
bufferingStartand does not come to anbufferingEnd.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.