网上下载的字幕有时和片源的时间轴不一致。我们能够自己写一个工具来调整,也就是总体向前移动几秒,或者向后移动几秒。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. iOS开发——GCD总结

    Grand Central Dispatch,简称GCD,在异步执行任务的技术之一. 一般将应用程序中记述的线程管理用的代码在系统级中实现,开发者只需要定义想执行的任务并追加到适当的Dispatch ...

  2. UVA-12186 Another Crisis 树形dp

    题目链接:https://cn.vjudge.net/problem/UVA-12186 题意 给出n, T和一棵树,树上每个节点需要选择T%个直属子节点. 问根节点一共需要选择几个节点. 思路 思路 ...

  3. kubernetes 项目

    1:CI/CD Docker: Harbor Git Jenkins 2:微服务 istio

  4. linux 系统相关命令

    说明:此篇以 Debian ( ubuntu16.04 ) 命令为例 1. tab键默认是不能自动补全命令 apt install bash-completion // 安装完成之后重启系统 2. 虚 ...

  5. ElementUi rules表单验证

    ElementUi 表单验证 工作中常用到的JS验证 可以在pattern中书写正则,并且配合elementUI进行表单验证. pattern 属性规定用于验证输入字段的模式.模式指的是正则表达式. ...

  6. Generator 简介

    Generator 就是一种状态机,封装多个内部状态. 执行 Generator 函数会返回一个遍历器对象(),也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数.返回的遍历器对 ...

  7. 题解 P3834 【【模板】可持久化线段树 1(主席树)】

    可持久化线段树的前置知识是权值线段树,但是你不学也没有太大的关系因为思想不是很难理解. 可持久化线段树支持历史记录查询,这是它赖以解题的方法. 在本题中思路是建立n颗线段树,然后对于每次询问,考虑其中 ...

  8. Qt之QCryptographicHash

    简述 QCryptographicHash类提供了生成密码散列的方法.该类可以用于生成二进制或文本数据的加密散列值.目前支持MD4.MD5.SHA-1.SHA-224.SHA-256.SHA-384和 ...

  9. HDU 2196 Computer(求树上每一个节点到其他点的最远距离)

    解题思路: 求出树的直径的两个端点.则树上每一个节点到其它点的最远距离一定是到这两个端点的距离中最长的那一个. #include <iostream> #include <cstri ...

  10. linux系统调用表(system call table)

    系统调用号 函数名 入口点 源码 0 read sys_read fs/read_write.c 1 write sys_write fs/read_write.c 2 open sys_open f ...