ExoPlayer icon indicating copy to clipboard operation
ExoPlayer copied to clipboard

How to correctly map internet radio stream metadata to Android notifications and now playing (Assistant, Bluetooth A2DP)?

Open fourofspades opened this issue 3 years ago • 2 comments
trafficstars

Been struggling with this problem for a very long time.

My Android app uses the Exoplayer (always latest build), to stream internet radio. I'm having real problems trying to get the audio metadata to map correctly to the Android notification correctly. This also causes issues with things like Google Assistant ("OK google, what's playing" will tell me the station name, not the track info". Also issues with what's displayed over Bluetooth A2DP on Android Auto and similar.

It doesn't help that there isn't a good example of audio streaming, and I haven't found anything in a github code search that does this correctly either.

fourofspades avatar Jul 06 '22 08:07 fourofspades

Please provide an example of an internet radio stream that I can use to reproduce the problem.

icbaker avatar Jul 15 '22 13:07 icbaker

Sure, here is an example audio stream;.

http://cast1.asurahosting.com:8621/med

fourofspades avatar Jul 15 '22 13:07 fourofspades

It's not clear from your report how you're currently building the notification. I played the stream provided in the demo app and I saw the title emitted via an IcyInfo entry in Player.Listener.onMetadata - so you could subscribe to that to update your notification.

I was also able to get the IcyInfo to come out of Player.Listener.onMediaMetadata (which is easier to consume because you don't need to cast), but in the demo app I needed to first comment out the setMediaMetadata call here, because ExoPlayer assumes that developer-provided metadata should override stream-provided metadata (so the title from the IcyInfo is never set into MediaMetadata, and so it never changes and the callback is never called):

https://github.com/google/ExoPlayer/blob/ab4d37f499ba49bb3cac7938eb03ebf7133ccfe6/demos/main/src/main/java/com/google/android/exoplayer2/demo/IntentUtil.java#L130

icbaker avatar Oct 06 '22 14:10 icbaker

Perhaps I'm missing something here. The Demo app doesn't seem to implement notifications. And it's the wiring of exoplayer to android subsystem that is causing me the main.

I'm implementing PlayerNotificationManager.MediaDescriptionAdapter to handle my notifications, and my code looks like this:

https://pastebin.com/fzkkEKNJ

I can't find any code that correctly maps Android notifications to audio streams that include metadata for track playing and allow my app itself to set the station name.

fourofspades avatar Oct 06 '22 17:10 fourofspades

I'm implementing PlayerNotificationManager.MediaDescriptionAdapter to handle my notifications, and my code looks like this:

https://pastebin.com/fzkkEKNJ

Your implementation of MediaDescriptionAdapter.getCurrentTItle looks roughly right, and when I try this it shows the song title in the notification:

@Override
public CharSequence getCurrentContentTitle(Player player) {
  @Nullable CharSequence title = player.getMediaMetadata().title;
  return title != null ? title : "no title set";
}

This only works because I'm not setting MediaMetadata.title when configuring the MediaItem (as described above). If this value is set at this point, then the title from the stream is ignored.

icbaker avatar Oct 07 '22 09:10 icbaker

Hi, does this work in Google Assistant when you ask it's what's playing? Does it show the correct track information on a bluetooth connection? Does it show the correct track information on a Google Pixel lock screen?

I have spent another day running around in circles on this, and getting absolutely nowhere. I can get a notification showing track and stream name, but I can't get it to propagate any deeper in the OS services.

Is there any news on a working demo that implements notifications, background services and metadata handling?

fourofspades avatar Oct 10 '22 15:10 fourofspades

Is there any news on a working demo that implements notifications, background services and metadata handling?

You may find it easier to use media3 rather than ExoPlayer (media3 is a superset of ExoPlayer), because it has much cleaner integration with media sessions, which is what controls the metadata used by Google Assistant and bluetooth connections.

https://developer.android.com/jetpack/androidx/releases/media3

https://android-developers.googleblog.com/2021/10/jetpack-media3.html

https://medium.com/google-exoplayer/jetpack-media3-1-0-0-beta01-whats-new-2367a712f112

https://github.com/androidx/media

icbaker avatar Oct 24 '22 10:10 icbaker

I'm going to close this because it looks like you're getting media3 help in e.g. https://github.com/androidx/media/issues/197

icbaker avatar Nov 10 '22 10:11 icbaker