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

ExoPlayer播放/暂停时不显示控制器的TV端适配需求

解决ExoPlayer在Nvidia Shield Pro上的媒体按键适配问题

核心问题分析

你遇到的问题是ExoPlayer默认会在播放状态切换时自动显示控制器,而禁用控制器(setUseController(false))会导致播放暂停的默认逻辑失效。我们需要保留控制器但完全手动控制其显示/隐藏,实现类似Plex/YouTube的交互逻辑:媒体操作不触发控制器显示,仅通过DPAD上下键控制控制器的显示和隐藏。

解决方案步骤

1. 配置PlayerView的控制器行为

在初始化时,彻底禁用控制器的自动显示逻辑,确保只有手动调用才能改变其可见性:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    viewBinding = ActivityPlayerBinding.inflate(layoutInflater)
    setContentView(viewBinding.root)

    // 初始化ExoPlayer实例
    val player = ExoPlayer.Builder(this).build()
    viewBinding.playerView.player = player

    // 配置PlayerView,完全手动控制控制器
    viewBinding.playerView.apply {
        // 禁止自动显示控制器
        controllerAutoShow = false
        // 禁止触摸(遥控器点击)时自动隐藏控制器
        controllerHideOnTouch = false
        // 初始状态隐藏控制器
        hideController()
    }

    // 加载你的媒体资源...
}

2. 重写按键事件处理逻辑

在onKeyDown中处理所有目标按键,执行对应操作后强制控制控制器的可见性:

override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
    val player = viewBinding.playerView.player ?: return super.onKeyDown(keyCode, event)

    return when (keyCode) {
        // 处理播放/暂停按键(兼容不同遥控器的按键码)
        KeyEvent.KEYCODE_MEDIA_PLAY, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> {
            if (player.isPlaying) player.pause() else player.play()
            // 强制隐藏控制器,覆盖默认的自动显示行为
            viewBinding.playerView.hideController()
            true
        }
        // 快进/快退操作后保持控制器隐藏
        KeyEvent.KEYCODE_DPAD_RIGHT -> {
            player.seekForward()
            viewBinding.playerView.hideController()
            true
        }
        KeyEvent.KEYCODE_DPAD_LEFT -> {
            player.seekBack()
            viewBinding.playerView.hideController()
            true
        }
        // DPAD_DOWN显示控制器
        KeyEvent.KEYCODE_DPAD_DOWN -> {
            viewBinding.playerView.showController()
            true
        }
        // DPAD_UP隐藏控制器
        KeyEvent.KEYCODE_DPAD_UP -> {
            viewBinding.playerView.hideController()
            true
        }
        // 其他按键交给系统默认处理
        else -> super.onKeyDown(keyCode, event)
    }
}

3. 布局无需额外修改

你的现有布局已经保留了StyledPlayerView和自定义控件,不需要修改布局代码——我们通过代码逻辑完全接管了控制器的显示行为。

关键说明

  • 不要设置setUseController(false):禁用控制器会导致ExoPlayer丢失播放暂停的默认交互逻辑,必须保留控制器实例。
  • 兼容多按键码:部分遥控器的播放暂停按键可能是KEYCODE_MEDIA_PLAY_PAUSE,同时处理两个按键码可以提升兼容性。
  • 强制调用hideController():执行媒体操作后手动隐藏控制器,覆盖ExoPlayer播放状态变化时自动显示控制器的默认行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 05:24:27