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

ExoPlayer默认“None”字幕选项无法选中问题咨询

ExoPlayer默认"None"字幕选项无法关闭的修复方案

问题现象

用ExoPlayer播放视频时,通过API拉取的.vtt字幕能正常显示且默认自动选中,但点击ExoPlayer自带的"None"选项无法关闭字幕;手动添加自定义"None"选项后,列表会出现两个"None",只有手动加的那个能生效。

当前代码情况

字幕配置列表创建代码

val list = arrayListOf<MediaItem.SubtitleConfiguration>()

captions.forEach { caption ->
  caption.resourceUrl?.let { url ->
    val subtitle = MediaItem.SubtitleConfiguration.Builder(url.toUri())
      .setMimeType(MimeTypes.TEXT_VTT)
      .setLanguage(caption.lang)
      .setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
      .build()
    list.add(subtitle)
  }
}

媒体项初始化代码

val mediaItem = MediaItem.Builder()
  .setUri(url.toUri())
  .setSubtitleConfigurations(generateSubtitles())
  .build()

with(exoPlayer) {
  setMediaItem(mediaItem)
  prepare()
  play()
}

手动添加"None"选项的尝试代码

if (list.isNotEmpty()) {
  val noneOption = MediaItem.SubtitleConfiguration.Builder(Uri.EMPTY)
    .setLanguage("none")
    .setMimeType(MimeTypes.TEXT_VTT)
    .build()
  list.add(0, noneOption)
}

解决方案

方案一:修复原生"None"选项功能

问题核心是你给所有字幕配置都加了C.SELECTION_FLAG_DEFAULT标记,导致ExoPlayer无法正确切换到无字幕状态。只需调整标记的设置逻辑:

  • 只给需要默认选中的单条字幕设置该标记,比如第一条字幕,其他字幕不要加。

修改后的字幕配置代码:

val list = arrayListOf<MediaItem.SubtitleConfiguration>()

captions.forEachIndexed { index, caption ->
  caption.resourceUrl?.let { url ->
    val subtitleBuilder = MediaItem.SubtitleConfiguration.Builder(url.toUri())
      .setMimeType(MimeTypes.TEXT_VTT)
      .setLanguage(caption.lang)
    // 仅给第一条字幕设置默认选中标记
    if (index == 0) {
      subtitleBuilder.setSelectionFlags(C.SELECTION_FLAG_DEFAULT)
    }
    list.add(subtitleBuilder.build())
  }
}

这样修改后,原生"None"选项就能正常关闭字幕,符合ExoPlayer的原生设计逻辑。

方案二:隐藏原生"None",只保留自定义选项

如果想完全自定义字幕列表,可通过以下步骤实现:

  1. 先添加自定义"None"选项,再添加其他字幕配置
val list = arrayListOf<MediaItem.SubtitleConfiguration>()

// 添加自定义None选项
val noneOption = MediaItem.SubtitleConfiguration.Builder(Uri.EMPTY)
  .setLanguage("none")
  .setMimeType(MimeTypes.TEXT_VTT)
  .build()
list.add(noneOption)

// 添加其他字幕,按需设置默认选中标记
captions.forEach { caption ->
  caption.resourceUrl?.let { url ->
    val subtitle = MediaItem.SubtitleConfiguration.Builder(url.toUri())
      .setMimeType(MimeTypes.TEXT_VTT)
      .setLanguage(caption.lang)
      .build()
    list.add(subtitle)
  }
}
  1. 监听字幕切换事件,选中自定义"None"时关闭字幕
exoPlayer.addListener(object : Player.Listener {
  override fun onTracksChanged(tracks: Tracks) {
    val subtitleTracks = tracks.groups.filter { it.type == C.TRACK_TYPE_TEXT }
    subtitleTracks.forEach { group ->
      for (i in 0 until group.length) {
        if (group.isSelected(i)) {
          val trackInfo = group.getTrackFormat(i)
          if (trackInfo.language == "none" && trackInfo.uri == Uri.EMPTY) {
            exoPlayer.setSelectedSubtitleTrack(null)
          }
        }
      }
    }
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 07:03:11