转自:http://www.eoeandroid.com/thread-171556-1-1.html

在论坛搜索srt字幕的解析,没有资源,于是自己琢磨,有点结果,与大家分享。

srt字幕文件的格式是:
1
00:00:02,580 --> 00:00:05,980
This is from Gagarin.

2
00:00:11,260 --> 00:00:15,760
<b><u><font color='RED'>出卖我的爱.</font></u></b>
<b><u><font color='RED'>       离开就离开.</font></u></b>
<b><u><font color='RED'>       分手就分手.</font></u></b>
<b><u><font color='RED'>没啥了不起.</font></u></b>

3
00:00:18,660 --> 00:00:22,660
初次发帖,欢迎分享.

4
00:00:23,860 --> 00:00:30,860
Trust is like a piece of paper. When it creases, it cannot recover even it is smoothed.

信任就像一张纸,皱了,即使抚平,也恢复不了原样了。

即:
数字
时间 --> 时间
字幕内容(可以多行)
空行
数字
时间 --> 时间
字幕内容(可以多行)
空行
.
.
.
这里为了说明方便,把
数字
时间 --> 时间
字幕内容(可以多行)
空行
叫做字幕元素。

思路应该是比较清晰的,先解析字幕后同步显示字幕。

1.解析字幕
字幕在解析的时候,就是解析出每一个字幕元素。关键是字幕元素的时间和内容,时间可以解析出开始时间和结束时间,内容可能一行,可能多行,有的还有格式。这里我们可以先声明一个SRT的Bean来存放解析出来的字幕元素。

[java]  view plain copy print ?
  1. package wjj.player.entity;
  2. public class SRT {
  3. private int beginTime;
  4. private int endTime;
  5. private String srtBody;
  6. public int getBeginTime() {
  7. return beginTime;
  8. }
  9. public void setBeginTime(int beginTime) {
  10. this.beginTime = beginTime;
  11. }
  12. public int getEndTime() {
  13. return endTime;
  14. }
  15. public void setEndTime(int endTime) {
  16. this.endTime = endTime;
  17. }
  18. public String getSrtBody() {
  19. return srtBody;
  20. }
  21. public void setSrtBody(String srtBody) {
  22. this.srtBody = srtBody;
  23. }
  24. @Override
  25. public String toString() {
  26. return "" + beginTime + ":" + endTime + ":" + srtBody;
  27. }
  28. }

然后就可以把字幕解析的结果放在这个SRT的对象中,由于字幕文件中有多个字幕元素,我们可以把它放在一个Map中存放。这里选用TreeMap。声明一个全局变量 TreeMap<Integer, SRT> srt_map =null;于是就可以把整个字幕文件解析到这个TreeMap中。

[java]  view plain copy print ?
  1. /**
  2. * 解析SRT字幕文件
  3. *
  4. * @param srtPath
  5. * 字幕路径
  6. */
  7. private void parseSrt(String srtPath) {
  8. FileInputStream inputStream = null;
  9. try {
  10. inputStream = new FileInputStream(srtPath);
  11. } catch (FileNotFoundException e) {
  12. // TODO Auto-generated catch block
  13. e.printStackTrace();
  14. return;// 有异常,就没必要继续下去了
  15. }
  16. BufferedReader br = new BufferedReader(new InputStreamReader(
  17. inputStream));
  18. String line = null;
  19. srt_map = new TreeMap<Integer, SRT>();
  20. StringBuffer sb = new StringBuffer();
  21. int key = 0;
  22. try {
  23. while ((line = br.readLine()) != null) {
  24. if (!line.equals("")) {
  25. sb.append(line).append("@");
  26. continue;
  27. }
  28. String[] parseStrs = sb.toString().split("@");
  29. // 该if为了适应一开始就有空行以及其他不符格式的空行情况
  30. if (parseStrs.length < 3) {
  31. <i>sb.delete(0, sb.length());// 清空,否则影响下一个字幕元素的解析</i>
  32. continue;
  33. }
  34. SRT srt = new SRT();
  35. // 解析开始和结束时间
  36. String timeTotime = parseStrs[1];
  37. int begin_hour = Integer.parseInt(timeTotime.substring(0, 2));
  38. int begin_mintue = Integer.parseInt(timeTotime.substring(3, 5));
  39. int begin_scend = Integer.parseInt(timeTotime.substring(6, 8));
  40. int begin_milli = Integer.parseInt(timeTotime.substring(9, 12));
  41. int beginTime = (begin_hour * 3600 + begin_mintue * 60 + begin_scend)
  42. * 1000 + begin_milli;
  43. int end_hour = Integer.parseInt(timeTotime.substring(17, 19));
  44. int end_mintue = Integer.parseInt(timeTotime.substring(20, 22));
  45. int end_scend = Integer.parseInt(timeTotime.substring(23, 25));
  46. int end_milli = Integer.parseInt(timeTotime.substring(26, 29));
  47. int endTime = (end_hour * 3600 + end_mintue * 60 + end_scend)
  48. * 1000 + end_milli;
  49. // System.out.println("开始:" + begin_hour + ":" + begin_mintue +
  50. // ":"
  51. // + begin_scend + ":" + begin_milli + "=" + beginTime
  52. // + "ms");
  53. // System.out.println("结束:" + end_hour + ":" + end_mintue + ":"
  54. // + end_scend + ":" + end_milli + "=" + endTime + "ms");
  55. // 解析字幕文字
  56. String srtBody = "";
  57. // 可能1句字幕,也可能2句及以上。
  58. for (int i = 2; i < parseStrs.length; i++) {
  59. srtBody += parseStrs</strong><i><strong> + "\n";
  60. }
  61. // 删除最后一个"\n"
  62. srtBody = srtBody.substring(0, srtBody.length() - 1);
  63. // 设置SRT
  64. srt.setBeginTime(beginTime);
  65. srt.setEndTime(endTime);
  66. srt.setSrtBody(new String(srtBody.getBytes(), "UTF-8"));
  67. // 插入队列
  68. srt_map.put(key, srt);
  69. key++;
  70. sb.delete(0, sb.length());// 清空,否则影响下一个字幕元素的解析
  71. }
  72. } catch (Exception e) {
  73. // TODO: handle exception
  74. e.printStackTrace();
  75. }
  76. }

2.同步显示
解析完成后,接下来就是显示的问题了。由于SRT字幕元素中有了开始时间,结束时间,而播放器也可以通过getCurrentPosition()获得当前播放的时间,同步显示的原理就是先获取当前播放时间,然后与SRT字幕元素中的开始时间和结束时间比较,在此范围内的就可以显示SRT字幕元素中的字幕内容。比较是通过一个while循环遍历完成。

[java]  view plain copy print ?
  1. private void showSRT() {
  2. TextView tvSrt = (TextView) srtView.findViewById(R.id.srt);//项目中显示字幕的控件
  3. int currentPosition = vv.getCurrentPosition();//vv是VideoView播放器
  4. Iterator<Integer> keys = srt_map.keySet().iterator();
  5. //通过while循环遍历比较
  6. while (keys.hasNext()) {
  7. Integer key = keys.next();
  8. SRT srtbean = srt_map.get(key);
  9. if (currentPosition > srtbean.getBeginTime()
  10. && currentPosition < srtbean.getEndTime()) {
  11. //Html.fromHtml可以解析出字幕内容的格式
  12. Spanned srtBodyHtml = Html.fromHtml(srtbean
  13. .getSrtBody());
  14. tvsrt.setText(srtBodyHtml);
  15. break;//找到后就没必要继续遍历下去,节约资源
  16. }
  17. }
  18. }

到此SRT字幕的解析与同步显示算是讲完了。我觉得关键还是个思路,有了思路就有了代码。

SRT视频字幕的解析与同步原理相关推荐

  1. SRT视频字幕的解析与同步

    转自:http://www.eoeandroid.com/thread-171556-1-1.html 在论坛搜索srt字幕的解析,没有资源,于是自己琢磨,有点结果,与大家分享. srt字幕文件的格式 ...

  2. 音视频同步原理解析;音频编码和解码原理

    视频流中的DTS/PTS到底是什么? DTS(解码时间戳)和PTS(显示时间戳)分别是解码器进行解码和显示帧时相对于SCR(系统参考)的时间戳.SCR可以理解为解码器应该开始从磁盘读取数据时的时间. ...

  3. 转贴:网友【原创·教程】 SRT外挂字幕时间轴调整及合并中英文同步字幕制作方法

    [原创·教程] SRT外挂字幕时间轴调整及合并中英文同步字幕制作方法 现时比较流行的一种外挂字幕之一就是SRT字幕了,视频电影在压制过程中如果加入字幕就会有损画质,所以就使用起外挂字幕,可隐藏可换多种 ...

  4. ffmpeg源码中ffplay音视频同步原理及实现

    音视频指南 文章目录 音视频指南 前言 一.音视频同步简单介绍? 二.基本概念解释 1.为什么需要视频压缩 2.什么是I帧.p帧.b帧 3.什么是DTS,PTS 4.其他概念解释 三.常用同步策略 四 ...

  5. 转贴:网友【原创·教程】 SRT外挂字幕时间轴调整及合并中英文同步字幕制作方法...

    [原创·教程]SRT外挂字幕时间轴调整及合并中英文同步字幕制作方法 现时比较流行的一种外挂字幕之一就是SRT字幕了,视频电影在压制过程中如果加入字幕就会有损画质,所以就使用起外挂字幕,可隐藏可换多种不 ...

  6. 转贴:网友【原创·教程】 SRT外挂字幕时间轴调整及合并中英文同步字幕制作方法 1

    [原创·教程] SRT外挂字幕时间轴调整及合并中英文同步字幕制作方法 现时比较流行的一种外挂字幕之一就是SRT字幕了,视频电影在压制过程中如果加入字幕就会有损画质,所以就使用起外挂字幕,可隐藏可换多种 ...

  7. 同步播放的效果——iSubtitle for mac视频字幕制作可以做到!

    同步播放的效果--iSubtitle for mac视频字幕制作可以做到!它不依赖于QuickTime或任何其他系统扩展或插件.支持批量导出和智能导入,iSubtitle for mac是一款可以将字 ...

  8. 音视频同步原理及实现

    本文主要描述音视频同步原理,及常见的音视频同步方案,并以代码示例,展示如何以音频的播放时长为基准,将视频同步到音频上以实现视音频的同步播放.内容如下: 1.音视频同步简单介绍 2.DTS和PTS简介 ...

  9. 音视频同步原理[ffmpeg]

    音视频同步原理[ffmpeg] output_example.c 中AV同步的代码如下(我的代码有些修改),这个实现相当简单,不过挺说明问题. 阅读前希望大家先了解一下时间戳的概念. /* compu ...

最新文章

  1. Yii中Action详解
  2. linux class device
  3. COCO 数据集的使用
  4. 实战|全程分析js到getshell
  5. common lisp 学习第三天 函数、注释
  6. 消消乐实现下坠_手把手教你如何实现iOS消消乐小游戏Demo
  7. 安装mongodb时为什么一直卡着不动
  8. ansible 基本操作(初试)
  9. 【Vue2.0】—Vue与Component的关系(十二)
  10. springboot 项目 测试环境在独立的tomcat部署
  11. Android 秒级编译 Freeline
  12. How Google Tests Software (出书,停止更新)
  13. arraylist长度_面经手册 第7篇ArrayList也这么多知识?一个指定位置插入就把谢飞机面晕了!...
  14. hdu5833 Zhu and 772002 (高斯消元的简单应用)
  15. KGB知识图谱,利用科技解决传统知识图谱问题
  16. VCL界面组件DevExpress VCL v22.1 - 发布全新的Shell组件
  17. MFC实现交通图导航系统
  18. linux终端关闭xmanager,xmanager之linux 解决方法
  19. 基于RFM模型对借贷App用户分层分析案例
  20. AV Foundationd 学习之(一)

热门文章

  1. 【软件开发】Java语言的简单介绍
  2. 仿照京东导航条html+css
  3. android paint 圆角 绘制_android 绘制椭圆 圆角矩形 详细解析
  4. 名校认证证书、免费课程……留学生不会告诉你的10个宝藏自学网站
  5. 中职网络安全操作系统渗透
  6. 学计算机的怎样分析TCGA数据库,开启数据挖掘之门:TCGA数据库入门必看!
  7. 我的项目: UConn summer academy BI制药 缺失值处理
  8. LintCode 1144.范围加法之二
  9. 在C ++中将二进制转换为十进制
  10. nativefier(一行代码将任意网页转化为桌面应用)