java线程代码:
package com.itc.vwm;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import com.itc.vwm.json.TransVideoObj;
import com.itc.vwm.model.TranscodeVideo;
import com.itc.vwm.module.FFmpegProcess;
import com.itc.vwm.module.TranscodeVideoHandle;
/**
*
* 于第一种方式相比,优势 1>当启动和去取消任务时可以控制 2>第一次执行任务时可以指定你想要的delay时间
*
* 在实现时,Timer类可以调度任务,TimerTask则是通过在run()方法里实现具体任务。 Timer实例可以调度多任务,它是线程安全的。
* 当Timer的构造器被调用时,它创建了一个线程,这个线程可以用来调度任务。 下面是代码:
*
* @author GT
*
*/
public class TranscodeVideoThread {
Timer timer;
TimerTask task;
TransVideoObj videoObj= new TransVideoObj();
public TranscodeVideoThread(){
task = new TimerTask() {
@Override
public void run() {
//task to run goes here
FFmpegProcess.getInstance().runFlag=0;
List<TranscodeVideo> tranVideoList = TranscodeVideoHandle.getInstance().getTranscodeVideo();
if(tranVideoList.size()>0){
TranscodeVideo video = (TranscodeVideo)tranVideoList.get(0);
String startTime = TranscodeVideoHandle.getInstance().startTranscodeVideo(video);
video.setType(1);
boolean buer = FFmpegProcess.getInstance().processMP4("/home/vod/", video);
if(FFmpegProcess.getInstance().runFlag==0){
String endTime = TranscodeVideoHandle.getInstance().endTranscodeVideo(video);
video.setStartTime(startTime);
video.setEndTime(endTime);
video.setType(2);
//System.out.println("----通知页面");
TranscodeVideoHandle.getInstance().ReportTransVideoRes(video,"100%",buer);
}
}
}
};
}
public void Start(){
timer = new Timer();
/*启动后 延迟半分钟执行*/
long delay = 30*1000;
/*1000毫秒执行一次*/
long intevalPeriod = 5*1000;//30*1000;
// schedules the task to be run in an interval
timer.scheduleAtFixedRate(task, delay, intevalPeriod);
}
public void Stop(){
timer.cancel();
}
}
java线程调用的核心类的转码函数:
package com.itc.vwm.module;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import com.itc.vwm.model.TranscodeVideo;
public class FFmpegProcess {
private static FFmpegProcess _instance = new FFmpegProcess();
public static FFmpegProcess getInstance(){
return _instance;
}
public int runFlag = 0;
private static String inputPath = "";
private static String outputPath = "";
private static String ffmpegPath = "";
private static void getPath() { // 先获取当前项目路径,在获得源文件、目标文件、转换器的路径
File diretory = new File("");
try {
String currPath = diretory.getAbsolutePath();
inputPath = currPath + "\\input\\test.wmv";
outputPath = "/home/vod/";
ffmpegPath = currPath + "\\ffmpeg\\";
System.out.println(currPath);
}
catch (Exception e) {
System.out.println("getPath出错");
}
}
private static boolean process() {
int type = checkContentType();
boolean status = false;
if (type == 0) {
System.out.println("直接转成flv格式");
status = processFLV(inputPath);// 直接转成flv格式
} else if (type == 1) {
String avifilepath = processAVI(type);
if (avifilepath == null)
return false;// 没有得到avi格式
status = processFLV(avifilepath);// 将avi转成flv格式
}
return status;
}
private static int checkContentType() {
String type = inputPath.substring(inputPath.lastIndexOf(".") + 1, inputPath.length())
.toLowerCase();
// ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
if (type.equals("avi")) {
return 0;
} else if (type.equals("mpg")) {
return 0;
} else if (type.equals("wmv")) {
return 0;
} else if (type.equals("3gp")) {
return 0;
} else if (type.equals("mov")) {
return 0;
} else if (type.equals("mp4")) {
return 0;
} else if (type.equals("asf")) {
return 0;
} else if (type.equals("asx")) {
return 0;
} else if (type.equals("flv")) {
return 0;
}
// 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),
// 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
else if (type.equals("wmv9")) {
return 1;
} else if (type.equals("rm")) {
return 1;
} else if (type.equals("rmvb")) {
return 1;
}
return 9;
}
private static boolean checkfile(String path) {
File file = new File(path);
if (!file.isFile()) {
return false;
}
return true;
}
// ffmpeg转mp4
public boolean processMP4(String filePath,TranscodeVideo video) {
if (!checkfile(filePath+video.getOrgVideoName())) {
System.out.println(filePath+video.getOrgVideoName() + " is not file");
return false;
}
/*
ffmpeg -y -i src.mp4 -vcodec libx264 -bf 0 -acodec aac -ar 48000 dst.mp4
*/
List<String> command = new ArrayList<String>();
command.add("ffmpeg");
command.add("-y");
command.add("-i");
command.add(filePath + video.getOrgVideoName());
command.add("-vcodec");
command.add("libx264");
command.add("-bf");
command.add("0");
command.add("-acodec");
command.add("aac");
command.add("-ar");
command.add("48000");
command.add(filePath + video.getVideoName());
try {
// 方案1
//Process videoProcess = Runtime.getRuntime().exec(ffmpegPath + "ffmpeg -i " + oldfilepath
// + " -ab 56 -ar 22050 -qscale 8 -r 15 -s 600x500 "
// + outputPath + "a.flv");
// 方案2
Process shellProcess = new ProcessBuilder(command).redirectErrorStream(true).start();
BufferedReader shellErrorResultReader = new BufferedReader(new InputStreamReader(shellProcess.getErrorStream()));
BufferedReader shellInfoResultReader = new BufferedReader(new InputStreamReader(shellProcess.getInputStream()));
String videoTotalTime = null;
String curTransTime = null;
long total_millionSeconds = 1;
String percent=null;
String infoLine=null;
String errorLine=null;
while ((infoLine = shellInfoResultReader.readLine()) != null || (errorLine = shellErrorResultReader.readLine()) != null) {
if(infoLine!=null){
//System.out.println("脚本执行信息:"+infoLine);
if(videoTotalTime==null&&infoLine.contains("Duration:")){
infoLine = infoLine.replaceAll(" ", "");//去掉空格
String[] timeArry =infoLine.split("Duration:");
String[] timeArry1=timeArry[1].split(",");
videoTotalTime = timeArry1[0];
//转毫秒
String[] temp1=videoTotalTime.split("\\.");
String[] temp2=temp1[0].split(":");
total_millionSeconds = Long.parseLong(temp2[0])*60*60*1000 + Long.parseLong(temp2[1])*60*1000 + Long.parseLong(temp2[2])*1000 + Long.parseLong(temp1[1]);
//System.out.println("1转毫秒:"+total_millionSeconds);
}
if(infoLine.contains("frame=")&&infoLine.contains("time=")&&infoLine.contains("bitrate=")&&infoLine.contains("speed=")){
infoLine = infoLine.replaceAll(" ", "");//去掉空格
String[] timeArry =infoLine.split("time=");
String[] timeArry1=timeArry[1].split("bitrate=");
curTransTime = timeArry1[0];
//转毫秒
String[] temp1=curTransTime.split("\\.");
String[] temp2=temp1[0].split(":");
long millionSeconds = Long.parseLong(temp2[0])*60*60*1000 + Long.parseLong(temp2[1])*60*1000 + Long.parseLong(temp2[2])*1000 + Long.parseLong(temp1[1]);
//System.out.println(total_millionSeconds+",2转毫秒:"+millionSeconds);
double temp =(double) millionSeconds/(double)total_millionSeconds;
percent = String.format("%.2f", temp*100)+"%";
TranscodeVideoHandle.getInstance().ReportTransVideoRes(video,percent,true);
}
System.out.print(".");
//System.out.println("视频总时长:"+videoTotalTime+",当前进度时间:"+curTransTime+",百分比:"+percent);
infoLine=null;
}
if(errorLine!=null){
System.out.println("脚本执行错误:"+errorLine);
errorLine=null;
}
if(runFlag==1){//跳出来
break;
}
}
// 等待程序执行结束并输出状态
if(runFlag==0){
int exitCode = shellProcess.waitFor();
if (0 == exitCode) {
System.out.printf("脚本文件执行成功:" + exitCode);
} else {
System.out.printf("脚本文件执行失败:" + exitCode);
}
}
if (null != shellInfoResultReader) {
shellInfoResultReader.close();
}
if (null != shellErrorResultReader) {
shellErrorResultReader.close();
}
if (null != shellProcess) {
shellProcess.destroy();
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
// 对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等), 可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
private static String processAVI(int type) {
List<String> commend = new ArrayList<String>();
commend.add(ffmpegPath + "mencoder");
commend.add(inputPath);
commend.add("-oac");
commend.add("lavc");
commend.add("-lavcopts");
commend.add("acodec=mp3:abitrate=64");
commend.add("-ovc");
commend.add("xvid");
commend.add("-xvidencopts");
commend.add("bitrate=600");
commend.add("-of");
commend.add("avi");
commend.add("-o");
commend.add(outputPath + "a.avi");
try {
ProcessBuilder builder = new ProcessBuilder();
Process process = builder.command(commend).redirectErrorStream(true).start();
PrintStream ps1 = new PrintStream(process.getOutputStream());
//PrintStream printStream2 = new PrintStream(process.getErrorStream());
process.waitFor();
return outputPath + "a.avi";
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// ffmpeg能解析的格式:(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
private static boolean processFLV(String oldfilepath) {
if (!checkfile(inputPath)) {
System.out.println(oldfilepath + " is not file");
return false;
}
List<String> command = new ArrayList<String>();
command.add(ffmpegPath + "ffmpeg");
command.add("-i");
command.add(oldfilepath);
command.add("-ab");
command.add("56");
command.add("-ar");
command.add("22050");
command.add("-qscale");
command.add("8");
command.add("-r");
command.add("15");
command.add("-s");
command.add("600x500");
command.add(outputPath + "a.flv");
try {
// 方案1
// Process videoProcess = Runtime.getRuntime().exec(ffmpegPath + "ffmpeg -i " + oldfilepath
// + " -ab 56 -ar 22050 -qscale 8 -r 15 -s 600x500 "
// + outputPath + "a.flv");
// 方案2
Process videoProcess = new ProcessBuilder(command).redirectErrorStream(true).start();
videoProcess.getInputStream();
videoProcess.getErrorStream();
PrintStream ps = new PrintStream(videoProcess.getOutputStream());
//PrintStream ps = new PrintStream(videoProcess.getErrorStream());
//new PrintStream(videoProcess.getInputStream());
//new PrintStream(videoProcess.getErrorStream());
videoProcess.waitFor();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}