前言
因为目前现在正在做毕业设计,需要一个功能能够将用户上传的视频上传到腾讯云的cos后获取视频的时长、分辨率、第一帧截图作为封面。而腾讯云上传后并不能获取视频的这些信息,所以只能再根据视频url地址来转换、流化,实现这一功能就需要使用FFmpeg来完成了。
下载安装
下载完windows系统的之后需要将它的bin目录配置到环境变量中。
在cmd下输入“ffmpeg -i” 如果出现这个则代表安装成功。
Java调用
使用java调用其实就是使用cmd命令来使用FFmpeg,首先导入maven包
<!-- 视频流处理 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
搞一个util方便调用
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import org.bytedeco.javacpp.Loader;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
public class VideoUtil {
/**
* 提取主方法
*
* @param path MP4视频路径
* @param tmpDir 存放封面图片和网络视频的临时目录
* @return 视频信息map
*/
public static Map<String,String> extract(String path, String tmpDir) throws Exception {
String mp4Path;
// 如果是网络视频先下载到临时目录
if (path.startsWith("http")) {
mp4Path = tmpDir + "/" + IdUtil.simpleUUID() + ".mp4";
HttpUtil.downloadFile(path, mp4Path);
} else {
mp4Path = path;
}
return ffmpegExtractImage(mp4Path, tmpDir + "\" + IdUtil.simpleUUID() + ".jpg");
}
/**
* 提取视频第一帧图片
*
* @param mp4Path 视频地址
* @param picPath 图片存放地址
* @return 提取的图片地址
*/
public static Map<String,String> ffmpegExtractImage(String mp4Path, String picPath) throws Exception {
String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
ProcessBuilder extractBuilder =
new ProcessBuilder(
ffmpeg, "-i", mp4Path, "-f", "image2", "-ss", "1","-frames:v", "1", picPath);
Map<String,String> map;
Process start = extractBuilder.start();
map = videoBaseInfo(start.getErrorStream());
start.waitFor();
// 添加图片文件路径
map.put("coverPath",picPath);
return map;
}
/**
* 获取视频的基本信息
*
* @param inputStream ffmpeg的输入流
* @return
*/
public static Map<String,String> videoBaseInfo(InputStream inputStream) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
Map<String,String> map = new HashMap<>();
String line = "";
while ((line = br.readLine()) != null) {
// 解析出视频信息
if (line.contains("Duration")) {
String duration = line.substring(line.indexOf("Duration") + 10).split(",")[0];
map.put("duration",duration);
}
if (line.contains("Stream")) {
String ratio = line.split(",")[3].substring(1);
map.put("ratio",ratio);
break;
}
}
return map;
}
public static void main(String[] args) throws Exception {
// System.out.println(extract("C:\Users\linyuxian\Downloads\436977885-1-208.mp4", "C:\Users\linyuxian\Downloads"));
System.out.println(extract("https://lmusic-1302280959.cos.ap-chengdu.myqcloud.com/lin/foodRecord/video/1063904913-1-208.mp4","C:\Users\linyuxian\Desktop"));
}
}
弊端
FFmpg使用起来确实简单方便,但它对于java程序来说也有两个弊端
- Java项目最终打包是要使用jar包的,一般都是运行在Linux服务器上,要想使用FFmpg又必须要在服务器上下载安装并且还需要单独的一套linux代码,十分不方便。
- FFmpg不能直接解析MultipartFile,需要根据视频地址把视频下载下来才能去解析,最后又需要把临时视频删除,增加了无端的流量耗用和性能消耗。