使用Java修改字幕檔案
今天在下了一部電影,準備看時卻發現網上的字幕都和電影不同步,整整差了一分鐘。本來暴風倒是可以調節字幕的延遲,但最大隻能延遲三十幾秒,無奈之下只好手動改字幕……
字幕檔案是.srt格式的,但考慮到其它檔案格式的讀取,先建立一個抽象的父類,以後不同型別檔案的操作類都繼承這個父類。
SubtitleDesigner實現了兩個介面,forward和delay分別用來提前和延遲字幕。
下面就開始針對srt檔案實現字幕的修改
子類除了實現父類的抽象方法外,還有幾個私有方法:
[b]
private boolean editSubtitle(int ctl, long msecond)
[/b]
主要的一個函式,實現字幕的延遲和提前操作。
[b]
private String[] getStartAndEndTime(String line)
[/b]
從字幕檔案中表示時間開始和結束的行中提取開始和結束時間,srt檔案中像這樣的行
00:00:00,229 --> 00:00:03,756
處理後會返回一個2維String,0和1的位置分別儲存開始和結束的時間(在這裡是00:00:00,229和00:00:03,756)
[b]
private int[] getTimes(String inTime)
[/b]
從上面函式得到的字串中獲得時、分、秒、毫秒的整數值,儲存在返回的int陣列中
[b]
private long timesToMs(int times[])
private int[] msToTimes(long ms)
[/b]
從上面函式得到的陣列計算出毫秒數/從毫秒數得到時分秒毫秒的陣列
[b]
private int[] reduceMs(int[] times, long ms)
private int[] addMs(int[] times, long ms)
[/b]
提前/延遲一定時間,返回時分秒毫秒的整形陣列。
整個類的具體實現是這樣的:
好了,在main函式中測試一下編好的類……
原始檔中有一段是這樣的:
[quote]
1
00:00:00,229 --> 00:00:03,756
貝蒂,能到外面聊幾句嗎?
2
00:00:18,447 --> 00:00:21,780
- 什麼事?可可
- 你姨媽打電話給我
[/quote]
生成的新檔案裡變為:
[quote]
1
00:00:59,229 --> 00:01:02,756
貝蒂,能到外面聊幾句嗎?
2
00:01:17,447 --> 00:01:20,780
- 什麼事?可可
- 你姨媽打電話給我
[/quote]
正好延遲了59秒。
OK!終於可以看電影了(為了看這玩意花了我快一小時,容易麼……)
以後有時間的話為這個程式再加一個圖形介面吧,先把現有程式碼傳上來。
字幕檔案是.srt格式的,但考慮到其它檔案格式的讀取,先建立一個抽象的父類,以後不同型別檔案的操作類都繼承這個父類。
package movie;
public abstract class SubtitleDesigner {
protected String src,des;
public SubtitleDesigner(String src,String des){
this.src = src;
this.des = des;
}
public abstract boolean forward(long msecond);
public abstract boolean delay(long msecond);
}
SubtitleDesigner實現了兩個介面,forward和delay分別用來提前和延遲字幕。
下面就開始針對srt檔案實現字幕的修改
子類除了實現父類的抽象方法外,還有幾個私有方法:
[b]
private boolean editSubtitle(int ctl, long msecond)
[/b]
主要的一個函式,實現字幕的延遲和提前操作。
[b]
private String[] getStartAndEndTime(String line)
[/b]
從字幕檔案中表示時間開始和結束的行中提取開始和結束時間,srt檔案中像這樣的行
00:00:00,229 --> 00:00:03,756
處理後會返回一個2維String,0和1的位置分別儲存開始和結束的時間(在這裡是00:00:00,229和00:00:03,756)
[b]
private int[] getTimes(String inTime)
[/b]
從上面函式得到的字串中獲得時、分、秒、毫秒的整數值,儲存在返回的int陣列中
[b]
private long timesToMs(int times[])
private int[] msToTimes(long ms)
[/b]
從上面函式得到的陣列計算出毫秒數/從毫秒數得到時分秒毫秒的陣列
[b]
private int[] reduceMs(int[] times, long ms)
private int[] addMs(int[] times, long ms)
[/b]
提前/延遲一定時間,返回時分秒毫秒的整形陣列。
整個類的具體實現是這樣的:
package movie;
import java.io.*;
import java.util.regex.*;
public class SrtDesigner extends SubtitleDesigner {
public static final int DELAY = 0;
public static final int FORWARD = 1;
public SrtDesigner(String src, String des) {
super(src, des);
}
private long timesToMs(int times[]) {
long ms;
ms = (times[0] * 3600 + times[1] * 60 + times[2]) * 1000 + times[3];
return ms;
}
private int[] msToTimes(long ms) {
int[] times = new int[4];
long tmp = ms;
times[3] = (int) (tmp % 1000);
tmp = tmp / 1000;
times[2] = (int) (tmp % 60);
tmp = tmp / 60;
times[1] = (int) (tmp % 60);
tmp = tmp / 60;
times[0] = (int) (tmp);
return times;
}
private int[] addMs(int[] times, long ms) {
long tmp;
int ret[];
tmp = timesToMs(times);
tmp += ms;
ret = msToTimes(tmp);
return ret;
}
private int[] reduceMs(int[] times, long ms) {
long tmp;
int ret[];
tmp = timesToMs(times);
tmp -= ms;
if(tmp<0)
return null;
ret = msToTimes(tmp);
return ret;
}
private String formatTime(int[] times){
String ret;
ret = String.format("%02d:%02d:%02d,%03d",times[0],times[1],times[2],times[3]);
return ret;
}
private int[] getTimes(String inTime) {
int[] times = new int[4];
String tmp[] = inTime.split(",");
times[3] = Integer.parseInt(tmp[1]);
String time[] = tmp[0].split(":");
times[0] = Integer.parseInt(time[0]);
times[1] = Integer.parseInt(time[1]);
times[2] = Integer.parseInt(time[2]);
return times;
}
private String[] getStartAndEndTime(String line) {
Pattern p = Pattern.compile("(\\d\\d:\\d\\d:\\d\\d,\\d\\d\\d)");
Matcher m = p.matcher(line);
String times[] = new String[2];
times[0] = m.find() ? m.group() : null;
times[1] = m.find() ? m.group() : null;
//System.out.println("Start:" + times[0] + "End:" + times[1]);
if (times[0] == null || times[1] == null)
return null;
return times;
}
private boolean editSubtitle(int ctl, long msecond) {
File srcFile = new File(src);
File desFile = new File(des);
BufferedReader reader = null;
BufferedWriter writer = null;
boolean visibleFlag = true;//是否顯示
String line;
try {
reader = new BufferedReader(new FileReader(srcFile));
writer = new BufferedWriter(new FileWriter(desFile));
String regex = "\\d\\d:\\d\\d:\\d\\d,\\d\\d\\d --> \\d\\d:\\d\\d:\\d\\d,\\d\\d\\d";
while ((line = reader.readLine()) != null) {
if (Pattern.matches(regex, line)) {
visibleFlag = true;
String startAndEndTimes[];
int startTimes[], endTimes[];
if ((startAndEndTimes = getStartAndEndTime(line)) == null)
return false;
startTimes = getTimes(startAndEndTimes[0]);
endTimes = getTimes(startAndEndTimes[1]);
if(ctl == FORWARD){
startTimes = reduceMs(startTimes, msecond);
endTimes = reduceMs(endTimes, msecond);
if(startTimes==null||endTimes==null){
visibleFlag = false;
continue;
}
}else{
startTimes = addMs(startTimes, msecond);
endTimes = addMs(endTimes, msecond);
}
line = formatTime(startTimes) + " --> " + formatTime(endTimes);
// System.out.println(formatTime(startTimes));
// System.out.println(formatTime(endTimes));
}
if(visibleFlag){
writer.write(line + "\n");
//System.out.println(line);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
reader.close();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
@Override
public boolean delay(long msecond) {
editSubtitle(DELAY, msecond);
return false;
}
@Override
public boolean forward(long msecond) {
editSubtitle(FORWARD, msecond);
return false;
}
}
好了,在main函式中測試一下編好的類……
public static void main(String args[]) {
System.out.println("Dealing with file");
SubtitleDesigner designer = new SrtDesigner("./src.srt", "./des.srt");
designer.delay(59000);
System.out.println("Done!!");
}
原始檔中有一段是這樣的:
[quote]
1
00:00:00,229 --> 00:00:03,756
貝蒂,能到外面聊幾句嗎?
2
00:00:18,447 --> 00:00:21,780
- 什麼事?可可
- 你姨媽打電話給我
[/quote]
生成的新檔案裡變為:
[quote]
1
00:00:59,229 --> 00:01:02,756
貝蒂,能到外面聊幾句嗎?
2
00:01:17,447 --> 00:01:20,780
- 什麼事?可可
- 你姨媽打電話給我
[/quote]
正好延遲了59秒。
OK!終於可以看電影了(為了看這玩意花了我快一小時,容易麼……)
以後有時間的話為這個程式再加一個圖形介面吧,先把現有程式碼傳上來。
相關文章
- 字幕檔案srt筆記筆記
- Java 例項 - 修改檔案最後的修改日期Java
- 使用touch命令修改檔案時間
- Java程式碼修改yml配置檔案屬性Java
- 使用vim修改linux中的檔案Linux
- sed 修改檔案
- 使用 Java 解析XML檔案JavaXML
- java批量修改檔名Java
- Ubuntu修改Hosts檔案工具HostsTool使用說明Ubuntu
- Mac電腦hosts檔案如何修改?macOS修改Hosts檔案教程Mac
- SVN培訓筆記(下拉專案、同步修改、新增檔案、修改檔案、刪除檔案、改名檔案等)筆記
- 使用Java處理大檔案Java
- Git修改配置檔案Git
- windows 修改hosts檔案Windows
- Linux下修改檔案建立時間(修改檔案更改時間)Linux
- Docker非root使用者修改/etc/hosts檔案Docker
- linux 修改hosts檔案以及修改hostnameLinux
- git提示檔案有修改但實際檔案無修改解決方案Git
- win10 如何修改hosts檔案 win10 如何修改host檔案Win10
- Java 如何打增量 jar 包【修改部分檔案不需全部打包】JavaJAR
- 修改Java檔案不用重啟Tomcat服務的方法JavaTomcat
- 使用ant編譯Java檔案(一)編譯Java
- 使用ant編譯Java檔案(二)編譯Java
- mac 修改 /etc/hosts 檔案Mac
- phpMyadmin配置檔案修改PHP
- ubuntu下修改host檔案Ubuntu
- 修改Oracle的配置檔案Oracle
- 用程式修改配置檔案
- 修改上傳檔案大小
- ubuntu下修改hosts檔案Ubuntu
- 修改資料檔案地址
- ubuntu 下修改host檔案Ubuntu
- python 修改文字檔案Python
- linux修改檔案所屬使用者和組Linux
- electron暴露配置檔案(使用者可隨時修改)
- 關於Java使用MinIO檔案伺服器操作檔案Java伺服器
- 增加日誌檔案,修改當前日誌檔案大小
- hosts檔案如何修改 hosts檔案修改後無法儲存怎麼解決