依赖导入
<!-- 获取时长 -->
<dependency>
<groupId>it.sauronsoftware</groupId>
<artifactId>jave</artifactId>
<version>1.0.2</version>
</dependency>
<!-- 截取封面(大小500MB左右,里面包含了多端的jar) -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.4</version>
</dependency>
/**
* 文件上传
*/
public R<String> uploadFile(MultipartFile file) throws Exception {
String path = "./file/";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdir();
}
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
String fileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + suffix;
File tmp = new File(path + fileName);
FileOutputStream fileOutputStream = new FileOutputStream(tmp);
IOUtils.copy(file.getInputStream(), fileOutputStream);
Map<String, Object> map = new HashMap<>();
map.put("size", FileSizeUtils.formatFileSize(file.getSize()));
map.put("fileName", fileName);
map = VideoUtils.fetchFrame(map, path, path + fileName, 1);
return R.isOk().data(map);
}
## 方法一(通过jar方法截取图片和获取时长,长视频可能会失败)
/**
* 获取指定视频的帧并保存为图片至指定目录
* @param videofile 源视频文件路径
* @param framefile 截取帧的图片存放路径
* @throws Exception
*/
public static Map fetchFrame(Map map, String framefile, String videofile)
throws Exception {
String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
File targetFile = new File(framefile+fileName);
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(videofile);
// 获取视频时长
Encoder encoder = new Encoder();
MultimediaInfo multimediaInfo = encoder.getInfo(new File(videofile));
long ls = multimediaInfo.getDuration()/1000;
int hour = (int) (ls/3600);
int minute = (int) (ls%3600)/60;
int second = (int) (ls-hour*3600-minute*60);
log.info("视频时长为:{}时{}分{}秒", hour, minute, second);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
map.put("duration", simpleDateFormat.format(simpleDateFormat.parse(hour+":"+minute+":"+second)));
frameGrabber.start();
int lenght = frameGrabber.getLengthInFrames();
int i = 0;
Frame frame = null;
while (i < lenght) {
// 过滤前5帧,避免出现全黑的图片,依自己情况而定
frame = frameGrabber.grabFrame();
if ((i > 5) && (frame.image != null)) {
break;
}
i++;
}
// 截取的帧图片
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage srcImage = converter.getBufferedImage(frame);
int srcImageWidth = srcImage.getWidth();
int srcImageHeight = srcImage.getHeight();
// 对截图进行等比例缩放(缩略图)
int width = 480;
int height = (int) (((double) width / srcImageWidth) * srcImageHeight);
BufferedImage thumbnailImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
thumbnailImage.getGraphics().drawImage(srcImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);
File picFile = new File(picPath);
ImageIO.write(thumbnailImage, "png", picFile);
map.put("cover", fileName);
frameGrabber.stop();
return map;
}
## 方法二(通过操作linux服务器获取图片和时长)
/**
* 获取指定视频的帧并保存为图片至指定目录
* @param videofile 源视频文件路径
* @param framefile 截取帧的图片存放路径
* @throws Exception
*/
public static Map fetchFrame(Map map, String framefile, String videofile, int type) throws Exception {
String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
//获取视频时长
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
map.put("duration", simpleDateFormat.format(simpleDateFormat.parse( processInfoCmd(videofile, framefile+fileName, 2))));
if (type == 1) {
//截取封面图
processInfoCmd(videofile, framefile+fileName, 1);
map.put("cover", fileName);
}
return map;
}
/**
* 通过linux指令获取封面和时长
*/
public static String processInfoCmd(String videoPath, String coverPath, int type) {
String command = null;
if (type == 1) {//截取图片
command = "ffmpeg -ss 00:00:05 -i " + videoPath + " -f image2 -y " + coverPath;
} else {//获取时长
command = "ffmpeg -i "+videoPath+" -hide_banner 2>&1 | grep 'Duration' | cut -b 13-23";
}
String result = null;
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(command);
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
if (type != 1) {
if (line.contains("Duration:")) {
int start = line.indexOf("Duration:");
int end = line.indexOf(", start:");
result = line.substring(start, end).substring("Duration:".length()).substring(0,9);
System.out.println(result.substring(0,9));
}
}
}
int exitVal = proc.waitFor();
stderr.close();
isr.close();
br.close();
} catch (Throwable t) {
t.printStackTrace();
}
return result;
}
FileSizeUtils工具类来源于:https://www.cnblogs.com/zhukaixin/p/10691305.html