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

Android VideoView无法显示Firebase Storage下载的.srt字幕,求解决方案

问题描述

视频播放正常,无报错但字幕不显示,使用Firebase Storage下载临时SRT文件的方案,需要修改哪些内容让字幕正常显示?

原代码:

var videoView : VideoView = findViewById(R.id.videoView)

fun getSubtitles() {
    val storageReference = FirebaseStorage.getInstance().reference
    var srtReference = storageReference.child("Subtitles/${videoName}.srt")
    val localFile = File.createTempFile("Subtitles", "srt")
    srtReference.getFile(localFile).addOnSuccessListener {
        videoView.addSubtitleSource(
                contentResolver.openInputStream(localFile.toUri()),
                MediaFormat.createSubtitleFormat("text/srt", Locale.ENGLISH.language)
        )
    }
}
fun playVideo(videoUrl : String){
    var uri = Uri.parse(videoUrl)
    videoView.setVideoURI(uri)
    val mediaController = MediaController(this)
    mediaController.setAnchorView(videoView)
    mediaController.setMediaPlayer(videoView)
    videoView.setMediaController(mediaController)
    getSubtitles()
    videoView.start()
}
val videoURLRef = FirebaseDatabase.getInstance().getReference("URL")
videoURLRef.addValueEventListener(object : ValueEventListener {
    override fun onDataChange(snapshot: DataSnapshot) {
        var videoUrl = snapshot.value.toString()
        playVideo(videoUrl)
    }
    override fun onCancelled(error: DatabaseError) {
        TODO("Not yet implemented")
    }
})
解决方案

以下是需要修改的几个关键点:

1. 调整字幕加载与视频播放的时机

getSubtitles是异步操作,当前代码中videoView.start()会在字幕下载完成前执行,导致字幕无法被视频加载。需将视频启动逻辑移到字幕下载成功的回调中,或监听视频就绪事件后再加载字幕:

fun getSubtitles(onSuccess: () -> Unit) {
    val storageReference = FirebaseStorage.getInstance().reference
    val srtReference = storageReference.child("Subtitles/${videoName}.srt")
    val localFile = File.createTempFile("Subtitles", "srt")
    srtReference.getFile(localFile).addOnSuccessListener {
        videoView.addSubtitleSource(
            contentResolver.openInputStream(localFile.toUri()),
            MediaFormat.createSubtitleFormat("text/srt", Locale.ENGLISH.toString())
        )
        onSuccess() // 字幕加载完成后触发播放
    }.addOnFailureListener {
        // 处理下载失败,直接启动视频
        onSuccess()
    }
}

fun playVideo(videoUrl : String){
    val uri = Uri.parse(videoUrl)
    videoView.setVideoURI(uri)
    val mediaController = MediaController(this)
    mediaController.setAnchorView(videoView)
    mediaController.setMediaPlayer(videoView)
    videoView.setMediaController(mediaController)
    
    // 监听视频准备事件,就绪后加载字幕并启动
    videoView.setOnPreparedListener {
        getSubtitles {
            videoView.start()
        }
    }
}

2. 修正字幕格式的语言参数

MediaFormat.createSubtitleFormat的第二个参数需要完整的语言标签(如"en-US"),Locale.ENGLISH.language仅返回"en",可能导致系统无法识别字幕语言,改用完整Locale标识:

MediaFormat.createSubtitleFormat("text/srt", Locale.ENGLISH.toString())

3. 确保临时文件的稳定性

系统临时文件可能被自动回收,建议将文件保存到应用缓存目录:

// 替换原临时文件创建代码
val cacheDir = applicationContext.cacheDir
val localFile = File(cacheDir, "${videoName}.srt")

4. 验证SRT文件格式

确认Firebase Storage中的SRT文件符合规范:

  • 时间码格式正确(如00:00:01,000 --> 00:00:03,000)
  • 文件编码为UTF-8
  • 无语法错误(如缺少时间码、空行格式错误)

5. 强制开启字幕显示

部分设备默认关闭字幕,可通过代码强制启用:

videoView.setOnPreparedListener { mediaPlayer ->
    // 遍历轨道,开启第一个字幕轨道
    for (i in mediaPlayer.trackInfo.indices) {
        if (mediaPlayer.trackInfo[i].trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
            mediaPlayer.selectTrack(i)
            break
        }
    }
    getSubtitles {
        videoView.start()
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:55:10