最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android jetpack compose - Google Cast SDK not sending media items to cast player when reconnected - Stack Overflow

programmeradmin4浏览0评论

I am using media3 exoplayer with google cast. I have implemented the casting. I am working with a composable project. Where I init the cast context in the on create of the composable. The casting seems to be working fine for the first time we open the screen.But once disconnected and reconnected the media item is not getting sent.Its showing no media is selected. Here is the class which handles the casting. When disconnected and reconnected, the cast player is not even getting the session availability call backs also. I am struggling to understand what went wrong. please help me do this.

@OptIn(UnstableApi::class)
class CastHelper(
    private val playerView: PlayerView,
    private val exoPlayer: ExoPlayer,
) {
    private lateinit var castPlayer: CastPlayer
    private lateinit var castContext: CastContext
    var mediaItem: MediaItem? = null
var isPipDisplayedInExoplayer: Boolean? = null
val pipButton: ImageButton = playerView.findViewById<ImageButton>(R.id.exo_pip_custom)

var openedFullScreen = false
var playFrom = 0L


val castPlayerListener = object : Player.Listener {
    override fun onIsLoadingChanged(isLoading: Boolean) {
        super.onIsLoadingChanged(isLoading)
        Log.d(LogTag, "CastPlayer Loading Changed $isLoading")
    }

    override fun onPlayerError(error: PlaybackException) {
        super.onPlayerError(error)
        Log.d(LogTag, "Cast Player error ${error.message}")
    }

    override fun onPlaybackStateChanged(playbackState: Int) {
        super.onPlaybackStateChanged(playbackState)
        Log.i(LogTag, "Cast Player playback state changed $playbackState")

        if (playbackState == Player.STATE_READY && isCasting() && openedFullScreen.not()) {
            openFullScreenControlsActivity()
            castPlayer.seekTo(playFrom)
        }
    }
}


val sessionAvailabilityListener = object : SessionAvailabilityListener {
    override fun onCastSessionAvailable() {
        startCastPlayer()
    }

    override fun onCastSessionUnavailable() {
        startExoPlayer()
        releaseCastPlayer()
    }

}

private fun initializeCastContext(context: Context) {
    (context as Activity).findViewById<MediaRouteButton>(R.id.exo_cast)?.apply {
        CastButtonFactory.setUpMediaRouteButton(context, this)
        dialogFactory = CustomCastThemeFactory()
    }
    castContext = CastContext.getSharedInstance(context).also {
        it.addSessionTransferCallback(
            CastSessionTransferCallback(playerView.context.applicationContext)
        )
    }
}

private fun initializeCastPlayer() {
    if (!::castContext.isInitialized) {
        throw IllegalStateException("CastContext is not initialized")
    }
    castPlayer = CastPlayer(castContext).also {
        it.setSessionAvailabilityListener(sessionAvailabilityListener)
    }
}

fun startCastPlayer() {
    // Clear previous media item if any
    castPlayer.clearMediaItems()
    playFrom = exoPlayer.currentPosition
    mediaItem?.let { item ->
        castPlayer.setMediaItem(item)
        castPlayer.addListener(castPlayerListener)
        castPlayer.prepare()
        castPlayer.playWhenReady = true
        playerView.player = castPlayer
        exoPlayer.stop()
        pipButton.isVisible(false)
        configurePosterView(shouldShow = true)
    }

}

private fun startExoPlayer() {
    mediaItem?.let { item ->
        exoPlayer.setMediaItem(item)
        exoPlayer.prepare()
        playerView.player = exoPlayer.also {
            it.seekTo(castPlayer.currentPosition)
            it.playWhenReady = true
        }
        castPlayer.stop()
        castPlayer.clearMediaItems()
        pipButton.isVisible(isPipDisplayedInExoplayer == true)
        configurePosterView(shouldShow = false)
    }
}

fun releaseCastPlayer() {
    if (::castPlayer.isInitialized) {
        castPlayer.clearMediaItems()
        castPlayer.release()
        Log.i(LogTag, "Cast Player released.")
    }
}

fun initCastMembers() {
    if (!DeviceType.isTv(playerView.context)) {
        initializeCastContext(playerView.context)
        initializeCastPlayer()
        Log.d(LogTag, "Cast Player ${getCastPlayer()}  ${isCasting()}")
    }

}

fun isCasting(): Boolean {
    val castSession = castContext.sessionManager.currentCastSession
    return castSession != null && castSession.isConnected
}

fun getCastPlayer(): CastPlayer? {
    return if (::castPlayer.isInitialized && isCasting())
        castPlayer
    else null
}

fun openFullScreenControlsActivity() {
    val context = playerView.context
    openedFullScreen = true
    context.startActivity(Intent(context, FullScreenCastControllerActivity::class.java))
}

@SuppressLint("CheckResult")
private fun configurePosterView(shouldShow: Boolean) {
    val posterUri = mediaItem?.mediaMetadata?.artworkUri
    playerView.findPosterView()?.let { poster ->
        Glide.with(poster)
            .load(posterUri)
            .error(R.drawable.logo_screen_error_placeholder)
            .into(poster)
        poster.isVisible(shouldShow)
        playerView.showController()
        playerView.controllerShowTimeoutMs = if (shouldShow) -1 else 2000
    }
}

fun keepControlViewWhenCasting() {
    playerView.doIfOnPhone {
        if (isCasting())
            playerView.showController()
    }
}

}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论