网上下载的字幕有时和片源的时间轴不一致。我们能够自己写一个工具来调整,也就是总体向前移动几秒,或者向后移动几秒。Java8中提供的Duration类使得这样的时间计算极其方便。以下就以最简单的srt字幕格式为例说明。



srt的时间轴格式例如以下:

1
00:00:36,800 --> 00:00:41,300
天下武功,皆出少林。

第一行是计数器。不用管。

第二行是时间轴,是我们的重点关注对象。这一行显示小时,分,秒,毫秒。

然后用一个箭头隔开,表示从哪个时间到哪个时间显示第三行的字幕。



java.time.Duration表示一段时间。对于srt字幕来说,00:00:36,800就表示从0開始到36秒800毫秒这段时间,所以逻辑上正好相应一个Duration。



以下这段代码处理srt文件的一行。假设是时间轴行,则调整,否则原样打印到新文件中。

void processLine(String line, int milliSecs) {
if(line.indexOf("-->") != -1) { // 这一行是时间轴 // 将字幕显示的起始时间和结束时间分开。 String timespan[] = line.split("-->"); // 起始时间的小时、分、秒、毫秒分开。
String begin[] = timespan[0].split("[:,]"); // 重点:把起始时间的小时、分、秒、毫秒统统加在一起构造一个Duration。
// plus方法是可串行的,就像StringBuffer的append。 Duration beginTime =
Duration.ofHours(Long.parseLong(begin[0].trim())).plus(
Duration.ofMinutes(Long.parseLong(begin[1].trim()))).plus(
Duration.ofSeconds(Long.parseLong(begin[2].trim()))).plus(
Duration.ofMillis(Long.parseLong(begin[3].trim()))); // 结束时间也如法炮制。
String end[] = timespan[1].split("[:,]"); Duration endTime =
Duration.ofHours(Long.parseLong(end[0].trim())).plus(
Duration.ofMinutes(Long.parseLong(end[1].trim()))).plus(
Duration.ofSeconds(Long.parseLong(end[2].trim()))).plus(
Duration.ofMillis(Long.parseLong(end[3].trim()))); // 把这两个时间分别加上我们希望的偏移量,也就是向前(milliSecs为负)或者向后移动的毫秒数,
// 得到两个新的Duration
Duration newStart = beginTime.plusMillis(milliSecs);
Duration newEnd = endTime.plusMillis(milliSecs); // pw是一个PrintWriter,把调整后的一行时间轴写入新的字幕文件。 pw.println(parse(newStart) + " --> " + parse(newEnd)); } else {
pw.println(line); // 不是时间轴行,原样打印
}
}

以下这一段代码用来将一个Duration转成00:00:36,800这样的格式的字符串。

String parse(Duration d) {
long h = d.toHours(); // 得到小时数
String sh = h<10 ? "0" + h : "" + h; // 假设仅仅有一位数。加上个0 // 为了得到后面的分,秒,毫秒,我们要将小时减掉,否则取分钟的时候会连小时算进去
d = d.minusHours(h); long min = d.toMinutes(); // 得到分钟
String smin = min<10 ? "0" + min : "" + min;
d = d.minusMinutes(min); // 减掉分钟
long s = d.getSeconds(); // 得到秒,注意这里是getSeconds,没有toSeconds方法
String ss = s<10 ? "0" + s : "" + s;
d = d.minusSeconds(s); // 减掉秒
long m = d.toMillis(); // 得到毫秒
String sm = m<10 ? "00" + m : (m<100 ? "0" + m : "" + m);
return sh + ":" + smin + ":" + ss + "," + sm;
}

此工具完整代码可在此处下载:

http://download.csdn.net/detail/ioriogami/7626991

使用Java8提供的Duration类制作字幕时间轴调整工具的更多相关文章

  1. stout代码分析之一:Duration类

    Duration类用于表示时间长度,可精确到纳秒. 代码实现在duration.hpp中,测试代码:duration_tests.cpp 相关api如下: parse, 将字符串转化成Duration ...

  2. Java8 Period 类与 Duration 类 用法详解

    引言 Java 8 中引入了两个与日期相关的新类: Period :基于日期值 Duration:基于时间值 它们最大的作用就不需要你自己复杂的计算关于两个年月日之间的相差的时间或日期啦. Perio ...

  3. Java8 ,LocalDate,LocalDateTime处理日期和时间工具类,

    Java8 ,LocalDate,LocalDateTime处理日期和时间工具类 1.获取今天的日期 2.在Java 8 中获取年.月.日信息 3.在Java 8 中处理特定日期 4.在Java 8 ...

  4. Java基础进阶:时间类要点摘要,时间Date类实现格式化与解析源码实现详解,LocalDateTime时间类格式化与解析源码实现详解,Period,Duration获取时间间隔与源码实现,程序异常解析与处理方式

    要点摘要 课堂笔记 日期相关 JDK7 日期类-Date 概述 表示一个时间点对象,这个时间点是以1970年1月1日为参考点; 作用 可以通过该类的对象,表示一个时间,并面向对象操作时间; 构造方法 ...

  5. 使用反射创建Bean、Spring中是如何根据类名配置创建Bean实例、Java提供了Class类获取类别的字段和方法,包括构造方法

    Java提供了Class类,可以通过编程方式获取类别的字段和方法,包括构造方法    获取Class类实例的方法:   类名.class   实例名.getClass()   Class.forNam ...

  6. 巧用CSS3 :target 伪类制作Dropdown下拉菜单(无JS)

    :target 是CSS3 中新增的一个伪类,用以匹配当前页面的URI中某个标志符的目标元素(比如说当前页面URL下添加#comment就会定位到id=“comment”的位置,俗称锚).CSS3 为 ...

  7. 如何使用SubtitleWorkshop制作字幕

    任意打开一段字幕文件 对于初学者而言还是最好打开一个带有中英字幕的视频文件(字幕是嵌入在视频文件里面的)然后一句一句照着写 先打开视频预览模式 再打开一段视频文件,并新建一个字幕文件 牢记几个快捷键 ...

  8. net 提供了Thread类用于线程的操作

    net 提供了Thread类用于线程的操作. 当初始化一个线程,把Thread.IsBackground=true的时候,指示该线程为后台线程.后台线程将会随着主线程的推出而退出.后台线程不妨碍程序的 ...

  9. Java8 新特性 Optional 类

    Optional 类的简介   Optional类的是来自谷歌Guava的启发,然后就加入到Java8新特性中去了.Optional类主要就是为子决解价值亿万的错误,空指针异常.   Optional ...

随机推荐

  1. plsql 查询历史执行语句

    control+e. 如果执行删除.修改.增加的操作,未提交的历史记录中也有.

  2. apicloud 上传/更新App版本到 ios store 流程步骤

    app更新 上传APP的地址: https://itunesconnect.apple.com/login 苹果开发者中心: https://developer.apple.com/ app正式包更新 ...

  3. [AngularJS] ng-ture-value & ng-false-value

    When you have a checkbox, not necessary that just 'ture' & 'false', you might have 'yes', 'no', ...

  4. elasticsearch中的几个概念总结

    1.Geo spatial search : 地理空间搜索,可以在搜索查询中指定的某一距离内查找所要的内容.也可以返回以当前为圆心,逐渐添加圆的半径.直到找到所匹配到的内容. 參考:http://ww ...

  5. Android4.2.2下Stagefright下OMX编解码器组件的控制流

    本文均属自己阅读源代码的点滴总结.转账请注明出处谢谢. 欢迎和大家交流. qq:1037701636 email:gzzaigcn2012@gmail.com Android源代码版本号Version ...

  6. [转]GLTF-3D图形界的JPEG

    GLTF简介 1.glTF(GL TransmissionFormat),即图形语言交换格式,它是一种3D内容的格式标准,由Khronos Group管理(Khronos Group还管理着OpenG ...

  7. hdoj--5569--matrix(动态规划)

    matrix Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Sub ...

  8. Linux下离线安装MySQL

    Linux下安装mysql 1 检查并卸载已安装mysql 命令:rpm -qa|grep -i mysql 命令:rpm -e --nodeps ‘上个命令后显示的本机已安装mysql依赖’ 如果存 ...

  9. [poj 2891] Strange Way to Express Integers 解题报告(excrt扩展中国剩余定理)

    题目链接:http://poj.org/problem?id=2891 题目大意: 求解同余方程组,不保证模数互质 题解: 扩展中国剩余定理板子题 #include<algorithm> ...

  10. 用LinkedList模拟Stack功能

    集合体系在Java中比较重要,整个集合体系是在JDK1.2版本后出现,Collection作为整个体系的顶层,拥有整个体系通用的功能.对于其下面的小弟,也是各有千秋.下面就一道面试题来看看Linked ...