如何通过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
相关产品推荐
相关产品推荐

