fix: radio playback "source error" on android auto (#426)

This commit is contained in:
Denis Machard 2026-02-10 05:00:33 +01:00 committed by GitHub
parent b8dc985279
commit e06a168350
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 21 deletions

View file

@ -606,20 +606,7 @@ public class AutomotiveRepository {
List<MediaItem> mediaItems = new ArrayList<>(); List<MediaItem> mediaItems = new ArrayList<>();
for (InternetRadioStation radioStation : radioStations) { for (InternetRadioStation radioStation : radioStations) {
MediaMetadata mediaMetadata = new MediaMetadata.Builder() mediaItems.add(MappingUtil.mapInternetRadioStation(radioStation));
.setTitle(radioStation.getName())
.setIsBrowsable(false)
.setIsPlayable(true)
.setMediaType(MediaMetadata.MEDIA_TYPE_RADIO_STATION)
.build();
MediaItem mediaItem = new MediaItem.Builder()
.setMediaId(radioStation.getId())
.setMediaMetadata(mediaMetadata)
.setUri(radioStation.getStreamUrl())
.build();
mediaItems.add(mediaItem);
} }
setInternetRadioStationsMetadata(radioStations); setInternetRadioStationsMetadata(radioStations);

View file

@ -3,6 +3,7 @@ package com.cappielloantonio.tempo.util
import android.content.Context import android.content.Context
import androidx.media3.common.C import androidx.media3.common.C
import androidx.media3.common.MediaItem import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import androidx.media3.common.MimeTypes import androidx.media3.common.MimeTypes
import androidx.media3.common.util.UnstableApi import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.DataSource import androidx.media3.datasource.DataSource
@ -20,10 +21,10 @@ class DynamicMediaSourceFactory(
) : MediaSource.Factory { ) : MediaSource.Factory {
override fun createMediaSource(mediaItem: MediaItem): MediaSource { override fun createMediaSource(mediaItem: MediaItem): MediaSource {
val mediaType: String? = mediaItem.mediaMetadata.extras?.getString("type", "") val mediaId = mediaItem.mediaId
val streamingCacheSize = Preferences.getStreamingCacheSize() val streamingCacheSize = Preferences.getStreamingCacheSize()
val bypassCache = mediaType == Constants.MEDIA_TYPE_RADIO val bypassCache = mediaId.startsWith("ir-")
val useUpstream = when { val useUpstream = when {
streamingCacheSize.toInt() == 0 -> true streamingCacheSize.toInt() == 0 -> true

View file

@ -32,6 +32,7 @@ import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_REPEAT_MO
import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_OFF
import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON import com.cappielloantonio.tempo.util.Constants.CUSTOM_COMMAND_TOGGLE_SHUFFLE_MODE_ON
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import com.cappielloantonio.tempo.util.Constants
import com.cappielloantonio.tempo.util.Preferences import com.cappielloantonio.tempo.util.Preferences
import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.Futures
import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.ListenableFuture
@ -366,13 +367,33 @@ open class MediaLibrarySessionCallback(
controller: MediaSession.ControllerInfo, controller: MediaSession.ControllerInfo,
mediaItems: List<MediaItem> mediaItems: List<MediaItem>
): ListenableFuture<List<MediaItem>> { ): ListenableFuture<List<MediaItem>> {
return super.onAddMediaItems( val firstItem = mediaItems.firstOrNull()
mediaSession, val isRadio = firstItem?.mediaId?.startsWith("ir-") == true
controller,
MediaBrowserTree.getItems(mediaItems) if (isRadio) {
return Futures.transformAsync(
automotiveRepository.internetRadioStations,
{ result ->
val stations = result?.value
val selected = stations?.find { it.mediaId == firstItem?.mediaId }
if (selected != null) {
val updatedSelected = selected.buildUpon()
.setMimeType(selected.localConfiguration?.mimeType)
.build()
Futures.immediateFuture(listOf(updatedSelected))
} else {
Futures.immediateFuture(emptyList())
}
},
androidx.core.content.ContextCompat.getMainExecutor(context)
) )
} }
val resolvedItems = MediaBrowserTree.getItems(mediaItems)
return super.onAddMediaItems(mediaSession, controller, resolvedItems)
}
override fun onSearch( override fun onSearch(
session: MediaLibraryService.MediaLibrarySession, session: MediaLibraryService.MediaLibrarySession,
browser: MediaSession.ControllerInfo, browser: MediaSession.ControllerInfo,