在命令行里直接执行ffmpeg没有问题,但用java调用就不行了。
原因是ffmpeg在linux的shell命令行下当然能执行(如果ffmpeg在/usr/bin下),但java调用的时候并不是shell模式,所以不能直接执行
解决办法:
请用完整的ffmpeg路径,另外需要使用shell命令执行。代码如下:
exec = Runtime.getRuntime().exec(new String[]{"sh","-c",cmd});
printProcessMsg(exec);
int i = exec.waitFor();
其中cmd是命令
下面是部分java代码:
if(os.indexOf("linux")>=0){
cmd = cleanUpBean.getFfmpegBinPath()+File.separator+"ffmpeg -loglevel quiet -y -i \"concat:"+tsSplice+"\" -bsf:a aac_adtstoasc -acodec copy -vcodec copy -f mp4 "+alarmMp4DestPath+File.separator+mediaBean.getUuid()+".mp4";
exec = Runtime.getRuntime().exec(new String[]{"sh","-c",cmd});
}else if(os.indexOf("windows")>=0){
cmd = "cmd /c "+folderTsPath.substring(0,folderTsPath.indexOf(":")+1)+" && cd " + folderTsPath + " && "+cleanUpBean.getFfmpegBinPath()+File.separator+"ffmpeg.exe -loglevel quiet -y -i \"concat:"+tsSplice+"\" -bsf:a aac_adtstoasc -acodec copy -vcodec copy "+alarmMp4DestPath+File.separator+mediaBean.getUuid()+".mp4";
exec = Runtime.getRuntime().exec(cmd);
}else{
_log.warn("未知的操作系统:{}",os);
return;
}
_log.info("ffmpeg copy cmd is: {}",cmd);
printProcessMsg(exec);
int i = exec.waitFor();
_log.info("Process waitFor 返回结果:{}",i);
/**
* 处理process输出流和错误流,防止进程阻塞,在process.waitFor();前调用
* @param exec
* @throws IOException
*/
private void printProcessMsg(Process exec) throws IOException {
//防止ffmpeg进程塞满缓存造成死锁
InputStream error = exec.getErrorStream();
InputStream is = exec.getInputStream();
StringBuffer result = new StringBuffer();
String line = null;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(error,"GBK"));
BufferedReader br2 = new BufferedReader(new InputStreamReader(is,"GBK"));
while((line = br.readLine()) != null){
result.append(line+"\n");
}
_log.info("FFMPEG视频转换进程错误信息:"+result.toString());
result = new StringBuffer();
line = null;
while((line = br2.readLine()) != null){
result.append(line+"\n");
}
_log.info("FFMPEG视频转换进程输出内容为:"+result.toString());
}catch (IOException e2){
e2.printStackTrace();
}finally {
error.close();
is.close();
}
}