You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过UI借助MediaBrowserServiceCompat控制ExoPlayer播放速度

ExoPlayer播放速度控制指令传递至MediaBrowserServiceCompat的实现方案

一、UI界面传递控制指令的实现步骤

1. UI层发送自定义控制指令

通过MediaControllerCompat向MediaBrowserServiceCompat发送自定义命令,携带播放速度参数:

// 在Activity/Fragment中获取MediaController实例
val mediaController = MediaControllerCompat.getMediaController(this)

// 用户调整速度时触发,比如点击1.5倍速按钮
val targetSpeed = 1.5f
mediaController.sendCommand(
    "cmd_set_playback_speed",
    Bundle().apply { putFloat("param_speed", targetSpeed) },
    null // 无需回调时传null
)

2. Service层处理指令并控制ExoPlayer

在MediaBrowserServiceCompat的MediaSessionCompat.Callback中重写onCommand方法,接收并处理速度控制指令:

private val mediaSessionCallback = object : MediaSessionCompat.Callback() {
    override fun onCommand(command: String?, extras: Bundle?, cb: ResultReceiver?) {
        when (command) {
            "cmd_set_playback_speed" -> {
                val speed = extras?.getFloat("param_speed", 1.0f) ?: 1.0f
                // 控制ExoPlayer调整播放速度
                exoPlayer?.setPlaybackSpeed(speed)
                // 更新播放状态,同步到UI
                updatePlaybackState()
            }
        }
        super.onCommand(command, extras, cb)
    }
}

// 更新播放状态的方法
private fun updatePlaybackState() {
    val playbackStateBuilder = PlaybackStateCompat.Builder()
        // 设置基础播放状态(如播放/暂停、进度等)
        .setState(
            if (exoPlayer?.isPlaying == true) PlaybackStateCompat.STATE_PLAYING else PlaybackStateCompat.STATE_PAUSED,
            exoPlayer?.currentPosition ?: 0,
            exoPlayer?.playbackSpeed ?: 1.0f // API 26+支持直接设置速度字段
        )
        // 兼容API 26以下版本,通过extras传递速度信息
        .setExtras(Bundle().apply {
            putFloat("extra_current_speed", exoPlayer?.playbackSpeed ?: 1.0f)
        })
    
    mediaSession.setPlaybackState(playbackStateBuilder.build())
}

3. UI层同步播放状态(显示当前速度)

注册MediaControllerCompat.Callback监听播放状态变化,获取当前速度并更新UI:

mediaController.registerCallback(object : MediaControllerCompat.Callback() {
    override fun onPlaybackStateChanged(state: PlaybackStateCompat?) {
        state?.let {
            // 优先使用API 26+的原生速度字段
            val currentSpeed = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                it.playbackSpeed
            } else {
                it.extras?.getFloat("extra_current_speed", 1.0f) ?: 1.0f
            }
            // 更新UI显示,比如TextView显示"1.5x"
            speedDisplayTv.text = String.format("%.1fx", currentSpeed)
        }
    }
})

二、Android系统的常规解决方案

Android系统原生的MediaSessionCompat/TransportControls并没有提供直接的播放速度控制API,常规的解决方案是通过自定义命令扩展播放控制逻辑,这也是官方推荐的扩展方式。

针对API 26(Android 8.0)及以上版本,PlaybackStateCompat新增了原生的播放速度字段(playbackSpeed),可以直接通过PlaybackState.Builder.setPlaybackSpeed()设置,UI层通过PlaybackState.getPlaybackSpeed()获取,无需额外通过extras传递,兼容性更好。

对于低版本系统,依然需要借助Bundle传递速度参数,并在PlaybackState的extras中同步状态,确保UI能正确获取当前速度。

内容的提问来源于stack exchange,提问作者David Feldman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 10:20:35