gpt4 book ai didi

安卓汽车 : Media item gets stuck "Getting your selection..." instead of showing controls while playing

转载 作者:行者123 更新时间:2023-12-05 04:25:05 26 4
gpt4 key购买 nike

我有一个实现 MediaBrowserServiceCompat()PlaybackService.kt 类,因为它是 Android Auto 支持所必需的。播放器本身在应用程序内运行良好。该应用 95% 用于几个不同 channel 之间的 HLS 流(5% 是音频样本文件)。

我可以成功获取我的 Root View ,它是一个简单的 channel 列表(“直播”、“80 年代”、“90 年代”等),当我单击其中一个时,音频开始播放,但我卡在了“正在获取您的选择...”屏幕,如下所示。查看logcat,没有报错。有一点可能很奇怪,也可能很正常,onGetRoot 在选择 channel 后再次调用。

Android Auto error

这是我的整个 PlaybackService.kt 文件。

package <my-package>.audio.service

import android.app.Notification
import android.app.PendingIntent
import android.content.Intent
import android.content.res.Configuration
import android.net.Uri
import android.os.Binder
import android.os.Bundle
import android.os.IBinder
import android.os.ResultReceiver
import android.support.v4.media.MediaBrowserCompat
import android.support.v4.media.MediaDescriptionCompat
import android.support.v4.media.MediaMetadataCompat
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import android.util.Log
import androidx.annotation.MainThread
import androidx.core.content.ContextCompat
import androidx.media.MediaBrowserServiceCompat
import androidx.media.session.MediaButtonReceiver
import <my-package>.MainActivity
import <my-package>.R
import <my-package>.audio.api.ChannelApi
import <my-package>.audio.api.StreamApi
import <my-package>.audio.models.NetworkChannel
import <my-package>.audio.models.State
import <my-package>.audio.utils.StorageHelper
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.WritableMap
import com.facebook.react.modules.core.DeviceEventManagerModule
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.audio.AudioAttributes
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.metadata.id3.TextInformationFrame
import com.google.android.exoplayer2.metadata.id3.UrlLinkFrame
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import com.google.android.exoplayer2.util.MimeTypes
import com.npaw.youbora.lib6.exoplayer2.Exoplayer2Adapter
import com.npaw.youbora.lib6.plugin.Options
import com.npaw.youbora.lib6.plugin.Plugin
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import java.util.*

open class PlaybackService : MediaBrowserServiceCompat() {
var reactContext: ReactContext? = null
private val binder = PlaybackBinder()
private val scope = MainScope()
private var sourceUrl: String? = null

private var isForegroundService = false

private val playerListener = playerListener()

private val playbackAudioAttributes = AudioAttributes.Builder()
.setContentType(C.AUDIO_CONTENT_TYPE_MUSIC)
.setUsage(C.USAGE_MEDIA)
.build()

private val player: ExoPlayer by lazy {
ExoPlayer.Builder(this).build().apply {
setAudioAttributes(playbackAudioAttributes, true)
setHandleAudioBecomingNoisy(true)
setWakeMode(C.WAKE_MODE_NETWORK)
addListener(playerListener)
setPlaybackSpeed(1.0f)
playWhenReady = true
}
}

private val youboraOptions = Options()
private lateinit var youboraPlugin: Plugin

private lateinit var notificationManager: NotificationManager
private lateinit var mediaSession: MediaSessionCompat
private lateinit var mediaSessionConnector: MediaSessionConnector

private var autoStations: List<NetworkChannel>? = null

private lateinit var appName: String

// START: Audio Module actions
fun play(streamName: String){
Log.d(TAG, "Processing stream: $streamName")
youboraOptions.contentChannel = streamName
buildStreamAndPlay(streamName)
}

fun playHook(hookUri: String, songTitle: String, artistName: String){
Log.d(TAG, "Process hook file: $hookUri")
youboraOptions.contentTitle = "$songTitle-$artistName"
buildMediaAndPlay(hookUri)
}

fun stop(){
Log.d(TAG, "Stopping stream.")
player.stop()
player.clearMediaItems()
}

fun getPlaybackState(): Int {
return player.playbackState
}
// END: Audio Module actions

override fun onCreate() {
Log.d(TAG, "onCreate")
super.onCreate()

appName = applicationContext.getString(R.string.app_name)

val sessionActivityPendingIntent = PendingIntent.getActivity(
/* context = */ reactContext ?: applicationContext,
/* requestCode = */ 0,
/* intent = */ Intent(reactContext ?: applicationContext, MainActivity::class.java),
/* flags = */ PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)

mediaSession = MediaSessionCompat(this, TAG).apply {
setSessionActivity(sessionActivityPendingIntent)
isActive = true
}

sessionToken = mediaSession.sessionToken

notificationManager = NotificationManager(
this,
mediaSession.sessionToken,
PlayerNotificationListener()
)

mediaSessionConnector = MediaSessionConnector(mediaSession)
mediaSessionConnector.setPlaybackPreparer(AudioServicePreparer())
mediaSessionConnector.setPlayer(player)

notificationManager.showNotificationForPlayer(player)
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(TAG, "onStartCommand")
MediaButtonReceiver.handleIntent(mediaSession, intent)
return START_STICKY
}

override fun onBind(intent: Intent?): IBinder {
if (intent != null) {
if(SERVICE_INTERFACE == intent.action){
return super.onBind(intent)!!
}
}
return binder
}

override fun onTaskRemoved(rootIntent: Intent?) {
super.onTaskRemoved(rootIntent)
player.stop()
player.clearMediaItems()
}

override fun onGetRoot(
clientPackageName: String,
clientUid: Int,
rootHints: Bundle?
): BrowserRoot? {
Log.d(TAG, "onGetRoot called")
return BrowserRoot(MEDIA_ROOT_ID, null)
}

override fun onLoadChildren(
parentId: String,
result: Result<List<MediaBrowserCompat.MediaItem>>
) {
Log.d(TAG, "OnLoadChildren: parentMediaId = $parentId")

if(EMPTY_MEDIA_ROOT_ID == parentId){
result.sendResult(null)
return
}

val mediaItems: MutableList<MediaBrowserCompat.MediaItem> = mutableListOf()

if(MEDIA_ROOT_ID == parentId){
// Build list of channels
Log.d(TAG, "Building root items")
if (autoStations != null) {
Log.d(TAG, "Channels exist, creating media items...")
for (i in 0 until autoStations!!.size) {
val station = autoStations!![i]
val mediaItem = createMediaItem(station)
if (mediaItem != null) {
mediaItems.add(mediaItem)
}
}
result.sendResult(mediaItems)
} else {
Log.d(TAG, "Making call to get channels...")
result.detach()
scope.launch {
try {
autoStations = ChannelApi.retrofitService.getChannels()

if (autoStations!!.isNotEmpty()) {
Log.d(TAG, "Stations fetched, creating media items...")
for (station in autoStations!!) {
val mediaItem = createMediaItem(station)
if (mediaItem != null) {
mediaItems.add(mediaItem)
}
}
result.sendResult(mediaItems)
}else{
useFallbackStation()
}
} catch (err: Exception) {
Log.e(TAG, "Failed to get channels from API. Reason: ${err.message}")
result.sendResult(mediaItems)
}
}
}
} else{
result.sendResult(mediaItems)
}
}

private fun createMediaItem(station: NetworkChannel): MediaBrowserCompat.MediaItem? {
return try {
val description = MediaDescriptionCompat.Builder()
.setMediaId(station.streamName)
.setTitle(station.title)

val isDarkMode = (reactContext ?: applicationContext).resources.configuration.uiMode == Configuration.UI_MODE_NIGHT_YES

if (isDarkMode) {
description.setIconUri(
Uri.parse("<my-cdn>" + station.streamName + "/album-md.png")
)
} else {
description.setIconUri(
Uri.parse("<my-cdn>" + station.streamName + "/album-md-dark.png")
)
}

MediaBrowserCompat.MediaItem(
description.build(),
MediaBrowserCompat.MediaItem.FLAG_PLAYABLE
)
} catch (ex: Exception) {
null
}
}

private fun useFallbackStation() {
autoStations = List(1) {
NetworkChannel(
channelId = 5,
title = appName,
streamName = appName.lowercase(Locale.getDefault()),
slug = "live",
inactiveOn = null
)
}
}

override fun onDestroy() {
scope.cancel()

mediaSession.run {
isActive = false
release()
}

player.removeListener(playerListener)
player.release()

super.onDestroy()
}

private fun playStream(){
Log.d(TAG, "playStream - sourceUrl: $sourceUrl")
player.clearMediaItems()

val mediaItem = MediaItem.Builder()
.setUri(sourceUrl)
.setMimeType(MimeTypes.APPLICATION_M3U8)
.setLiveConfiguration(
MediaItem.LiveConfiguration.Builder()
.setMaxPlaybackSpeed(1.02f)
.build()
)
.build()

// Testing adding metadata for AA issue, no change...
mediaSession.setMetadata(MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, "Test 1")
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "Test 2")
.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, -1)
.build())

if (player.isPlaying || player.isLoading) {
stop()
}

player.addMediaItem(mediaItem)
player.prepare()
}

private fun buildStreamAndPlay(streamName: String) {
scope.launch {
sourceUrl = StreamApi.retrofitService.getStreamUrl(
mapOf(
"encoding" to "hls",
"platform" to "android",
"network" to streamName,
)
).data.streamUrl

Log.d(TAG, "Got stream url: $sourceUrl")

playStream()
}
}

private fun buildMediaAndPlay(hookUri: String) = scope.launch {
val userData = StorageHelper.getUserData(reactContext ?: applicationContext)

if(!::youboraPlugin.isInitialized && reactContext != null){
youboraPlugin = Plugin(youboraOptions, reactContext)
youboraPlugin.activity = reactContext?.currentActivity

Exoplayer2Adapter(player)
.also { adapter ->
youboraPlugin.adapter = adapter
}
}

if (player.isPlaying == true || player.isLoading == true) {
stop()
}

val mediaItem = MediaItem.Builder()
.setUri(hookUri)
.build()

player.addMediaItem(mediaItem)
player.prepare()
player.play()
}

@MainThread
private fun playerListener() = object: Player.Listener {
override fun onPlaybackStateChanged(playbackState: Int) {
val state: State = when (playbackState){
ExoPlayer.STATE_IDLE -> State.Idle
ExoPlayer.STATE_BUFFERING -> State.Buffering
ExoPlayer.STATE_READY -> State.Ready
ExoPlayer.STATE_ENDED -> State.Stopped
else -> State.Stopped
}

if(state != State.Buffering){
notificationManager.hideNotification()
}

Log.d(TAG, "PlayerState: $state")
sendEvent(EVENT_PLAYER_STATE, state.state )
}

override fun onIsPlayingChanged(isPlaying: Boolean) {
if(isPlaying) {
Log.d(TAG, "PlayerState: Playing")
notificationManager.showNotificationForPlayer(player)
sendEvent(EVENT_PLAYER_STATE, State.Playing.state)
}else{
Log.d(TAG, "PlayerState: Paused (Stopping and clearing)")
sendEvent(EVENT_PLAYER_STATE, State.Paused.state)
player.stop()
player.clearMediaItems()
}
}

override fun onPlayerError(error: PlaybackException) {
sendEvent(EVENT_PLAYER_STATE, State.Error.state)
super.onPlayerError(error)
}

override fun onMetadata(metadata: com.google.android.exoplayer2.metadata.Metadata) {
var handled = false

var id: String? = null
var title: String? = null
var artist: String? = null
var isBreak = false

Log.d(TAG, "Raw Meta: $metadata")

(0 until metadata.length()).forEach { i ->
when (val entry = metadata[i]) {
is TextInformationFrame -> {
when (entry.id.uppercase()) {
"TIT2", "TT2" -> {
if(entry.value.isNotEmpty()){ // Added to due current bug with empty metadata
handled = true
title = entry.value
}
}
"TOPE", "TPE1", "TP1" -> {
handled = true
artist = entry.value
}
"TUID" -> {
handled = true
id = entry.value
}
}
}
is UrlLinkFrame -> {
when (entry.id.uppercase()) {
"WXXX" -> {
handled = true
if (id == null) {
id = entry.url
}
}
}
}
}
}

if (handled){
try {
UUID.fromString(id)
} catch (ignored: Exception) {
Log.d(TAG, "Detected stream break.")
id = null
isBreak = true
}

notificationManager.currentArtist = artist.toString()
notificationManager.currentSong = title.toString()

youboraOptions.contentTitle = "$title-$artist"
youboraOptions.contentId = "$id"

youboraOptions.contentBitrate = player.audioFormat?.bitrate?.toLong()

Arguments.createMap().apply {
putString("id", id)
putString("title", title)
putString("artist", artist)
putBoolean("isBreak", isBreak)
sendEvent(EVENT_METADATA, this)
}
}
}
}

private fun sendEvent(eventName: String, params: WritableMap?){
reactContext?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit(eventName, params)
}

private fun sendEvent(eventName: String, eventValue: String){
reactContext?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
?.emit(eventName, eventValue)
}

inner class PlaybackBinder: Binder(){
val service = this@PlaybackService
}

/**
* Listen for notification events.
*/
private inner class PlayerNotificationListener :
PlayerNotificationManager.NotificationListener {
override fun onNotificationPosted(
notificationId: Int,
notification: Notification,
ongoing: Boolean
) {
if (ongoing && !isForegroundService) {
ContextCompat.startForegroundService(
applicationContext,
Intent(applicationContext, this@PlaybackService.javaClass)
)

startForeground(notificationId, notification)
isForegroundService = true
}
}

override fun onNotificationCancelled(notificationId: Int, dismissedByUser: Boolean) {
stopForeground(true)
isForegroundService = false
stopSelf()
}
}

private inner class AudioServicePreparer: MediaSessionConnector.PlaybackPreparer {
override fun onCommand(
player: Player,
command: String,
extras: Bundle?,
cb: ResultReceiver?
): Boolean = false

override fun getSupportedPrepareActions(): Long =
PlaybackStateCompat.ACTION_PREPARE_FROM_MEDIA_ID or
PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID or
PlaybackStateCompat.ACTION_PREPARE_FROM_SEARCH or
PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH


override fun onPrepare(playWhenReady: Boolean) {
Log.d(TAG, "[AudioServicePreparer] - onPrepare")
// TODO: Should get last played station
onPrepareFromMediaId("<default-media-id>", playWhenReady, null)
}

override fun onPrepareFromMediaId(
mediaId: String,
playWhenReady: Boolean,
extras: Bundle?
) {
Log.d(TAG, "[AudioServicePreparer] - onPrepareFromMediaId - $mediaId - playWhenReady? $playWhenReady")
player.playWhenReady = playWhenReady
play(mediaId)
}

override fun onPrepareFromSearch(query: String, playWhenReady: Boolean, extras: Bundle?) {
Log.d(TAG, "[AudioServicePreparer] - onPrepareFromSearch")
// TODO: Should search for station
play("<default-media-id>")
}

override fun onPrepareFromUri(uri: Uri, playWhenReady: Boolean, extras: Bundle?) = Unit
}

companion object {
const val TAG = "PlaybackService"

const val EVENT_PLAYER_STATE = "onPlayerStateChanged"
const val EVENT_METADATA = "onMetadataReceived"

private const val MEDIA_ROOT_ID = "my_root"
private const val EMPTY_MEDIA_ROOT_ID = "my_empty_root"
}
}

在 Android Auto 中选择站点时的 Logcat 输出:

2022-11-22 17:11:08.293  2264-2264  PlaybackService         <my-package>                        D  [AudioServicePreparer] - onPrepareFromMediaId - <stream-name> - playWhenReady? true
2022-11-22 17:11:08.304 2264-2264 PlaybackService <my-package> D Processing stream: <stream-name>
2022-11-22 17:11:08.305 2264-2264 PlaybackService <my-package> D playStream - sourceUrl: <valid-url>
2022-11-22 17:11:08.395 2264-2264 PlaybackService <my-package> D PlayerState: Buffering
2022-11-22 17:11:08.397 2264-2476 ReactNativeJS <my-package> I 'STATE:', 'buffering'
2022-11-22 17:11:11.102 2264-2521 DMCodecAdapterFactory <my-package> I Creating an asynchronous MediaCodec adapter for track type audio
2022-11-22 17:11:11.105 2264-9864 CCodec <my-package> I state->set(ALLOCATING)
2022-11-22 17:11:11.105 2264-9864 CCodec <my-package> I allocate(c2.android.aac.decoder)
2022-11-22 17:11:11.111 2264-9864 CCodec <my-package> I setting up 'default' as default (vendor) store
2022-11-22 17:11:11.114 2264-9864 CCodec <my-package> I Created component [c2.android.aac.decoder]
2022-11-22 17:11:11.114 2264-9864 CCodec <my-package> I state->set(ALLOCATED)
2022-11-22 17:11:11.115 2264-9864 CCodecConfig <my-package> D read media type: audio/mp4a-latm
2022-11-22 17:11:11.123 2264-9864 CCodecConfig <my-package> I query failed after returning 19 values (BAD_INDEX)
2022-11-22 17:11:11.124 2264-9864 MediaCodec <my-package> I MediaCodec will operate in async mode
2022-11-22 17:11:11.125 2264-9864 CCodec <my-package> D [c2.android.aac.decoder] buffers are bound to CCodec for this session
2022-11-22 17:11:11.125 2264-9864 CCodec <my-package> I appPid(2264) width(0) height(0)
2022-11-22 17:11:11.125 2264-9864 CCodecConfig <my-package> D no c2 equivalents for log-session-id
2022-11-22 17:11:11.125 2264-9864 CCodecConfig <my-package> D no c2 equivalents for flags
2022-11-22 17:11:11.126 2264-9864 CCodecConfig <my-package> D c2 config diff is c2::u32 raw.channel-count.value = 2
2022-11-22 17:11:11.126 2264-9864 Codec2Client <my-package> W query -- param skipped: index = 1107298332.
2022-11-22 17:11:11.126 2264-9864 CCodecConfig <my-package> I query failed after returning 19 values (BAD_INDEX)
2022-11-22 17:11:11.127 2264-2521 MediaCodec <my-package> D keep callback message for reclaim
2022-11-22 17:11:11.128 2264-9864 CCodec <my-package> I state->set(STARTING)
2022-11-22 17:11:11.132 2264-9864 Codec2Client <my-package> W query -- param skipped: index = 1342179345.
2022-11-22 17:11:11.132 2264-9864 Codec2Client <my-package> W query -- param skipped: index = 2415921170.
2022-11-22 17:11:11.132 2264-9864 Codec2Client <my-package> W query -- param skipped: index = 1610614798.
2022-11-22 17:11:11.135 2264-9864 CCodec <my-package> I state->set(RUNNING)
2022-11-22 17:11:11.135 2264-9864 CCodecBufferChannel <my-package> I [c2.android.aac.decoder#96] 4 initial input buffers available
2022-11-22 17:11:11.136 2264-2980 BufferPoolAccessor2.0 <my-package> D bufferpool2 0xb40000701ca21d68 : 0(0 size) total buffers - 0(0 size) used buffers - 3845/3850 (recycle/alloc) - 5/3845 (fetch/transfer)
2022-11-22 17:11:11.136 2264-2980 BufferPoolAccessor2.0 <my-package> D Destruction - bufferpool2 0xb40000701ca21d68 cached: 0/0M, 0/0% in use; allocs: 3850, 100% recycled; transfers: 3845, 100% unfetched
2022-11-22 17:11:11.140 2264-2264 PlaybackService <my-package> D PlayerState: Ready
2022-11-22 17:11:11.141 2264-2476 ReactNativeJS <my-package> I 'STATE:', 'ready'
2022-11-22 17:11:11.147 2264-2264 PlaybackService <my-package> D PlayerState: Playing
2022-11-22 17:11:11.148 2264-2264 PlaybackService <my-package> D Raw Meta: entries=[PRIV: owner=com.apple.streaming.transportStreamTimestamp]
2022-11-22 17:11:11.149 2264-2264 PlaybackService <my-package> D Raw Meta: entries=[TIT2: description=null: value=]
2022-11-22 17:11:11.154 2264-9864 CCodecConfig <my-package> D c2 config diff is c2::u32 raw.channel-mask.value = 12
2022-11-22 17:11:11.163 2264-2264 PlaybackService <my-package> D onStartCommand
2022-11-22 17:11:11.172 2264-2521 AudioTrack <my-package> D setVolume(1.000000, 1.000000) pid : 2264
2022-11-22 17:11:11.238 2264-2521 AudioTrack <my-package> D getTimestamp_l(74): device stall time corrected using current time 2384346281016
2022-11-22 17:11:11.274 2264-2476 ReactNativeJS <my-package> I 'STATE:', 'playing'
2022-11-22 17:11:11.372 2264-2476 ReactNativeJS <my-package> I Metadata is undefined
2022-11-22 17:11:12.523 2264-2476 ReactNativeJS <my-package> I Token is not expired
2022-11-22 17:11:12.651 2264-2478 RNFBCrashlyticsInit <my-package> D isCrashlyticsCollectionEnabled via RNFBJSON: true
2022-11-22 17:11:12.652 2264-2478 RNFBCrashlyticsInit <my-package> D isCrashlyticsCollectionEnabled after checking crashlytics_debug_enabled: false
2022-11-22 17:11:12.652 2264-2478 RNFBCrashlyticsInit <my-package> D isCrashlyticsCollectionEnabled final value: false
2022-11-22 17:11:14.406 2264-2977 CCodecBufferChannel <my-package> D [c2.android.aac.decoder#96] DEBUG: elapsed: n=6 [in=0 pipeline=0 out=2]
2022-11-22 17:11:16.930 2264-2264 ViewRootIm...nActivity] <my-package> I ViewPostIme pointer 0
2022-11-22 17:11:17.069 2264-2264 ViewRootIm...nActivity] <my-package> I ViewPostIme pointer 1
2022-11-22 17:11:17.082 2264-2264 PlaybackService <my-package> D Stopping stream.
2022-11-22 17:11:17.086 2264-9864 CCodec <my-package> I state->set(FLUSHING)
2022-11-22 17:11:17.086 2264-9864 CCodec <my-package> I state->set(FLUSHED)
2022-11-22 17:11:17.087 2264-2521 MediaCodec <my-package> D keep callback message for reclaim
2022-11-22 17:11:17.087 2264-9864 CCodec <my-package> I state->set(RESUMING)
2022-11-22 17:11:17.087 2264-9864 CCodecConfig <my-package> I query failed after returning 19 values (BAD_INDEX)
2022-11-22 17:11:17.088 2264-9864 CCodec <my-package> I state->set(RUNNING)
2022-11-22 17:11:17.089 2264-9864 CCodec <my-package> I state->set(RELEASING)
2022-11-22 17:11:17.090 2264-9929 CCodec <my-package> I state->set(RELEASED)
2022-11-22 17:11:17.090 2264-9864 hw-BpHwBinder <my-package> I onLastStrongRef automatically unlinking death recipients
2022-11-22 17:11:17.090 2264-9864 MediaCodec <my-package> I Codec shutdown complete
2022-11-22 17:11:17.095 2264-2264 PlaybackService <my-package> D PlayerState: Idle
2022-11-22 17:11:17.097 2264-2476 ReactNativeJS <my-package> I 'STATE:', 'idle'
2022-11-22 17:11:17.097 2264-2264 PlaybackService <my-package> D PlayerState: Paused (Stopping and clearing)
2022-11-22 17:11:17.201 2264-2476 ReactNativeJS <my-package> I 'STATE:', 'paused'
2022-11-22 17:11:22.137 2264-2979 BufferPoolAccessor2.0 <my-package> D bufferpool2 0xb40000701c6606a8 : 0(0 size) total buffers - 0(0 size) used buffers - 311/316 (recycle/alloc) - 5/311 (fetch/transfer)
2022-11-22 17:11:22.137 2264-2979 BufferPoolAccessor2.0 <my-package> D evictor expired: 1, evicted: 1

流式传输时媒体 session 转储的 Pastebin: https://pastebin.com/5is1h2Mk

如果您认为有任何其他文件可能有助于找到答案,我会尝试提供,但我必须清理一些东西。

最佳答案

我遇到了同样的事情。您在媒体 session 上的播放状态需要调用 setState。您只是在设置播放操作。

关于安卓汽车 : Media item gets stuck "Getting your selection..." instead of showing controls while playing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73340801/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com