java通过FFmpeg粗加工处理视频转码、截封面图
这是我参与更文挑战的第11天,活动详情查看: 更文挑战
业务场景:
通过java对上传的视频进行转码,截封面图,然后将视频上传到文件存储服务器
使用工具
-
ffmpeg(视频处理工具)下载地址:ffmpeg.org/download.ht…
-
jave.jar(工具jar包)下载地址:www.sauronsoftware.it/projects/ja…
(jave包是一个处理ffmpeg的一个开源框架,比较老旧,功能也相对欠缺,本文只用它来做一个视频格式转换的功能)
pom.xml配置
<!--FFmpeg集成jar包-->
<dependency>
<groupId>joinery</groupId>
<artifactId>jave</artifactId>
<version>1.0.2</version>
</dependency>
实现原理
将传过来的视频先写入在本地test1,然后调用本地安装的视频处理工具ffmpeg进行处理,把处理好的文件放在本地test2,调用相关API把test2里的文件上传到文件存储服务器,上传完毕后删除掉本地test1和test2里的文件
代码实现
视频转码部分的处理直接使用了jave包封装好的方法处理,视频截封面图的功能jave并没有封装好,此处直接是在代码里把处理截图的命令拼接好,然后通过调用系统的命令行去让ffmpeg执行该命令
视频处理相关方法
private static void dealStreamCommon(BufferedReader buff) {
String line = null;
try {
while ((line = buff.readLine()) != null) {
logger.warn("output: " + line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
buff.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 删除文件
*
* @param file
*/
public static void deleteFile(File file) {
if (file.exists()) {
file.delete();
}
}
开启线程处理Ffmpeg处理流
/**
*
* @param process
*/
private static void dealStream(Process process) {
if (process == null) {
return;
}
// 处理InputStream的线程
new Thread() {
@Override
public void run() {
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
dealStreamCommon(in);
}
}.start();
// 处理ErrorStream的线程
new Thread() {
@Override
public void run() {
BufferedReader err = new BufferedReader(new InputStreamReader(process.getErrorStream()));
dealStreamCommon(err);
}
}.start();
}
截取视频中的一帧作为封面图片
/**
*
*
* @param fileName
* ffmpeg -i /Users/jinx/Downloads/test.mp4 -y -f image2 -ss
* 00:00:01 -vframes 1 /Users/jinx/Downloads/test.jpeg
* @return
*/
public static boolean covPic(String fileName, String time, String outName, String size) {
List<String> command = new ArrayList<String>();
command.add(FFMPEG_PATH);
command.add("-i");
//文件输入源路径
command.add(fileName);
command.add("-y");
command.add("-f");
command.add("image2");
command.add("-ss");
//截取的时间点格式为 00:00:01
command.add(time);
command.add("-vframes");
command.add("1");
command.add("-s");
//截取的图片大小,格式为:1920x1080
command.add(size);
//文件输出路径,格式为 11.jpg
command.add(outName);
try {
Process videoProcess = new ProcessBuilder(command).start();
dealStream(videoProcess);
videoProcess.waitFor();
return true;
} catch (Exception e) {
}
return false;
}