显然,我们只能将 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 中也有一个从可组合角度来看的相关问题。
您可以使用如下所示的服务意图。
传递身份验证密钥与 media3 主题不同。 这取决于您的安全设计。对于演示,您可以从钥匙串或本地存储加载。
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))
}
}```