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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 06:35:16