最近有个上传视频截取缩略图的功能,但是上传视频就得对视频进行描述,还得保存是哪个用户保存的,
所以大体思路就是先让用户上传视频的简介,再上传视频,当获取到视频后,再截取缩略图,最后把图片路径和视频路径存数据库。
先上界面的代码
这是上传视频代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Spring Boot file upload example</h1>
<form method="POST" action="/upload" enctype="multipart/form-data">
<input type="file" name="file" /><br/><br/>
<input type="submit" value="Submit" />
</form>
</body>
</html>
视频上传成功后跳转的界面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<h1>Spring Boot - Upload Status</h1>
<div th:if="${message}">
<h2 th:text="${message}"/>
</div>
</body>
</html>
conterller层代码
package guru.springframework.controllers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import guru.springframework.domain.VideoBean;
import guru.springframework.utils.FetchFrame;
import publicclass.PublicIP;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@Controller
public class UploadController {
static Logger logger = LoggerFactory.getLogger(UploadController.class);
private VideoBean VideoBean =new VideoBean();
//接受视频id和视频简介
@ResponseBody
@RequestMapping(value = "/uploadUser", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public String getUser(@RequestBody VideoBean request) {
this.VideoBean = request;
return "ok";
}
@GetMapping("/upload")
public String index() {
return "upload";
}
//上传视频接口
@PostMapping("/upload") // //new annotation since 4.3
public String singleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {
if (file.isEmpty()) {
redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
return "redirect:uploadStatus";
}
//判断该目录是否存在,不存在创建
File filed = new File(PublicIP.UPLOADED_FOLDER);
if (!filed.exists()) {
filed.mkdirs();
}
try {
// 上传
byte[] bytes = file.getBytes();
//增加时间戳 去重
Long time = System.currentTimeMillis();
String filename = time+file.getOriginalFilename() ;
Path path = Paths.get(PublicIP.UPLOADED_FOLDER + filename);
VideoBean.setAbsolute_Path(PublicIP.UPLOADED_FOLDER + filename);
VideoBean.setVideo_Name(filename);
Files.write(path, bytes);
//截取视频缩略图
FetchFrame FetchFrame = new FetchFrame();
int a=0;
try {
a=FetchFrame.fetchFrame(path.toString(), PublicIP.PATHPHTOT,VideoBean);
logger.info(String.format("视频缩略图 响应=== %s", a));
redirectAttributes.addFlashAttribute("message",
a);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/uploadStatus";
}
@GetMapping("/uploadStatus")
public String uploadStatus() {
return "uploadStatus";
}
}
缩略图方法,截取完了后,入库保存图片和视频的路径,然后跳转界面。
package guru.springframework.utils;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import guru.springframework.dao.VideoDao;
import guru.springframework.domain.VideoBean;
public class FetchFrame {
// videofile 源视频文件路径
// framefile 截取帧的图片存放路径
// 根据视频生成图片
public static int fetchFrame(String videofile, String framefile ,VideoBean VideoBean) throws Exception {
File filed = new File(framefile);
if (!filed.exists()) {
filed.mkdirs();
}
Long time = System.currentTimeMillis();
framefile += String.valueOf(time) + ".jpg";
long start = System.currentTimeMillis();
File targetFile = new File(framefile);
VideoBean.setVideo_thumbnail(framefile);
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile);
ff.start();
int lenght = ff.getLengthInFrames();
int i = 0;
Frame f = null;
while (i < lenght) {
// 过滤前5帧,避免出现全黑的图片,依自己情况而定
f = ff.grabFrame();
if ((i > 5) && (f.image != null)) {
break;
}
i++;
}
IplImage img = f.image;
int owidth = img.width();
int oheight = img.height();
// 对截取的帧进行等比例缩放
int width = 800;
int height = (int) (((double) width / owidth) * oheight);
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
bi.getGraphics().drawImage(f.image.getBufferedImage().getScaledInstance(width, height, Image.SCALE_SMOOTH), 0,
0, null);
ImageIO.write(bi, "jpg", targetFile);
// ff.flush();
ff.stop();
//入库
VideoDao VideoDao = new VideoDao();
int a = VideoDao.inertVideo(VideoBean);
System.out.println(System.currentTimeMillis() - start);
return a;
}
}
maven依赖
<!-- 截取缩略图依赖 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>0.8</version>
</dependency>
控制上传文件大小
applition.properties
# 单个文件的最大值
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB