如何使用AndroidX Media3 ExoPlayer与Jetpack Compose显示HLS内嵌字幕?
AndroidX Media3 ExoPlayer + Jetpack Compose HLS内嵌字幕问题解决
问题描述
使用AndroidX Media3 ExoPlayer结合Jetpack Compose播放HLS视频时,内嵌字幕无法显示,且播放器控制栏没有字幕显示/隐藏切换按钮。
解决步骤
1. 配置PlayerView启用字幕控件与渲染
默认PlayerView未开启字幕按钮和基础渲染配置,需手动启用:
AndroidView( factory = { PlayerView(context).apply { this.player = player layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) // 显示字幕切换按钮 setShowSubtitleButton(true) // 启用控制器自动显示 controllerAutoShow = true // 配置默认字幕样式(可根据需求调整) subtitleView?.apply { setStyle(CaptionStyleCompat.DEFAULT) setTextSize(CaptionStyleCompat.DEFAULT_TEXT_SIZE) } } } )
2. 配置ExoPlayer的字幕轨道选择策略
通过TrackSelector设置字幕优先规则,确保ExoPlayer正确识别并加载字幕轨道:
val player: ExoPlayer = remember { val trackSelector = DefaultTrackSelector(context).apply { val params = buildUponParameters() // 设置优先选择的字幕语言(示例为英文,可改为系统语言或自定义) .setPreferredTextLanguage("en") // 允许自动匹配HLS的AUTOSELECT配置 .setForceHighestSupportedTextTrack(false) setParameters(params) } ExoPlayer.Builder(context) .setTrackSelector(trackSelector) .build() .apply { setMediaItem(MediaItem.fromUri(hlsUri)) prepare() } }
3. 检查HLS字幕流有效性
- 确认
#EXT-X-MEDIA:TYPE=SUBTITLES对应的URI指向有效字幕播放列表(需包含VTT/TTML格式的字幕片段) - 可直接在浏览器中打开字幕URI,验证是否能正常加载内容
- 若需要默认自动显示字幕,可将HLS配置中的
DEFAULT=YES替换原有的DEFAULT=NO
4. 升级Media3到最新稳定版
当前使用的1.0.2版本较旧,部分字幕相关bug已在后续版本修复,建议更新版本:
# gradle/libs.versions.toml androidXMedia = "1.2.1"
完整修改后的代码
@Composable fun MyPlayer() { val hlsUri = Uri.parse("https://some.website/video.m3u8") val context = LocalContext.current val player: ExoPlayer = remember { val trackSelector = DefaultTrackSelector(context).apply { val params = buildUponParameters() .setPreferredTextLanguage("en") .setForceHighestSupportedTextTrack(false) setParameters(params) } ExoPlayer.Builder(context) .setTrackSelector(trackSelector) .build() .apply { setMediaItem(MediaItem.fromUri(hlsUri)) prepare() } } AndroidView( factory = { PlayerView(context).apply { this.player = player layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT) setShowSubtitleButton(true) controllerAutoShow = true subtitleView?.apply { setStyle(CaptionStyleCompat.DEFAULT) setTextSize(CaptionStyleCompat.DEFAULT_TEXT_SIZE) } } } ) }
内容的提问来源于stack exchange,提问作者Sébastien Dubois
相关产品推荐
相关产品推荐

