-
Notifications
You must be signed in to change notification settings - Fork 6k
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
The player should properly expose audio focus state #6203
Comments
This issue does not seem to follow the issue template. Make sure you provide all the required information. |
I think the |
Testing on API 26 emulator I also can't reproduce the behavior you're seeing (after enabling audio focus handling as per your code snippet above, the player pauses when I simulate an incoming call and resumes afterwards). |
Hi. Thanks for taking interest in this issue. Maybe the issue is bound to some other functionality (MediaSessionConnector or any other additional ExoPlayer classes i'm using). I managed to create simple reproduce project, that have this behavior (tested on API 28 Emulator and Nokia 8 device). In this project i'm using only ExoPlayer classes to play one online hls track. On call - playback doesn't get paused (you can see that on state textview and on notification). Let me know if i can assist you more |
I gave your demo a try and playback is definitely pausing and resuming correctly. I think what you're confused by is that You may just want to track #5087. Alternatively, is this causing any concrete issues for you? |
So, as i understand it, the player changed it's internal state but mediasession does not get notified about this? Is there a way around it, some way to listen to this internal changes and notify mediasession myself? The issue you linked seems to be stale and mediasession not being notified seems like a serious issue for me |
Please can you explain why in the context of an actual use case? I'm not saying it's not a serious issue, I'm just saying that we need to understand the user facing issue to know how to prioritize this. |
I attached recording of use case that gets weird.
Scanario above results in weird and unpredictable user experience. |
Thanks, that makes sense. I think it's correct that Ideally we'd introduce a new For the use case shown in your example, I think what should happen is that the position should stop counting up, but the play/pause button should not change (i.e. it should continue to represent the opposite to the user intention - i.e. continue to be the pause button). Changing the pause button would be weird in cases where the transient focus loss only occurs for a brief period (e.g. a second or two), and would also prevent the user from changing their intention whilst the focus is lost. Does that make sense? |
In my opinion what end user really cares about is the simplest player state. I think if somebody will see that player reports to be playing, but progress will not be going - one could assume error on app side. In users eyes playback is paused for the call, and he/she does not care about internal player state.
I think the best solution here would be changing play/pause button on |
The reason I think it should work as I described is that it's the only way that would allow the user to disable automatic resumption of the media when the focus is granted back to the app. With Spotify, it seems that:
So it doesn't seem like the optimal model to me. I know it's an edge case, but it seems preferable that the user should be able to tap the play/pause button during period when the app doesn't have focus, to avoid playback resuming when focus is returned. Either way, it seems the most important thing is the fix the progress reporting. Chances are users wont be pulling down the notification drawer and trying to interact with the media notification mid phone call. |
Yes, I can agree that progress reporting is the most important factor here :-) |
i think with state_waiting there should be a way to know why exoplayer is in state of waiting like phonecall |
I agree that STATE_WAITING or getting a STATE_PAUSED from MediaSession is very important. Noticed it's tagged as an "enhancement" but feels more like a critical bugg. Not only does the UX gets really strange here that the user will see the wrong position in the UI after a call (pausing the player resets it to the correct one). But in our case we also report the position to the backend. Meaning the user can end up in the wrong place next time playback starts because we report what we get from MediaSession. |
@Flyktsodan we will face the exact same issue at some point when we will have to report playback events to backend service. Thanks for bringing that up |
@tonihei - We should probably come up with an interim solution for this. |
I think we decided against adding a WAITING state because it would cause too much disturbance to existing state handling code. Instead we'll add a isWaitingForAudioFocus method that can be used to handle the state update in the |
The player may suppress playback when waiting for audio focus even if the state==Player.READY. There is currently no getter or callback to obtain this piece of information for UI updates or analytics. Also, it's a important derived state to know whether the playback position is advancing. Add isPlaying and the corresponding callback to allow retrieving this information more easily. Issue:#6203 PiperOrigin-RevId: 268921721
The playback speed set in MediaSession's PlaybackStateCompat needs to be the actual speed at which the playback position progresses and not the user-defined target speed. This fixed a bug where the position advances although the player lost audio focus. Issue:#6203 PiperOrigin-RevId: 269295249
The player now has extra methods to query the state and the media session bug is fixed as well. |
This will be part of the 2.10.5 release. |
The player may suppress playback when waiting for audio focus even if the state==Player.READY. There is currently no getter or callback to obtain this piece of information for UI updates or analytics. Also, it's a important derived state to know whether the playback position is advancing. Add isPlaying and the corresponding callback to allow retrieving this information more easily. Issue:#6203 PiperOrigin-RevId: 268921721
The playback speed set in MediaSession's PlaybackStateCompat needs to be the actual speed at which the playback position progresses and not the user-defined target speed. This fixed a bug where the position advances although the player lost audio focus. Issue:#6203 PiperOrigin-RevId: 269295249
I tested the new 2.10.5 release and well - it is subjectively worse than it was before. In attached video i highlighted issues i have with it:
|
I don't think the problematic one is related to @NekroMancer - In the meantime you can hide the problematic counter using
It's already explained above why this doesn't seem optimal, and also that it's possible to toggle Spotify's notification into the state that you consider incorrect anyway... It seems somewhat dubious that the edge case of interacting with a media notification whilst there's an incoming phone call could ever have a "serious" UX problem worth reimplementing large amounts of code to change, even if you disagree with exactly how it works. Reopening to track fixing the chronometer. |
Yes indeed. There are some more usages in our code base that should use isPlaying instead of the previous method of determining "is playing". Will update accordingly.
That's actually working as intended. See the documentation here that explicitly says that this method returns 0 when paused. If you'd like to check the user-defined target playback speed, you can access the extra |
Nice! good job guys and thanks for fixing it so quickly. |
This method should be used where we previously checked for active playback by state==READY and playWhenReady=true. Using the new method ensures we take audio focus into account for these usages. Also update some method naming to avoid confusion with the isPlaying method. Issue:#6203 PiperOrigin-RevId: 270910982
Adding this callback makes sense for completeness (we have similar callbacks for all other playback state properties), and also to detect audio focus loss while buffering which would currently trigger no callback because isPlaying is still false. Issue:#6203 PiperOrigin-RevId: 271347351
This method should be used where we previously checked for active playback by state==READY and playWhenReady=true. Using the new method ensures we take audio focus into account for these usages. Also update some method naming to avoid confusion with the isPlaying method. Issue:#6203 PiperOrigin-RevId: 270910982
Adding this callback makes sense for completeness (we have similar callbacks for all other playback state properties), and also to detect audio focus loss while buffering which would currently trigger no callback because isPlaying is still false. Issue:#6203 PiperOrigin-RevId: 271347351
Hi @ojw28 , I implemented On the other hand, i tried keeping the logs in exoplayer demo app (v2.10.6) in
and in @OverRide In exoPlayer demo app also I am not able to see any logs in the same incoming call scenario. Please let me know if i did wrong. In which case, this call back will come. |
Did playback resume automatically after the call ended, or did it remain stopped? I'm not sure, but this may depend on which dialer app you're using. We currently only notify playback suppression for the "resume automatically" case when In 2.11.0 we'll also be adding the option to stop playback due to audio becoming noisy, so there will be at least two possible reasons for the permanently stopped case. Please let us know which of the two cases you're seeing. If it's the resume automatically case then we should investigate this as a bug. If it's the remain stopped case then we should just ensure that the future work is properly tracked by an enhancement issue. |
Yes, the playback resumes automatically when call ends. I am using Nokia 6.1 Plus, it has stock android and i don't think that it uses any much modified dialer app. You can see the following eventlogger logs
|
There's no I tried checking out 2.10.6 and implementing
to do some logging in the demo app, and I do see the logging when playback is paused due to an incoming call. So it seems to be working correctly. Note that you do have to actually enable audio focus handling on the player for any of this to work, with something like:
|
Thanks @ojw28 . I will check the code and |
Issue description
I'm trying to get AudioFocus behavior: duck (lower volume) on notifications and pause on incoming call (and play after call end). When i look at the code https://github.com/google/ExoPlayer/blob/release-v2/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioFocusManager.java#L419 default ExoPlayer implementation should be working like this (or maybe i don't understand it well). But unfortunetely - on incoming call volume is down to 0, but playback doesn't stop.
Interestingly enough.
CONTENT_TYPE_SPEECH
is not working either. Playback isn't stopped on both - notifications and incoming call.Reproduction steps
I set audio attributes like this
In logs i can see that
AUDIOFOCUS_LOSS_TRANSIENT
was dispatched. It seems likePLAYER_COMMAND_WAIT_FOR_CALLBACK
wasn't handled properly.EDIT: when i digged deeper i found that on
SimpleExoPlayer
ComponentListener
toPlayerCommand
is ignoringPLAYER_COMMAND_WAIT_FOR_CALLBACK
completelyVersion of ExoPlayer being used
2.10.3
Device(s) and version(s) of Android being used
Samsung Galaxy S7 Edge, Android 8.0; Huawei Mate 20 lite, Android 8.1; Samsung Galaxy A7 (2018), Android 9
Also emulators of Pixel 2 devices using Android 8, 9 and Q (9+)
The text was updated successfully, but these errors were encountered: