简介
这章主要是上传视频截帧,公司需求对动态上传需求是OSS上传和截帧(最开始时没有需求,自己用的是FFmpeg 多媒体处理工具截取的),最后因为服务器上没有FFmpeg 工具,导致上传docker报错,失败,最后OSS截取帧数。
一、FFmpeg的使用(需要下载工具)
解压就行。
Spring Boot整合FFmpeg截取帧数
pom.xml
<!-- 视频获取某一帧的图片 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.0.2-1.4.3</version>
</dependency>
Test
@Test
public void getVideoInfo() {
try {
File file = new File("C:\\Users\\lanys\\Desktop\\周报\\21400e3e608358da2d970bd7f69a37f1.mp4");
FileInputStream fileInputStream = new FileInputStream(file);
//放入采集器
FFmpegFrameGrabber fFmpegFrameGrabber = new FFmpegFrameGrabber(fileInputStream);
//启动
fFmpegFrameGrabber.start();
//截取图片
Frame frame = fFmpegFrameGrabber.grabImage();
Java2DFrameConverter java2DFrameConverter = new Java2DFrameConverter();
BufferedImage bufferedImage = java2DFrameConverter.getBufferedImage(frame);
//创建一个ByteArrayOutputStream
ByteArrayOutputStream os = new ByteArrayOutputStream();
//输出 可以不用
ImageIO.write(bufferedImage, "jpg", os);
InputStream input = new ByteArrayInputStream(os.toByteArray());
//InputStream转成MultipartFile
MultipartFile multipartFile =new MockMultipartFile("file", "file.jpg", "text/plain", input);
s5(multipartFile);
fFmpegFrameGrabber.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
@Autowired
private OSS ossClient;
@Autowired
private AliyunConfig aliyunConfig;
public void s5(MultipartFile multipartFile){
//获取图片名称
String originalFilename = multipartFile.getOriginalFilename();;
DateTime dateTime = new DateTime();
String filePath = "uploads/dynamic/pictures/" + dateTime.toString("yyyy") + dateTime.toString("MM") + dateTime.toString("dd") + "/" + System.currentTimeMillis() +
RandomUtils.nextInt(100, 9999) + "." +
StringUtils.substringAfterLast(originalFilename, ".");
System.out.println(filePath);
try {
ossClient.putObject(aliyunConfig.getBucket(), filePath, new
ByteArrayInputStream(multipartFile.getBytes()));
log.info("--------视频上传成功--------");
} catch (Exception e) {
e.printStackTrace();
log.info("上传失败");
}
}
就是这么简单,例子:截取到的图片
二、OSS视频截帧(收费)
价格也不算贵,1000帧数好像2毛钱(自己测试够用)
Spring Boot整合OSS视频截帧
官方OSS接口:https://help.aliyun.com/document_detail/64555.html
整合的话就不说了,一篇文章已经说了,正题
pom.xml
<!-- oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
说明,如果是接口,一般都是用 MultipartFile 接收视频或图片。
getPoster方法(生成一个可视化图片)
/**
* 获取视频截图
*
* @param videosPath
* @return
* @throws IOException
*/
public String getPoster(String videosPath) throws IOException {
// 填写视频文件的完整路径。若视频文件不在Bucket根目录,需携带文件访问路径,例如examplefolder/videotest.mp4。
String objectName = videosPath;
// 填写视频文件所在的Bucket名称。
String bucketName = OssBucketName;
// 使用精确时间模式截取视频5s处的内容,输出为JPG格式的图片,宽度为1080,高度为1800,图片格式:JPG。
String style = "video/snapshot,t_500,f_jpg,w_1080,h_1800,f_jpg";
// 指定过期时间为10分钟。
Date expiration = new Date(System.currentTimeMillis() + 1000 * 60 * 10);
GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
//过期时间必须设置,不然报错提示
req.setExpiration(expiration);
req.setProcess(style);
//获取可视化帧数路径,有过期时间
URL signedUrl = ossClient.generatePresignedUrl(req);
System.out.println(signedUrl);
//获取url的路径,进行真正的OSS存储
String stream = UploadNetworkStream(OssPrefix + signedUrl.getFile());
return stream;
}
uploadNetworkStream(获取上传OSS)
/**
* 上传网络流
* @param url
* @throws IOException
*/
public String UploadNetworkStream(String url) throws IOException {
System.out.println(url);
//随机生成一个图片名
String Path = RandomUtils.nextInt(100, 9999)+".jpg";
DateTime dateTime = new DateTime();
//生成一个真正的图片路径(用于数据库存储)
String picturePath = "uploads/dynamic/videos/" + dateTime.toString("yyyy") + dateTime.toString("MM") + dateTime.toString("dd") + "/" + System.currentTimeMillis() +"/"+Path;
// 上传网络流, url指的是生成可视化的路径,获取流
InputStream inputStream = new URL(url).openStream();
try{
//上传 OssBucketName就是yml中桶的名称,picturePath 上传的路径,inputStream流
ossClient.putObject(OssBucketName, picturePath, inputStream);
//成功返回路径
return picturePath;
}catch (Exception e){
log.info("-------图片复制失败-------");
e.printStackTrace();
}
return null;
}
好了,例子:例子图片
总结
好了结束,里面有个坑,picturePath路径前面不用加斜杠,不然会网络错误之类的话和如果是接口,接口是开放,创建用户或动态都需要用,不要最后加个ossClient.shutdown(),之后都懂了。