在Android Media3 MediaSessionService中如何指定HLS流媒体源

问题描述 投票:0回答:1

显然,我们只能将 HLS 媒体源设置为 ExoPlayer,而不是 Activity/Composable 中的 MediaController。有没有办法将 URL 和令牌传递给服务以便可以使用 HLSMediaSource 工厂?即使这样,也不知道下次如何播放不同的源?

class PlaybackService : MediaSessionService() {
    private var mediaSession: MediaSession? = null

    override fun onCreate() {
        super.onCreate()

        val dataSourceFactory = DataSource.Factory {
            val dataSource = DefaultHttpDataSource.Factory().createDataSource()
            dataSource.setRequestProperty("Authorization", token) // <-- HOW TO PASS TOKEN TO SERVICE?
            dataSource
        }

        val mediaSourceFactory = HlsMediaSource.Factory(dataSourceFactory)
            .createMediaSource(MediaItem.fromUri(url)) // <-- HOW TO PASS HLS STREAMING URL TO SERVICE?

        val player = ExoPlayer.Builder(this)
            .setMediaSourceFactory(
                DefaultMediaSourceFactory(this)
                    .setDataSourceFactory(dataSourceFactory),
            )
            .build()

        mediaSession = MediaSession.Builder(this, player)
            .build()
    }

    override fun onBind(intent: Intent?): IBinder? {
        return super.onBind(intent)
    }

    override fun onTaskRemoved(rootIntent: Intent?) {
        mediaSession?.player?.let { player ->
            if (!player.playWhenReady || player.mediaItemCount == 0) {
                stopSelf()
            }
        }
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? {
        return mediaSession
    }
}

对应的Composable代码,如何从这里传递URL和token?

    val sessionToken = SessionToken(context, ComponentName(context, PlaybackService::class.java))
    val controllerFuture = MediaController.Builder(context, sessionToken).buildAsync()

我在 Android Jetpack Compose Media3 HLS Stream withplaying service 中也有一个从可组合角度来看的相关问题。

android-mediaplayer exoplayer android-mediasession android-media3 exoplayer-media-item
1个回答
0
投票

您可以使用如下所示的服务意图。

传递身份验证密钥与 media3 主题不同。 这取决于您的安全设计。对于演示,您可以从钥匙串或本地存储加载。

播放服务.kt

class PlaybackService: MediaSessionService() {

    private var mediaSession: MediaSession? = null
    private var player: ExoPlayer? = null

    override fun onCreate() {
        super.onCreate()
        player = ExoPlayer.Builder(applicationContext)
            .build()
        mediaSession = MediaSession.Builder(applicationContext, player!!)
            .build()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Timber.d("onStartCommand:$intent")
        when (intent?.action) {
            "playSample" -> {
                intent.getStringExtra("url")?.let { url ->
                    Timber.d("url:$url")
                    val authorization = "" // load from keystore or app local storage.
                    player?.setMediaSource(createHlsMediaSource(url, authorization))
                }
            }
            "stop" -> player?.stop()
            else -> {}
        }
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? {
        return mediaSession
    }

    private fun createHlsMediaSource(url: String, authorization: String): MediaSource {
        val dataSourceFactory = DefaultHttpDataSource.Factory()
            .setDefaultRequestProperties(
                mapOf(
                    "Authorization" to authorization
                )
            )
        return HlsMediaSource.Factory(dataSourceFactory)
            .createMediaSource(MediaItem.fromUri(url))
    }
}```
© www.soinside.com 2019 - 2024. All rights reserved.