1.调用
if (StringUtil.equals(HotCacheData.os, "linux")) {
msg = processVideo(filePath, n, targetUrl);
} else {
if (StringUtil.isEmpty(HotCacheData.ffmpegUrl)) {
throw new CustomResultException(ResultEn.FILE_LOADUP_ERROR.getCode(), "win系统ffmpeg的执行文件未找到");
}
msg = processVideo(HotCacheData.ffmpegUrl, filePath, n, targetUrl);
}
2.封装的方法
private static String processVideo(String filePath, int n, String targetUrl) {
String msg = "";
StringBuilder commend = new StringBuilder();
commend.append("ffmpeg ")
.append(" -i ")
.append(filePath)
.append(" -ss ")
.append(" ").append(n).append(" ")
.append(" -f ")
.append(" image2 ")
.append(targetUrl);
Process process = null;
try {
ProcessBuilder pb = new ProcessBuilder();
//因为process执行命令并不是像窗口中执行shell一样,所以需要添加参数,用于执行脚本
pb.command("sh", "-c", commend.toString());
//processBuilder支持将inputStream与ErrorStream合并为一个Stream,即所有的输出信息都合并到inputStream中,这样做可以减少一个线程
pb.redirectErrorStream(true);
process = pb.start();
//由于process机制原因会导致死锁,所以需要在waitfor方法之前,创建线程用于处理inputstream中缓冲区的数据,这也是为什么要合并inputstream和errorstream的原因,在这里可以少创建一个线程
readInputStream(process.getInputStream());
//返回0则表示输出正常
int resultCode = process.waitFor();
} catch (Exception e) {
msg = ExcBox.getExcMsg(e);
log.info("\n视频解析帧画面异常:");
log.info(msg);
} finally {
try {
if (null != process) {
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().close();
}
} catch (Exception ignored) {
}
}
return msg;
}
linux
private static String processVideo(String ffmpegPath, String filePath, int n, String targetUrl) {
String msg = "";
Process process = null;
try {
ProcessBuilder pb = new ProcessBuilder();
//因为process执行命令并不是像窗口中执行shell一样,所以需要添加参数,用于执行脚本
pb.command(ffmpegPath, "-y", "-i", filePath, "-ss", n + "", "-f", "image2", targetUrl);
//processBuilder支持将inputStream与ErrorStream合并为一个Stream,即所有的输出信息都合并到inputStream中,这样做可以减少一个线程
pb.redirectErrorStream(true);
process = pb.start();
//由于process机制原因会导致死锁,所以需要在waitfor方法之前,创建线程用于处理inputstream中缓冲区的数据,这也是为什么要合并inputstream和errorstream的原因,在这里可以少创建一个线程
readInputStream(process.getInputStream());
//返回0则表示输出正常
int resultCode = process.waitFor();
} catch (Exception e) {
msg = ExcBox.getExcMsg(e);
log.info("\n视频解析帧画面异常:");
log.info(msg);
} finally {
try {
if (null != process) {
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().close();
}
} catch (Exception ignored) {
}
}
return msg;
}
win
//创建线程处理输出流
private static void readInputStream(InputStream in) {
executor.execute(new Runnable() {
@Override
public void run() {
InputStreamReader reader = null;
try {
reader = new InputStreamReader(in);
LineNumberReader line = new LineNumberReader(reader);
String str = null;
while ((str = line.readLine()) != null) {
System.out.println(str);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
共通部分