一、概要
执行FFmpeg必须是服务程序和FFmpeg在同一个环境内,可以相互调用,如果是docker部署也是需要在容器中安装FFmpeg,或者可以使用ssh方式远程执行!
二、工具类
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.concurrent.TimeUnit;
/**
* 执行FFmpeg命令工具类
*/
@Component
public class FfmpegUtil {
private static final Logger logger = LoggerFactory.getLogger(FfmpegUtil.class);
// 命令执行超时时间(秒)
private static final int timeout = 300;
/**
* 执行FFmpeg命令
*/
public boolean execCmd(String[] cmd) {
return execCmd(cmd, null);
}
/**
* 执行FFmpeg命令(带输出处理)
*/
public boolean execCmd(String[] cmd, OutputHandler outputHandler) {
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
// 合并标准错误和标准输出
processBuilder.redirectErrorStream(true);
try {
Process process = processBuilder.start();
// 处理输出流
if (outputHandler != null) {
handleOutput(process, outputHandler);
}
// 等待进程完成
boolean finished = process.waitFor(timeout, TimeUnit.SECONDS);
if (!finished) {
process.destroyForcibly();
logger.error("FFmpeg命令执行超时: {}", String.join(" ", cmd));
return false;
}
int exitValue = process.exitValue();
if (exitValue == 0) {
logger.info("FFmpeg命令执行成功: {}", String.join(" ", cmd));
return true;
} else {
logger.error("FFmpeg命令执行失败,退出码: {}, 命令: {}", exitValue, String.join(" ", cmd));
return false;
}
} catch (IOException | InterruptedException e) {
logger.error("FFmpeg命令执行异常: {}", e.getMessage(), e);
return false;
}
}
/**
* 处理输出流
*/
private void handleOutput(Process process, OutputHandler outputHandler) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
outputHandler.handle(line);
}
} catch (IOException e) {
logger.error("处理FFmpeg输出流异常: {}", e.getMessage());
}
}
/**
* 输出处理器接口
*/
public interface OutputHandler {
void handle(String line);
}
}
三、测试类
java
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.beans.factory.annotation.Autowired;
/**
* FFMPEG测试
*/
@SpringBootTest
public class FfmpegUtilTests {
@Autowired
private FfmpegUtil ffmpegUtil;
@Test
void test() {
// 不带输出处理
boolean b = ffmpegUtil.execCmd(new String[]{"/opt/homebrew/bin/ffmpeg", "-version"});
System.out.println(b);
// 带输出处理信息
ffmpegUtil.execCmd(new String[]{"/opt/homebrew/bin/ffmpeg", "-version"}, new FfmpegUtil.OutputHandler() {
@Override
public void handle(String line) {
System.out.println( line);
}
});
}
}
注意:ffmpeg的位置是需要指定的