news 2026/1/21 8:20:30

Compose - 使用 Media3(ExoPlayer)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Compose - 使用 Media3(ExoPlayer)

View版及更多功能使用:详见

一、概念

1.1 实现方式选择

media3-ui-composemedia3-ui-compose-material3
界面组件基础组件。开箱即用,含预设样式的按钮或控件。
状态管理提供 remember***State 状态持有者来管理逻辑。在内部管理状态,但仍可根据需要访问状态容器。
使用场景使用自定义风格构建播放器界面。使用 Material3 预设快速构建。

1.2 显示组件

ContentFrame

@Composable
fun ContentFrame(
player: Player?,
modifier: Modifier = Modifier,
surfaceType: @SurfaceType Int = SURFACE_TYPE_SURFACE_VIEW,
contentScale: ContentScale = ContentScale.Fit,
keepContentOnReset: Boolean = false,
shutter: @Composable () -> Unit = { Box(Modifier.fillMaxSize().background(Color.Black)) },
)

参数 contentScale:视频缩放。

参数 keepContentOnReset:为 true 播放器重置时将保持最后一帧画面显示,为 false 则会清空渲染表面。

参数 shutter:用于在需要覆盖视频渲染表面时显示。默认情况下,它显示为黑色背景。

1.3 控制组件

组件中可以直接拿到对应状态里的属性/方法(推荐通过this调用方便阅读)。

通用组件PlayPauseButton播放和暂停。
SeekBackButton根据预设值,向前调整播放进度。
SeekForwardButton根据预设值,向后调整播放进度。
NextButton跳转到下一个媒体项。
PreviousButton跳转到上一个媒体项。
RepeatButton切换重复模式。
ShuffleButton切换随机模式。
MuteButton切换静音模式。
TimeText显示时长相关文本。
Material3PositionAndDurationText当前位置和总时长的文本。
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) }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/14 15:18:17

Linly-Talker黑客马拉松活动筹备进展

Linly-Talker黑客马拉松活动筹备进展 在虚拟主播24小时不间断带货、AI客服秒回千条咨询的今天&#xff0c;数字人早已不是科幻电影里的概念。但真正让开发者头疼的是&#xff1a;如何把语音识别、大模型对话、语音合成和面部动画这些“高门槛”技术串成一条流畅的流水线&#x…

作者头像 李华
网站建设 2026/1/12 23:01:50

上市首日破发?李泽湘IPO版图再添一子! 希迪智驾 香港科技大学

上市首日破发&#xff1f;李泽湘IPO版图再添一子! 原创 Z 维科网机器人 2025年12月19日 18:27 广东 卧安机器人还没敲钟&#xff0c;“大疆教父”李泽湘先收获了一个IPO。 今日&#xff0c;希迪智驾正式在港交所敲钟上市&#xff0c;不仅拿下“自动驾驶矿卡第一股”的头衔&am…

作者头像 李华
网站建设 2026/1/11 7:17:06

Linly-Talker用户数据绝不用于训练模型声明

Linly-Talker&#xff1a;隐私优先的本地化数字人系统 在虚拟主播、智能客服和在线教育日益普及的今天&#xff0c;人们对数字人的期待早已超越了简单的“会说话的头像”。真正的挑战在于&#xff1a;如何让一个虚拟形象既具备自然流畅的交互能力&#xff0c;又能完全尊重用户的…

作者头像 李华
网站建设 2026/1/18 6:43:11

Linly-Talker腾讯云TI平台集成方案讨论

Linly-Talker 腾讯云TI平台集成方案深度解析 在虚拟主播、智能客服和数字员工逐渐走入大众视野的今天&#xff0c;一个核心问题摆在开发者面前&#xff1a;如何以低成本、高效率的方式构建具备自然交互能力的实时数字人&#xff1f;传统依赖动画师手动调参、逐帧渲染的制作模式…

作者头像 李华
网站建设 2026/1/8 10:10:35

Linly-Talker助力自媒体创作者突破内容瓶颈

Linly-Talker&#xff1a;一张图&#xff0c;一句话&#xff0c;让数字人替你说话 在短视频日更、直播不间断的今天&#xff0c;内容创作者面临的压力前所未有。不仅要绞尽脑汁想选题&#xff0c;还得亲自出镜、反复拍摄、熬夜剪辑——一条三分钟的视频&#xff0c;可能要花上大…

作者头像 李华
网站建设 2026/1/18 15:29:28

Linly-Talker结合ASR实现双语字幕自动生成

Linly-Talker 结合 ASR 实现双语字幕自动生成 在直播带货、在线教育和跨国会议日益频繁的今天&#xff0c;内容创作者常常面临一个现实难题&#xff1a;如何让一段讲解视频同时被中文母语者和英语学习者无障碍理解&#xff1f;传统做法是后期人工添加字幕&#xff0c;耗时费力且…

作者头像 李华