View版及更多功能使用:详见
一、概念
1.1 实现方式选择
| media3-ui-compose | media3-ui-compose-material3 | |
| 界面组件 | 基础组件。 | 开箱即用,含预设样式的按钮或控件。 |
| 状态管理 | 提供 remember***State 状态持有者来管理逻辑。 | 在内部管理状态,但仍可根据需要访问状态容器。 |
| 使用场景 | 使用自定义风格构建播放器界面。 | 使用 Material3 预设快速构建。 |
1.2 显示组件
| ContentFrame | @Composable 参数 contentScale:视频缩放。 参数 keepContentOnReset:为 true 播放器重置时将保持最后一帧画面显示,为 false 则会清空渲染表面。 参数 shutter:用于在需要覆盖视频渲染表面时显示。默认情况下,它显示为黑色背景。 |
1.3 控制组件
组件中可以直接拿到对应状态里的属性/方法(推荐通过this调用方便阅读)。
| 通用组件 | PlayPauseButton | 播放和暂停。 |
| SeekBackButton | 根据预设值,向前调整播放进度。 | |
| SeekForwardButton | 根据预设值,向后调整播放进度。 | |
| NextButton | 跳转到下一个媒体项。 | |
| PreviousButton | 跳转到上一个媒体项。 | |
| RepeatButton | 切换重复模式。 | |
| ShuffleButton | 切换随机模式。 | |
| MuteButton | 切换静音模式。 | |
| TimeText | 显示时长相关文本。 | |
| Material3 | PositionAndDurationText | 当前位置和总时长的文本。 |
| PositionText | 当前位置的文本。 | |
| DurationText | 总时长的文本。 | |
| RemainingDurationText | 剩余时长的文本。 |
自定义方式:
PlayPauseButton(player) {
Icon(
modifier = Modifier
.size(20.dp)
.clickable(
enabled = this.isEnabled,
onClick = { this.onClick() }
),
imageVector = if (this.showPlay) Icons.Default.PlayArrow else Icons.Default.PauseCircle,
contentDescription = if (this.showPlay) "Play" else "Pause"
)
}
Material3 方式:
Row {
SeekBackButton(player)
PlayPauseButton(player)
SeekForwardButton(player)
}
1.4 状态(自定义控制组件)
如果上面没有需要的组件,可以自行通过状态来构建自定义组件。
| 状态 | 获取方式 |
| 播放暂停 | rememberPlayPauseButtonState |
| 上一项 | rememberPreviousButtonState |
| 下一项 | rememberNextButtonState |
| 重复模式 | rememberRepeatButtonState |
| 随机模式 | rememberShuffleButtonState |
| 播放速度 | rememberPlaybackSpeedState |
val state = rememberPlayPauseButtonState(player)
Icon(
modifier = Modifier
.size(20.dp)
.clickable(
enabled = state.isEnabled,
onClick = { state.onClick() }
),
imageVector = if (state.showPlay) Icons.Default.PlayArrow else Icons.Default.PauseCircle,
contentDescription = if (state.showPlay) "Play" else "Pause"
)
二、添加依赖
[versions]
media3 = "1.9.0"
[libraries]
media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "media3" }
media3-datasource-okhttp = { module = "androidx.media3:media3-datasource-okhttp", version.ref = "media3" }
#二选一
media3-ui-compose = { module = "androidx.media3:media3-ui-compose", version.ref = "media3" }
media3-ui-compose-material3 = { moudle = "androidx.media3:media3-ui-compose-material3", version.ref = "media3" }
三、实现方式
3.1 ViewModel
在 ViewModel 中提供 ExoPlayer,将业务和UI分离。
class PlayerVM : ViewModel() {
private val playlist = mutableListOf<MediaItem>()
private val playerListener by lazy {
object : Player.Listener {
}
}
val player by lazy {
ExoPlayer.Builder(APP.context)
.setSeekBackIncrementMs(10000)
.setSeekForwardIncrementMs(10000)
.build()
.apply {
addListener(playerListener)
setMediaItem(MediaItem.fromUri("https://www.w3schools.com/html/movie.mp4"))
prepare()
playWhenReady = true
}
}
override fun onCleared() {
super.onCleared()
player.release()
}
}
3.2 UI
@Composable
private fun Demo(
viewModel: PlayerVM = viewModel()
) {
ContentFrame(viewModel.player)
}
2835

被折叠的 条评论
为什么被折叠?



