Java实现SRT字幕中英文合成工具

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



	}

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java ffmpeg 字幕合成是指使用Java编程语言和ffmpeg这个强大的多媒体处理工具,将视频和字幕文件合成为一个新的视频文件的过程。一般来说,字幕文件可以是SRT、ASS、SSA等常见的格式,而视频文件格式则没有限制。 在Java中使用ffmpeg进行字幕合成的步骤如下: 1.下载和安装ffmpeg,并配置好环境变量。 2.在Java程序中引入ffmpeg相关的库文件。 3.编写Java代码,使用ProcessBuilder类创建一个新的进程,并在命令行中传递ffmpeg命令和参数,用于指定输入文件、输出文件、字幕文件及其格式等信息。 4.启动进程,并等待ffmpeg的执行结果。 5.如果合成成功,则可以得到一个新的视频文件,包含了原始视频和字幕。如果有必要,可以使用Java程序来对新文件进行进一步处理。 Java ffmpeg 字幕合成可以应用于很多场景,比如制作字幕影片、合成公司宣传视频等。如果您需要使用Java ffmpeg 字幕合成技术,需要掌握ffmpeg的使用方法和Java语言的编程技巧。同时,您还需要了解视频和字幕文件之间的格式换和编码等知识,以确保最终合成的文件质量和兼容性。 ### 回答2: Java是一种广泛使用的编程语言,被用于开发各种类型的应用程序,而FFmpeg是一个流行的开源视频处理工具。在Java中使用FFmpeg进行字幕合成是非常常见的。字幕合成是将字幕嵌入到视频中的过程,使得观众可以看到字幕并理解视频的内容。 为了在Java中使用FFmpeg进行字幕合成,首先需要下载并安装FFmpeg程序。然后,可以使用Java中的ProcessBuilder类来调用FFmpeg程序并使用它的命令行参数来合成字幕。简单的代码示例如下: ``` ProcessBuilder pb = new ProcessBuilder("ffmpeg", "-i", "video.mp4", "-vf", "subtitles=subs.srt", "output.mp4"); pb.start(); ``` 在这个例子中,我们使用ProcessBuilder来创建一个新的进程并运行FFmpeg程序,使用其命令行参数来合成字幕。该命令行参数包括输入视频文件名(video.mp4)、字幕文件名(subs.srt)以及输出文件名(output.mp4)。 在Java中使用FFmpeg合成字幕可以让开发者方便地为自己的视频添加字幕,并提供更好的观看体验。此外,由于Java是跨平台的编程语言,因此该过程在不同平台上都可以使用。 ### 回答3: Java FFMPEG 字幕合成是一种将字幕和视频合并在一起,生成新的视频文件的技术。在实际应用中,通常使用 FFMPEG 提供的 API 将字幕文件与视频文件进行合并。使用 Java 编程语言可以方便地操作 API,并实现字幕和视频合并成一段新的视频的功能。在合成字幕时,需要指定字幕的样式、字体、位置、颜色、大小以及出现和消失的时间等参数。Java 语言具有简单、易读、易于维护和交互性好等特点,利用 Java 语言编写的 FFMPEG 字幕合成程序可以实现更好的用户交互性。另外,合成的视频文件的质量在很大程度上依赖于 FFMPEG 命令行工具的配置。因此,在编写 Java FFMPEG 字幕合成程序时,需要根据具体情况,适时地进行参数调整和优化,确保合成出来的视频文件质量达到最佳效果。总之,Java FFMPEG 字幕合成技术为用户提供了一个可定制和灵活的视频字幕合成方案,既方便了用户使用,又提高了视频合成的质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值