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
相关产品推荐
相关产品推荐

