如何使用Exoplayer实现字幕下载并动态添加到播放中的视频
ExoPlayer实现动态下载加载字幕的完整方案
1. 字幕搜索与下载实现
调用字幕平台的公开API完成搜索和下载,优先用视频哈希值、文件时长作为搜索参数,匹配准确率比纯文件名搜索高很多。
- 搜索后筛选对应语言的字幕资源,大部分平台返回的字幕都是zip/rar压缩包,下载完成后需要先解压得到srt、ass、ssa等ExoPlayer支持的字幕格式文件
- 注意:ExoPlayer本身不提供rar解压能力,需要自行引入第三方解压库处理rar格式的压缩包
2. 字幕文件预处理
加载前先处理字幕文件避免乱码和解析失败问题:
- 转码:把GBK、BIG5等非UTF-8编码的字幕统一转成UTF-8编码,ExoPlayer默认仅支持UTF-8编码的字幕
- 校验:提前解析字幕文件的基本结构,过滤内容损坏的无效字幕文件
- 存储:把处理好的字幕文件存到应用私有缓存目录,避免外部存储权限申请和文件被误删
3. 动态追加字幕到正在播放的视频
ExoPlayer 2.10及以上版本支持动态追加字幕轨,不需要停止播放或重建整个播放实例,核心实现代码如下:
3.1 构建字幕配置
// 本地缓存的字幕文件路径 val subtitleFile = File(cacheDir, "downloaded_sub.srt") val subtitleConfig = MediaItem.SubtitleConfiguration.Builder(Uri.fromFile(subtitleFile)) .setMimeType(MimeTypes.APPLICATION_SUBRIP) // srt格式用这个值,ass格式用MimeTypes.APPLICATION_ASS .setLanguage("zh-CN") // 填写字幕对应语言 .setSelectionFlags(C.SELECTION_FLAG_DEFAULT) .build()
3.2 动态更新到当前播放项
// 拿到当前正在播放的MediaItem val currentMediaItem = exoPlayer.currentMediaItem ?: return // 追加新的字幕配置 val newMediaItem = currentMediaItem.buildUpon() .setSubtitleConfigurations( currentMediaItem.subtitleConfigurations.toMutableList().apply { add(subtitleConfig) } ) .build() // 更新媒体项,第二个参数设为true保持当前播放进度不中断 exoPlayer.setMediaItem(newMediaItem, true) exoPlayer.prepare()
3.3 自动显示新加载的字幕
如果需要自动切换到刚加载的字幕,调整轨道选择器参数即可:
trackSelector.setParameters( trackSelector.buildUponParameters() .setPreferredTextLanguage("zh-CN") .setSelectUndeterminedTextLanguage(true) )
注意:如果你的ExoPlayer版本低于2.10,无法动态追加字幕轨,需要重新构建整个MediaSource再替换到播放器,建议升级到最新稳定版降低适配成本
4. 交互功能适配
- 字幕样式调整:通过
SubtitleView的相关方法可以直接调整字幕的字体大小、颜色、描边、上下边距,调整后实时生效不需要重启播放 - 字幕偏移调整:如果字幕和音画不同步,调用
exoPlayer.setPlaybackParameters(PlaybackParameters(playbackSpeed, offsetUs))即可调整,offsetUs为偏移量,单位是微秒 - 字幕切换:可以弹出选择框列出所有已加载的字幕,用户可以自由切换显示不同字幕或者关闭字幕显示
内容的提问来源于stack exchange,提问作者ahmadu suleiman
相关产品推荐
相关产品推荐

