如何在Jetpack Compose的Media3 ExoPlayer中移除进度条及15秒进退按钮
在Jetpack Compose中自定义Media3 ExoPlayer直播控制视图
先修正你当前代码里的几个基础问题:
video: string?需改为video: String?(Kotlin中类型首字母大写)- 判空逻辑里的
videoUri应替换为video,与函数参数保持一致 - 异常抛出建议用更规范的
IllegalArgumentException
修正后的基础代码:
@Composable fun VideoView(video: String?, viewModel: ChannelsViewModel = viewModel()) { val context = LocalContext.current if (video == null) { throw IllegalArgumentException("Video URI cannot be null") } val exoPlayer = ExoPlayer.Builder(context) .build() .also { exoPlayer -> val mediaItem = MediaItem.Builder() .setUri(video) .build() exoPlayer.setMediaItem(mediaItem) exoPlayer.prepare() exoPlayer.playWhenReady = true } DisposableEffect(exoPlayer) { val listener = object : Player.Listener { // 后续添加直播状态判断逻辑 } exoPlayer.addListener(listener) onDispose { exoPlayer.removeListener(listener) exoPlayer.release() } } AndroidView(factory = { PlayerView(context).apply { player = exoPlayer layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) // 此处添加自定义控制器配置 } }) }
以下是两种实现直播模式下隐藏进度条和15秒进退按钮的方案:
方案一:自定义控制器布局XML
这种方式可以完全掌控控制视图的结构:
在
res/layout目录下创建custom_live_player_controller.xml,复制Media3默认控制器布局(可从Media3库的layout/exo_player_control_view.xml获取原布局),然后删除以下组件:- 进度条(id为
exo_progress的ProgressBar) - 15秒后退按钮(id为
exo_rew的ImageButton) - 15秒前进按钮(id为
exo_ffwd的ImageButton)
- 进度条(id为
在PlayerView中设置自定义布局:
AndroidView(factory = { ctx -> PlayerView(ctx).apply { player = exoPlayer layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) // 绑定自定义控制器布局 controllerLayoutId = R.layout.custom_live_player_controller } })
方案二:代码动态隐藏指定组件
如果不想自定义XML,可通过代码定位默认控制器的子视图,根据直播状态动态切换显示:
// 先通过remember持有PlayerView引用 val playerView = remember { mutableStateOf<PlayerView?>(null) } DisposableEffect(exoPlayer) { val listener = object : Player.Listener { override fun onTimelineChanged(timeline: Timeline, reason: Int) { super.onTimelineChanged(timeline, reason) playerView.value?.let { updateControllerVisibility(exoPlayer, it) } } } exoPlayer.addListener(listener) onDispose { exoPlayer.removeListener(listener) exoPlayer.release() } } AndroidView(factory = { ctx -> PlayerView(ctx).apply { player = exoPlayer layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) playerView.value = this } }) // 辅助函数:根据直播状态控制组件显示 private fun updateControllerVisibility(player: ExoPlayer, playerView: PlayerView) { val isLive = player.currentTimeline.windowCount > 0 && player.currentTimeline.getWindow(0, Timeline.Window()).isLive playerView.post { // 隐藏/显示15秒进退按钮 playerView.findViewById<ImageButton>(R.id.exo_rew)?.visibility = if (isLive) View.GONE else View.VISIBLE playerView.findViewById<ImageButton>(R.id.exo_ffwd)?.visibility = if (isLive) View.GONE else View.VISIBLE // 隐藏/显示进度条 playerView.findViewById<ProgressBar>(R.id.exo_progress)?.visibility = if (isLive) View.GONE else View.VISIBLE } }
内容的提问来源于stack exchange,提问作者IdanB
相关产品推荐
相关产品推荐

