周末在家上看《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); } }