周末在家上看《Rome》,发现有中英文两种字幕切换,英文字幕还是大写,
于是写了个小程序,完成以下两个功能:
1、 convert all upper case to lower case把英文字幕变成小写
2、 attach Chinese script to English script
把中文字幕附件到英文字幕下面
程序源码见附件,效果就像很多港产片的字幕一样:
上面是英文字幕,下面是中文字幕。

如果你看电影的时候发现有中英文两种srt字幕文件,不妨用附件的程序一试,一句话:“谁用谁知道!”:)
/**
* Movie Script Converter
* 1、convert all upper case to lower case把英文字幕变成小写
* 2、attach Chinese script to English script 把中文字幕附件到英文字幕下面
*@category file
*@class MovieScriptConverter
*@author zhusheng3@126.com
*@date 2008-6-22 10:19:57
*@see
*/
result like:
---------------------------
12
00:02:04,567 --> 00:02:08,600
once, pompey was acknowledged
by all to be the greater man,
曾经,庞贝被公认为更有王者风范
---------------------------
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
/**
* Movie Script Converter
* 1、convert all upper case to lower case把英文字幕变成小写
* 2、attach Chinese script to English script 把中文字幕附件到英文字幕下面
*@category file
*@class MovieScriptConverter
*@author zhusheng3@gmail.com
*@date 2008-6-22 10:19:57
*@see
*/
public class MovieScriptConverter {
public static String [] chsScriptIdendifiers= new String[]{".chs.",".gb."};
public static String engScriptIdendifier=".eng.";
private static String tempFileOrDirName="temp";
/**
* 1,attach Chinese script to English Script,call mothod:
* mergeChs2Eng(File inFileOrDir,File outFileOrDir)
* 2,convert all letters from upper case to lower case,call mothod:
* upperCase2LowerCase(File inFileOrDir,File outLowerCaseFileOrDir)
* @param inFileOrDir
* @return
* change the input file or all sub dir's files
* 1,attach chs script to eng script
* 2,convert all letters from upper case to lower case
*/
public void convertAll(File inFileOrDir)
{
if(inFileOrDir.isFile())
{
tempFileOrDirName+="/"+inFileOrDir.getName();
File tempFileOrDir =new File(tempFileOrDirName);
if(tempFileOrDir.exists())
{
FileUtil.deleteFile(tempFileOrDir.getAbsolutePath());
// tempFileOrDir.delete();
tempFileOrDir.getParentFile().mkdirs();
}
else
{
tempFileOrDir.getParentFile().mkdirs();
}
mergeChs2Eng_singleFile(inFileOrDir,tempFileOrDir);
upperCase2LowerCase_singleFile(tempFileOrDir,inFileOrDir);
}
else if(inFileOrDir.isDirectory())
{
File tempFileOrDir =new File(tempFileOrDirName);
if( tempFileOrDir.exists())
{
FileUtil.deleteFile(tempFileOrDir.getAbsolutePath());
//tempFileOrDir.delete();
tempFileOrDir.mkdirs();
}
else
{
tempFileOrDir.mkdirs();
}
mergeChs2Eng_allSubFiles( inFileOrDir,tempFileOrDir,null,null,true);
upperCase2LowerCase_allSubFiles( tempFileOrDir,inFileOrDir,null,null,true);
//tempFileOrDir.delete();
FileUtil.deleteFile(tempFileOrDir.getAbsolutePath());
}
}
/**
* merge Chinese Movie script to English script
* for example:
---------------------------
12
00:02:04,567 --> 00:02:08,600
once, pompey was acknowledged
by all to be the greater man,
曾经,庞贝被公认为更有王者风范
---------------------------
* @param inFileOrDir,a file or a root Dir source,
* when input a dir,merge all its sub Dir's files
* @param outFileOrDir,output file or output root Dir
*/
public void mergeChs2Eng(File inFileOrDir,File outFileOrDir)
{
mergeChs2Eng_allSubFiles( inFileOrDir,outFileOrDir,null,null,true);
}
/**
* change all the English letters in inFile and all its sub Dir's files
* from Upper Case to Lower Case
* @param inFileOrDir, Upper Case :THE CITY IS CONSTANTLY ROILED BY CONFLICT
* @return outLowerCaseFileOrDir, lower Case :the city is constantly roiled by conflict
*/
public void upperCase2LowerCase(File inFileOrDir,File outLowerCaseFileOrDir)
{
upperCase2LowerCase_allSubFiles( inFileOrDir,outLowerCaseFileOrDir,null,null,true);
}
/**
* change all the English letters in inFile
* from Upper Case to Lower Case
* @param inFile,single file, Upper Case :THE CITY IS CONSTANTLY ROILED BY CONFLICT
* @return outLowerrCaseFile, lower Case :the city is constantly roiled by conflict
*/
private void upperCase2LowerCase_singleFile(File inFile,File outLowerrCaseFile) {
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(
inFile)));
bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outLowerrCaseFile)));
String line = null;
while ((line = br.readLine()) != null)
{
bw.write(line.toLowerCase());
bw.newLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
bw.close();
System.out.println("upperCase2LowerCase ");
System.out.println("Dir:"+inFile.getParent());
System.out.println(" -->"+outLowerrCaseFile.getParent());
System.out.println("File:"+inFile.getName());
System.out.println(" -->"+outLowerrCaseFile.getName());
System.out.println();
} catch (IOException e) {
}
}
}
}
private void upperCase2LowerCase_allSubFiles(File sourceRoot, File targetRoot,
String sourcePrefix, String targetPrefix, boolean isFirstTime)
{
if (isFirstTime)
{
sourcePrefix = sourceRoot.getAbsolutePath();
targetPrefix = targetRoot.getAbsolutePath();
}
try
{
String targetFilePath = "";
if (sourceRoot.isFile())
{
String targetPath = targetRoot.getAbsolutePath();
if (!targetPath.endsWith("/"))
{
targetPath = targetPath + "/";
}
targetFilePath = targetPath + sourceRoot.getName();
upperCase2LowerCase_singleFile(sourceRoot, new File(targetFilePath));
}
else if (sourceRoot.isDirectory())
{
File[] files = sourceRoot.listFiles();
for (int i = 0; i < files.length; i++)
{
String srcName = "";
String tgtName = "";
File tgtFile = null;
if (files[i].isFile())
{
srcName = files[i].getAbsolutePath();
tgtName = targetPrefix
+ srcName.substring(srcName
.indexOf(sourcePrefix)
+ sourcePrefix.length());
tgtFile = new File(tgtName);
upperCase2LowerCase_singleFile(files[i], tgtFile);
}
else if (files[i].isDirectory())
{
srcName = files[i].getAbsolutePath();
tgtName = targetPrefix
+ srcName.substring(srcName
.indexOf(sourcePrefix)
+ sourcePrefix.length());
tgtFile = new File(tgtName);
if (!tgtFile.exists())
{
tgtFile.mkdirs();
}
upperCase2LowerCase_allSubFiles(files[i], tgtFile, sourcePrefix,
targetPrefix, false);
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* merge Chinese Movie script to English script
* for example:
---------------------------
12
00:02:04,567 --> 00:02:08,600
once, pompey was acknowledged
by all to be the greater man,
曾经,庞贝被公认为更有王者风范
---------------------------
* @param chsFile
* @return outEngWithChsFile,the format is like above example
*/
private void mergeChs2Eng_singleFile(File engFile,File outEngWithChsFile)
{
if(!engFile.getName().contains(engScriptIdendifier))
{
return;
}
boolean isChsFileExists=false;
File chsFile=null;
for (String chsIdentifier : chsScriptIdendifiers)
{
String chsFileName=engFile.getAbsolutePath().replaceAll(engScriptIdendifier,chsIdentifier );
chsFile = new File(chsFileName);
if(chsFile.exists())
{
isChsFileExists=true;
break;
}
}
//System.err.println(""+chsFile.getAbsolutePath());
if (!isChsFileExists)
{
System.err.println("ERROR:"+engFile+"'s Chinese Script File does not exists!!");
for (String chsIdentifier : chsScriptIdendifiers)
{
System.out.println("not exists:"+engFile.getAbsolutePath().replaceAll(engScriptIdendifier, chsIdentifier));
}
return;
}
BufferedReader br_chs = null;
BufferedReader br_eng = null;
BufferedWriter bw = null;
try
{
br_chs = new BufferedReader(new InputStreamReader(new FileInputStream(
chsFile)));
br_eng =new BufferedReader(new InputStreamReader(new FileInputStream(
engFile)));
bw = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(outEngWithChsFile)));
String line_eng = null;
String lastLine=null;
String lineKey="";
//read english script file each line,
//and add Chinese script to each item
while ((line_eng = br_eng.readLine()) != null)
{
bw.write(line_eng);
if(!"".equalsIgnoreCase(line_eng))
{
if(line_eng.contains(" -->"))
{
/*
*attention:this line determine line key is:[00:32:49,367] if the line item below:
00:32:49,367 --> 00:32:51,167
they settle their political disputes
*/
lineKey = line_eng.substring(0, line_eng.indexOf("-->"));
}
}//if empty line,then attach according chinese script
else
{
String attachChsScript=attachChsScript(chsFile,lineKey);
//if there is no Chinese script ,then attach Chinese script.
//this condition to avoid repeat attach
boolean alreadyHasChineseScript=false;
if(hasChineseScript(lastLine))
{
alreadyHasChineseScript=true;
}
if(alreadyHasChineseScript==false)
{
bw.write(attachChsScript);
}
}
bw.newLine();
lastLine=line_eng;
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
br_eng.close();
br_chs.close();
bw.close();
System.out.println("mergeChs2Eng ");
System.out.println("Dir:"+engFile.getParent());
System.out.println(" -->"+outEngWithChsFile.getParent());
System.out.println("File:"+engFile.getName());
System.out.println(" -->"+outEngWithChsFile.getName());
System.out.println();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private void mergeChs2Eng_allSubFiles(File sourceRoot, File targetRoot,
String sourcePrefix, String targetPrefix, boolean isFirstTime)
{
if (isFirstTime)
{
sourcePrefix = sourceRoot.getAbsolutePath();
targetPrefix = targetRoot.getAbsolutePath();
}
try
{
String targetFilePath = "";
if (sourceRoot.isFile())
{
String targetPath = targetRoot.getAbsolutePath();
if (!targetPath.endsWith("/"))
{
targetPath = targetPath + "/";
}
targetFilePath = targetPath + sourceRoot.getName();
mergeChs2Eng_singleFile(sourceRoot, new File(targetFilePath));
}
else if (sourceRoot.isDirectory())
{
File[] files = sourceRoot.listFiles();
for (int i = 0; i < files.length; i++)
{
String srcName = "";
String tgtName = "";
File tgtFile = null;
if (files[i].isFile())
{
srcName = files[i].getAbsolutePath();
tgtName = targetPrefix
+ srcName.substring(srcName
.indexOf(sourcePrefix)
+ sourcePrefix.length());
tgtFile = new File(tgtName);
mergeChs2Eng_singleFile(files[i], tgtFile);
}
else if (files[i].isDirectory())
{
srcName = files[i].getAbsolutePath();
tgtName = targetPrefix
+ srcName.substring(srcName
.indexOf(sourcePrefix)
+ sourcePrefix.length());
tgtFile = new File(tgtName);
if (!tgtFile.exists())
{
tgtFile.mkdirs();
}
mergeChs2Eng_allSubFiles(files[i], tgtFile, sourcePrefix, targetPrefix, false);
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* Util mothod
* @param chsFile
* @param lineKey
* @return a String of Chinese script should be attached to english script
* according to the line idendified by lineKey
* @throws Exception
*/
private String attachChsScript(File chsFile,String lineKey) throws Exception
{
String attachedString="";
BufferedReader br_chs = new BufferedReader(new InputStreamReader(new FileInputStream(chsFile)));
String line_chs="";
while ((line_chs = br_chs.readLine()) != null)
{
//find the according Chinse line to English script
if(line_chs.contains(lineKey))
{
while((line_chs = br_chs.readLine())!=null)
{
if(!"".equalsIgnoreCase(line_chs))
{
attachedString =attachedString+line_chs+"/n";
}
else
{
break;
}
}
break;
}
}
return attachedString;
}
//determine if input string has Chinese Characters:double bytes char
private boolean hasChineseScript(String inputStr)
{
boolean result=false;
if(inputStr ==null) return result;
if(inputStr.length()!=inputStr.getBytes().length)
{
result=true;
}
return result;
}
public static void main(String[] args)
{
MovieScriptConverter.engScriptIdendifier=".eng.";
MovieScriptConverter.chsScriptIdendifiers= new String[]{".chs.",".gb."};
MovieScriptConverter aMovieScriptConverter=null;
////convert a single file
// aMovieScriptConverter = new MovieScriptConverter();
// File aFile=new File("e:/rome/Rome.S01E01.HR.HDTV.AC3.5.1.XviD-NBS.eng.srt");
// aMovieScriptConverter.convertAll(aFile);
////convert a dir and all its sub dir's files
aMovieScriptConverter = new MovieScriptConverter();
File aDir=new File("d:/upload");
aMovieScriptConverter.convertAll(aDir);
}
}