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

ExoPlayer 2.18.7如何对接自定义Compose组件实现字幕实时显示?

ExoPlayer 2.18.7 自定义Compose字幕组件实现方案

核心思路

ExoPlayer 没有类似 MediaPlayer 的 onTimedTextListener,但可以通过**CueGroupListener**监听字幕更新,结合 Compose 的状态管理实现自定义字幕渲染。你之前尝试的onCues是正确方向,大概率是轨道配置或监听逻辑问题导致未生效。

步骤实现

1. 确保字幕轨道正确配置与激活

先确认SubtitleConfiguration已关联到MediaItem,并在用户开启字幕时激活对应轨道:

// 构建带字幕的MediaItem
val subtitleConfig = SubtitleConfiguration.Builder(Uri.parse("subtitle_file_url"))
    .setMimeType(MimeTypes.TEXT_VTT) // 根据字幕格式设置对应MIME类型(如SRT用MimeTypes.APPLICATION_SUBRIP)
    .setLanguage("zh-CN")
    .build()

val mediaItem = MediaItem.Builder()
    .setUri("audio_file_url")
    .setSubtitleConfigurations(listOf(subtitleConfig))
    .build()

player.setMediaItem(mediaItem)

// 用户开启字幕时激活轨道
fun enableSubtitle() {
    val subtitleTrackGroups = player.currentTracks.groups.filter { it.type == C.TRACK_TYPE_TEXT }
    if (subtitleTrackGroups.isNotEmpty()) {
        val trackSelectionParams = player.trackSelectionParameters.buildUpon()
            .setTrackTypeDisabled(C.TRACK_TYPE_TEXT, false) // 启用字幕轨道类型
            .setSelectedTextTrackIndex(subtitleTrackGroups[0].indexInTrackGroupArray) // 选中第一个字幕轨道
            .build()
        player.trackSelectionParameters = trackSelectionParams
    }
}

// 用户关闭字幕时禁用
fun disableSubtitle() {
    val trackSelectionParams = player.trackSelectionParameters.buildUpon()
        .setTrackTypeDisabled(C.TRACK_TYPE_TEXT, true)
        .build()
    player.trackSelectionParameters = trackSelectionParams
}

2. 注册CueGroupListener监听字幕更新

通过addCueGroupListener获取实时字幕数据(Cue对象包含文本、显示时间范围等信息),并更新Compose状态:

// 在Compose中定义状态存储当前字幕
val currentSubtitleState = remember { mutableStateOf("") }
val coroutineScope = rememberCoroutineScope()

// 注册监听器(建议在player初始化后注册)
player.addCueGroupListener { _, cues ->
    // 拼接所有字幕行,处理多行字幕场景
    val subtitleText = cues.joinToString("\n") { cue ->
        cue.text?.toString() ?: ""
    }
    // 更新Compose状态,需在协程中操作
    coroutineScope.launch {
        currentSubtitleState.value = subtitleText
    }
}

3. 自定义Compose字幕组件

基于状态渲染自定义视图,根据用户的字幕开关控制显示:

@Composable
fun CustomSubtitleView(
    currentSubtitle: String,
    isSubtitleEnabled: Boolean
) {
    if (isSubtitleEnabled && currentSubtitle.isNotEmpty()) {
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 16.dp, vertical = 32.dp)
                .align(Alignment.BottomCenter),
            contentAlignment = Alignment.Center
        ) {
            Text(
                text = currentSubtitle,
                color = Color.White,
                fontSize = 18.sp,
                style = TextStyle(
                    background = Color.Black.copy(alpha = 0.7f),
                    padding = PaddingValues(horizontal = 8.dp, vertical = 4.dp)
                )
            )
        }
    }
}

// 使用示例
CustomSubtitleView(
    currentSubtitle = currentSubtitleState.value,
    isSubtitleEnabled = remember { mutableStateOf(true) }.value
)

常见问题排查

  • onCues未触发:检查字幕轨道是否被正确激活(通过player.currentTracks查看选中状态),或字幕文件的格式、路径是否正确。
  • 字幕乱码:确认SubtitleConfiguration的MIME类型与字幕文件格式匹配。

内容的提问来源于stack exchange,提问作者Petermonteer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 01:17:26