Skip to content
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

Closed
jakoss opened this issue Jul 19, 2019 · 28 comments
Closed

The player should properly expose audio focus state #6203

jakoss opened this issue Jul 19, 2019 · 28 comments
Assignees

Comments

@jakoss
Copy link

jakoss commented Jul 19, 2019

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

setAudioAttributes(AudioAttributes.Builder()
    .setContentType(C.CONTENT_TYPE_MUSIC)
    .setUsage(C.USAGE_MEDIA)
    .build(), true)

In logs i can see that AUDIOFOCUS_LOSS_TRANSIENT was dispatched. It seems like PLAYER_COMMAND_WAIT_FOR_CALLBACK wasn't handled properly.

D/AudioManager: dispatching onAudioFocusChange(-2) to android.media.AudioManager@1420c8com.google.android.exoplayer2.audio.AudioFocusManager$AudioFocusListener@d3f1561
D/AudioManager: dispatching onAudioFocusChange(1) to android.media.AudioManager@1420c8com.google.android.exoplayer2.audio.AudioFocusManager$AudioFocusListener@d3f1561

EDIT: when i digged deeper i found that on SimpleExoPlayer ComponentListener to PlayerCommand is ignoring PLAYER_COMMAND_WAIT_FOR_CALLBACK completely

private void updatePlayWhenReady(
      boolean playWhenReady, @AudioFocusManager.PlayerCommand int playerCommand) {
    player.setPlayWhenReady(
        playWhenReady && playerCommand != AudioFocusManager.PLAYER_COMMAND_DO_NOT_PLAY,
        playerCommand != AudioFocusManager.PLAYER_COMMAND_PLAY_WHEN_READY);
  }

Version 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+)

@google-oss-bot
Copy link
Collaborator

This issue does not seem to follow the issue template. Make sure you provide all the required information.

@andrewlewis
Copy link
Collaborator

I think the updatePlayWhenReady code does identify PLAYER_COMMAND_WAIT_FOR_CALLBACK (it's different to the other two possible constants). Could you add some logging in that method to check what parameters are passed to setPlayWhenReady when audio focus is lost transiently and gained again?

@andrewlewis
Copy link
Collaborator

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).

@jakoss
Copy link
Author

jakoss commented Jul 26, 2019

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
AudioFocus.zip

@ojw28
Copy link
Contributor

ojw28 commented Jul 26, 2019

I gave your demo a try and playback is definitely pausing and resuming correctly.

I think what you're confused by is that getPlayWhenReady continues to report true, even though playback is not continuing internally. This is by design for transient loss of focus, when the player is expected to be able to resume once focus is returned.

You may just want to track #5087. Alternatively, is this causing any concrete issues for you?

@ojw28 ojw28 assigned ojw28 and unassigned nic0lette Jul 26, 2019
@jakoss
Copy link
Author

jakoss commented Jul 26, 2019

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

@ojw28
Copy link
Contributor

ojw28 commented Jul 26, 2019

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.

@jakoss
Copy link
Author

jakoss commented Jul 26, 2019

I attached recording of use case that gets weird.
Step by step:

  • I start playback
  • I remember track position
  • I start a call
  • During a call, MediaSession claims that track is still playing and refreshes position
  • After a call, music starts to play with the same position as it was during a call (but this position is incorrect, sincle MediaSession doesn't get notified about playback state change)
  • On manual pause MediaSession update's track progress to the right state, which results in sudden change on seekbar.

Scanario above results in weird and unpredictable user experience.

untitled.zip

@ojw28
Copy link
Contributor

ojw28 commented Jul 29, 2019

Thanks, that makes sense. I think it's correct that getPlayWhenReady continues to return true, since it's the user intention, and in this case the user intention is still to play (which is why playback automatically resumes when focus is reacquired).

Ideally we'd introduce a new STATE_WAITING state, which would be similar to STATE_BUFFERING but for cases where we're waiting on some local condition to become true, in this case audio focus acquisition. Unfortunately, introducing this would be a very disruptive API change. We'll probably need to figure out a way of fixing this that's less disruptive (but also, not really hacky).

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?

@jakoss
Copy link
Author

jakoss commented Jul 29, 2019

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.

Changing the pause button would be weird in cases where the transient focus loss only occurs for a brief period

I think the best solution here would be changing play/pause button on AUDIOFOCUS_GAIN_TRANSIENT and leaving it for AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK. Spotify, YouTube and many other major players seems to be doing just that.

@ojw28
Copy link
Contributor

ojw28 commented Jul 29, 2019

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:

  1. There's no way to do this. If you're playing when the call starts, it seems impossible to prevent playback resuming when the call ends. At least via the notification - I didn't check via the main app UI.
  2. It seems like it's still possible to toggle the notification's play/pause button back into the state you'd consider incorrect (without anything happening).

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.

@jakoss
Copy link
Author

jakoss commented Jul 29, 2019

Yes, I can agree that progress reporting is the most important factor here :-)

@ojw28 ojw28 changed the title Player not pausing on incoming call The player should properly expose audio focus state Aug 1, 2019
@geeta4
Copy link

geeta4 commented Aug 2, 2019

i think with state_waiting there should be a way to know why exoplayer is in state of waiting like phonecall

@Flyktsodan
Copy link

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.

@jakoss
Copy link
Author

jakoss commented Sep 4, 2019

@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

@ojw28 ojw28 assigned tonihei and unassigned ojw28 Sep 4, 2019
@ojw28
Copy link
Contributor

ojw28 commented Sep 10, 2019

@tonihei - We should probably come up with an interim solution for this.

@tonihei
Copy link
Collaborator

tonihei commented Sep 11, 2019

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 MediaSessionConnector.

ojw28 pushed a commit that referenced this issue Sep 16, 2019
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
ojw28 pushed a commit that referenced this issue Sep 16, 2019
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
@tonihei
Copy link
Collaborator

tonihei commented Sep 19, 2019

The player now has extra methods to query the state and the media session bug is fixed as well.

@tonihei tonihei closed this as completed Sep 19, 2019
@ojw28
Copy link
Contributor

ojw28 commented Sep 20, 2019

This will be part of the 2.10.5 release.

ojw28 pushed a commit that referenced this issue Sep 20, 2019
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
ojw28 pushed a commit that referenced this issue Sep 20, 2019
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
@jakoss
Copy link
Author

jakoss commented Sep 23, 2019

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:

  • In notification one progress is properly paused, but the upper one isn't. It seems like MediaSession expects proper state update, not only a playback speed change
  • When paused, mediaController.playbackState.playbackSpeed value is 0.0. Is it really necessary? i used this to calculate totalTime of a song, doing mediaController.metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION) / playbackSpeed
  • In my opinion (and a lot of collagues in work thinks the same) player should report that it is paused. As a user i expect player to show me if it is paused or not. Now this behavior is even less intuitive. Our users might wonder why player is playing in background, but without a sound, while they have a call. And, as i mentioned before, Spotify, YouTube and all major players that i tested - they ALL show paused state on incoming call. So we can't show users something else - they will assume it's incorrect behavior. Without that i think we will have to do MediaSession all by ourselves, since this is a serious UX problem for us.

player.zip

@ojw28
Copy link
Contributor

ojw28 commented Sep 23, 2019

In notification one progress is properly paused, but the upper one isn't. It seems like MediaSession expects proper state update, not only a playback speed change

I don't think the problematic one is related to MediaSession. @tonihei - I think this condition needs updating to use isPlaying. We'll need to hook into the new event as well. We should also never use the chronometer if playback speed is anything other than 1, because there's no way to make it count up in anything other than realtime.

@NekroMancer - In the meantime you can hide the problematic counter using playerNotificationManager.setUseChronometer(false);.

In my opinion (and a lot of collagues in work thinks the same) player should report that it is paused. As a user i expect player to show me if it is paused or not. Now this behavior is even less intuitive. Our users might wonder why player is playing in background, but without a sound, while they have a call. And, as i mentioned before, Spotify, YouTube and all major players that i tested - they ALL show paused state on incoming call. So we can't show users something else - they will assume it's incorrect behavior. Without that i think we will have to do MediaSession all by ourselves, since this is a serious UX problem for us.

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.

@ojw28 ojw28 reopened this Sep 23, 2019
@tonihei
Copy link
Collaborator

tonihei commented Sep 23, 2019

I think this condition needs updating to use isPlaying

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.

When paused, mediaController.playbackState.playbackSpeed value is 0.0. Is it really necessary? i used this to calculate totalTime of a song, doing mediaController.metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION) / playbackSpeed

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 MediaSessionConnector.EXTRAS_SPEED.

@Flyktsodan
Copy link

Nice! good job guys and thanks for fixing it so quickly.

ojw28 pushed a commit that referenced this issue Oct 2, 2019
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
ojw28 pushed a commit that referenced this issue Oct 2, 2019
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
@ojw28 ojw28 closed this as completed Oct 2, 2019
ojw28 pushed a commit that referenced this issue Oct 14, 2019
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
ojw28 pushed a commit that referenced this issue Oct 14, 2019
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
@GouravSna
Copy link

GouravSna commented Oct 23, 2019

Hi @ojw28 ,

I implemented public void onPlaybackSuppressionReasonChanged(int playbackSuppressionReason) in my app code and tried to see in which cases we will get the audio suppression. We did a phone call and picked the call then i could see that i did not get any suppression reason.

On the other hand, i tried keeping the logs in exoplayer demo app (v2.10.6) in ExoPlayerImpl in setPlayWhenReady method,

if (suppressionReasonChanged) { Log.d("xxxLogs", " suppressionReasonChanged In ExoPlayerImpl " + suppressionReasonChanged) ; listener.onPlaybackSuppressionReasonChanged(playbackSuppressionReason); }

and in EventLogger class as well by implementing the following method,

@OverRide
public void onPlaybackSuppressionReasonChanged(EventTime eventTime,
int playbackSuppressionReason) {
Log.d("xxxLogs", " suppressionReasonChanged in EventLogger " + playbackSuppressionReason) ;
}

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.

@ojw28
Copy link
Contributor

ojw28 commented Oct 23, 2019

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 playWhenReady remains true. For the permanently stopped case when playWhenReady is toggled to false, we do not currently propagate a reason. This is work that's still to be done.

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.

@GouravSna
Copy link

GouravSna commented Oct 23, 2019

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

2019-10-23 17:07:01.894 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: state [0.01, 0.00, window=0, true, BUFFERING]
2019-10-23 17:07:01.954 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: surfaceSizeChanged [0.07, 0.00, window=0, 1080, 2065]
2019-10-23 17:07:02.003 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: timelineChanged [0.12, 0.00, window=0, periodCount=1, windowCount=1, reason=PREPARED
2019-10-23 17:07:02.003 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   period [734.00]
2019-10-23 17:07:02.003 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   window [734.00, true, false]
2019-10-23 17:07:02.003 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: ]
2019-10-23 17:07:02.008 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: mediaPeriodCreated [0.12, 0.00, window=0, period=0]
2019-10-23 17:07:02.009 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: loading [0.12, 0.00, window=0, period=0, true]
2019-10-23 17:07:02.011 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderEnabled [0.12, 0.00, window=0, period=0, video]
2019-10-23 17:07:02.011 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderEnabled [0.12, 0.00, window=0, period=0, audio]
2019-10-23 17:07:02.024 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: tracksChanged [0.14, 0.00, window=0, period=0, 
2019-10-23 17:07:02.024 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   Renderer:0 [
2019-10-23 17:07:02.024 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:     Group:0, adaptive_supported=YES [
2019-10-23 17:07:02.024 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:0, id=1, mimeType=video/avc, bitrate=769255, codecs=avc1.42c01e, res=320x142, fps=24.0, supported=YES
2019-10-23 17:07:02.024 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:1, id=2, mimeType=video/avc, bitrate=1774254, codecs=avc1.4d401f, res=854x380, fps=24.0, supported=YES
2019-10-23 17:07:02.024 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:2, id=3, mimeType=video/avc, bitrate=7203938, codecs=avc1.4d4028, res=1280x570, fps=24.0, supported=YES
2019-10-23 17:07:02.025 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:3, id=4, mimeType=video/avc, bitrate=18316946, codecs=avc1.64002a, res=1920x856, fps=24.0, supported=YES
2019-10-23 17:07:02.025 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:     ]
2019-10-23 17:07:02.025 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   ]
2019-10-23 17:07:02.025 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   Renderer:1 [
2019-10-23 17:07:02.025 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:     Group:0, adaptive_supported=N/A [
2019-10-23 17:07:02.025 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:0, id=0, mimeType=audio/mp4a-latm, bitrate=131596, codecs=mp4a.40.2, channels=2, sample_rate=44100, language=en, supported=YES
2019-10-23 17:07:02.025 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:     ]
2019-10-23 17:07:02.025 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   ]
2019-10-23 17:07:02.025 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: ]
2019-10-23 17:07:02.029 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: mediaPeriodReadingStarted [0.14, 0.00, window=0, period=0]
2019-10-23 17:07:02.374 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: downstreamFormatChanged [0.49, 0.00, window=0, period=0, id=0, mimeType=audio/mp4a-latm, bitrate=131596, codecs=mp4a.40.2, channels=2, sample_rate=44100, language=en]
2019-10-23 17:07:02.407 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: downstreamFormatChanged [0.52, 0.00, window=0, period=0, id=4, mimeType=video/avc, bitrate=18316946, codecs=avc1.64002a, res=1920x856, fps=24.0]
2019-10-23 17:07:02.869 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderInitialized [0.98, 0.00, window=0, period=0, video, OMX.qcom.video.decoder.avc]
2019-10-23 17:07:02.870 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderInputFormatChanged [0.98, 0.00, window=0, period=0, video, id=4, mimeType=video/avc, bitrate=18316946, codecs=avc1.64002a, res=1920x856, fps=24.0]
2019-10-23 17:07:02.895 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderInitialized [1.01, 0.00, window=0, period=0, audio, OMX.google.aac.decoder]
2019-10-23 17:07:02.896 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderInputFormatChanged [1.01, 0.00, window=0, period=0, audio, id=0, mimeType=audio/mp4a-latm, bitrate=131596, codecs=mp4a.40.2, channels=2, sample_rate=44100, language=en]
2019-10-23 17:07:02.927 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: audioSessionId [1.04, 0.00, window=0, period=0, 105]
2019-10-23 17:07:02.957 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: videoSizeChanged [1.07, 0.00, window=0, period=0, 1920, 856]
2019-10-23 17:07:02.959 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: renderedFirstFrame [1.07, 0.00, window=0, period=0, Surface(name=null)/@0x47f9401]
2019-10-23 17:07:02.986 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: surfaceSizeChanged [1.10, 0.00, window=0, period=0, 1080, 482]
2019-10-23 17:07:02.989 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: state [1.10, 0.00, window=0, period=0, true, READY]
2019-10-23 17:07:17.183 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: loading [15.30, 14.11, window=0, period=0, false]
2019-10-23 17:07:23.157 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: loading [21.27, 20.08, window=0, period=0, true]
2019-10-23 17:07:23.671 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: loading [21.78, 20.59, window=0, period=0, false]
2019-10-23 17:07:31.195 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: surfaceSizeChanged [29.31, 28.12, window=0, period=0, 0, 0]
2019-10-23 17:07:32.445 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderDisabled [30.56, 29.31, window=0, period=0, video]
2019-10-23 17:07:32.446 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderDisabled [30.56, 29.31, window=0, period=0, audio]
2019-10-23 17:07:32.447 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: mediaPeriodReleased [30.56, 29.31, window=0, period=0]
2019-10-23 17:07:36.133 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: seekStarted [0.01, 0.00, window=0]
2019-10-23 17:07:36.133 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: positionDiscontinuity [0.01, 29.30, window=0, SEEK]
2019-10-23 17:07:36.136 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: state [0.01, 29.30, window=0, true, BUFFERING]
2019-10-23 17:07:36.161 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: surfaceSizeChanged [0.03, 29.30, window=0, 1080, 482]
2019-10-23 17:07:36.221 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: timelineChanged [0.09, 29.30, window=0, periodCount=1, windowCount=1, reason=PREPARED
2019-10-23 17:07:36.221 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   period [734.00]
2019-10-23 17:07:36.221 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   window [734.00, true, false]
2019-10-23 17:07:36.221 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: ]
2019-10-23 17:07:36.226 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: seekProcessed [0.10, 29.30, window=0]
2019-10-23 17:07:36.226 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: mediaPeriodCreated [0.10, 29.30, window=0, period=0]
2019-10-23 17:07:36.227 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: loading [0.10, 29.30, window=0, period=0, true]
2019-10-23 17:07:36.228 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderEnabled [0.10, 29.30, window=0, period=0, video]
2019-10-23 17:07:36.248 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderEnabled [0.12, 29.30, window=0, period=0, audio]
2019-10-23 17:07:36.249 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: tracksChanged [0.12, 29.30, window=0, period=0, 
2019-10-23 17:07:36.249 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   Renderer:0 [
2019-10-23 17:07:36.249 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:     Group:0, adaptive_supported=YES [
2019-10-23 17:07:36.249 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:0, id=1, mimeType=video/avc, bitrate=769255, codecs=avc1.42c01e, res=320x142, fps=24.0, supported=YES
2019-10-23 17:07:36.249 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:1, id=2, mimeType=video/avc, bitrate=1774254, codecs=avc1.4d401f, res=854x380, fps=24.0, supported=YES
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:2, id=3, mimeType=video/avc, bitrate=7203938, codecs=avc1.4d4028, res=1280x570, fps=24.0, supported=YES
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:3, id=4, mimeType=video/avc, bitrate=18316946, codecs=avc1.64002a, res=1920x856, fps=24.0, supported=YES
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:     ]
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   ]
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   Renderer:1 [
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:     Group:0, adaptive_supported=N/A [
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:       [X] Track:0, id=0, mimeType=audio/mp4a-latm, bitrate=131596, codecs=mp4a.40.2, channels=2, sample_rate=44100, language=en, supported=YES
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:     ]
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger:   ]
2019-10-23 17:07:36.250 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: ]
2019-10-23 17:07:36.254 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: mediaPeriodReadingStarted [0.13, 29.30, window=0, period=0]
2019-10-23 17:07:36.666 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: downstreamFormatChanged [0.54, 29.30, window=0, period=0, id=4, mimeType=video/avc, bitrate=18316946, codecs=avc1.64002a, res=1920x856, fps=24.0]
2019-10-23 17:07:36.678 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: downstreamFormatChanged [0.55, 29.30, window=0, period=0, id=0, mimeType=audio/mp4a-latm, bitrate=131596, codecs=mp4a.40.2, channels=2, sample_rate=44100, language=en]
2019-10-23 17:07:37.018 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderInitialized [0.89, 29.30, window=0, period=0, audio, OMX.google.aac.decoder]
2019-10-23 17:07:37.019 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderInputFormatChanged [0.89, 29.30, window=0, period=0, audio, id=0, mimeType=audio/mp4a-latm, bitrate=131596, codecs=mp4a.40.2, channels=2, sample_rate=44100, language=en]
2019-10-23 17:07:37.128 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderInitialized [1.00, 29.30, window=0, period=0, video, OMX.qcom.video.decoder.avc]
2019-10-23 17:07:37.128 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: decoderInputFormatChanged [1.00, 29.30, window=0, period=0, video, id=4, mimeType=video/avc, bitrate=18316946, codecs=avc1.64002a, res=1920x856, fps=24.0]
2019-10-23 17:07:37.174 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: audioSessionId [1.05, 29.30, window=0, period=0, 137]
2019-10-23 17:07:38.665 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: videoSizeChanged [2.54, 29.30, window=0, period=0, 1920, 856]
2019-10-23 17:07:38.671 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: renderedFirstFrame [2.54, 29.30, window=0, period=0, Surface(name=null)/@0x47f9401]
2019-10-23 17:07:39.227 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: state [3.10, 29.30, window=0, period=0, true, READY]
2019-10-23 17:07:43.198 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: state [7.07, 33.17, window=0, period=0, false, READY]
2019-10-23 17:07:48.364 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: state [12.24, 33.17, window=0, period=0, true, READY]
2019-10-23 17:07:49.246 10962-10962/com.google.android.exoplayer2.demo D/EventLogger: state [13.12, 34.14, window=0, period=0, false, READY]

@ojw28
Copy link
Contributor

ojw28 commented Oct 23, 2019

There's no EventLogger logging for playback suppression in 2.10.6 (see the source code). There is logging added in the dev-v2 branch (see the source code). So lack of EventLogger logging is expected if you're using 2.10.6.

I tried checking out 2.10.6 and implementing

PlayerActivity.PlayerEventListener.onPlaybackSuppressionReasonChanged(
    @PlaybackSuppressionReason int playbackSuppressionReason)

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:

player.setAudioAttributes(AudioAttributes.DEFAULT, /* handleAudioFocus= */ true);

@GouravSna
Copy link

Thanks @ojw28 . I will check the code and setAudioAttributes code.

@google google locked and limited conversation to collaborators Dec 2, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants