java后端的图片、视频处理工具jar包
1.获取视频信息
2.生成视频封面图
3.异步压缩视频(生成输出文件名后,调用异步压缩视频方法,且同一时间只会处理一个视频,多个请求的视频会进行排队处理)
4.异步压缩视频完成时回调通知
5.图片裁切
6.图片压缩
运行环境需安装FFmpeg和ImageMagick,官网地址如下:
FFmpeg:https://ffmpeg.org/
ImageMagick:https://imagemagick.org/
CentOS安装命令:sudo yum install ImageMagick
FFmpeg解压后需设置/bin目录的环境变量,ImageMagick安装版安装后会自动设置环境变量。
<dependency>
<groupId>vip.gnloypp</groupId>
<artifactId>multimedia-utils</artifactId>
<version>1.0.0</version>
</dependency>
spring:
servlet:
multipart:
# 是否支持 multipart 上传文件
enabled: true
# 最大支持文件大小
max-file-size: 10MB
# 最大支持请求大小
max-request-size: 10MB
# 上传文件的临时目录
location: E:/tomcat-temp
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import vip.gnloypp.easy.multimedia.client.FFmpegClient;
import vip.gnloypp.easy.multimedia.client.ImageMagickClient;
@Component
public class MultimediaUtilsConfig {
/**
* 视频处理工具,因为所有压缩任务需要排队进行,所以FFmpegUtils需要是单例的,FFmpegUtils实例交由spring管理就为单例的
*/
@Bean
public FFmpegClient fFmpegClient() {
return new FFmpegClient("F:/ffmpeg-6.1.1-essentials_build/bin/");
}
/**
* 图片处理工具
*/
@Bean
public ImageMagickClient imageMagickClient() {
return new ImageMagickClient("F:/ImageMagick-7.1.1-26-portable-Q16-x64/");
}
}
FileController
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import vip.gnloypp.easy.multimedia.client.FFmpegClient;
import vip.gnloypp.easy.multimedia.client.ImageMagickClient;
import vip.gnloypp.easy.multimedia.data.attribute.CompressionAttributes;
import vip.gnloypp.easy.multimedia.data.attribute.CropAttributes;
import vip.gnloypp.easy.multimedia.data.attribute.ResizeAttributes;
import vip.gnloypp.easy.multimedia.data.attribute.VideoAttributes;
import vip.gnloypp.easy.multimedia.data.dto.FFmpegInfo;
import vip.gnloypp.easy.multimedia.data.enums.VideoSize;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
@Tag(name = "视频图片处理")
@Log4j2
@Validated
@RestController
@RequestMapping("/open/multimedia")
public class MultimediaController {
private static final String DIRECTORY = "C:/Users/MC/Desktop/multimedia";
@Autowired
private ImageMagickClient imageMagickClient;
@Autowired
private FFmpegClient fFmpegClient;
/**
* 获取视频信息
*/
@PostMapping("/getVideoInfo")
public FFmpegInfo getVideoInfo(@RequestParam MultipartFile file) {
// 生成上传视频的临时文件
File inputFile = multipartFile2File(file, DIRECTORY);
// 调用视频处理工具类
String inputFileName = inputFile.getName();
FFmpegInfo info = fFmpegClient.getInfo(DIRECTORY, inputFileName);
// 删除上传视频的临时文件
inputFile.delete();
return info;
}
/**
* 生成视频封面图
*/
@PostMapping("/createVideoCover")
public String createVideoCover(@RequestParam MultipartFile file) {
// 生成上传视频的临时文件
File inputFile = multipartFile2File(file, DIRECTORY);
// 调用视频处理工具类
String outputFileName = fFmpegClient.createCover(DIRECTORY, inputFile.getName());
// 删除上传视频的临时文件
inputFile.delete();
return outputFileName;
}
/**
* 压缩视频
*/
@PostMapping("/compressionVideo")
public String compressionVideo(@RequestParam MultipartFile file) {
// 生成上传视频的临时文件
File inputFile = multipartFile2File(file, DIRECTORY);
// 调用视频处理工具类
CompressionAttributes compressionAttributes = new CompressionAttributes();
// 设置视频压缩完成时的回调URL
compressionAttributes.setProgressUrl("http://localhost:8081/mysql-manager/open/multimedia/callback?fileId=111111&a=456");
// 设置视频压缩参数
VideoAttributes videoAttributes = new VideoAttributes();
videoAttributes.setMaxDuration(15);
videoAttributes.setMaxFps(20);
videoAttributes.setVideoSize(VideoSize.HD480);
compressionAttributes.setVideoAttributes(videoAttributes);
return fFmpegClient.putCompressionTask(DIRECTORY, inputFile.getName(), compressionAttributes);
}
/**
* 压缩视频完成时的回调
*/
@PostMapping(value = "/callback")
public void callback(@RequestBody byte[] data, @RequestParam("fileId") String fileId, @RequestParam("a") String a) {
// 回调信息
log.info(new String(data, StandardCharsets.UTF_8));
// 回调参数 fileId,根据fileId查询数据库的上传临时文件名和下载临时文件名,进行文件上传和文件删除
log.info(String.format("fileId为%s的文件已压缩完成", fileId));
}
/**
* 图片裁切
*/
@PostMapping("/crop")
public String crop(@RequestParam MultipartFile file) {
// 生成上传图片的临时文件
File inputFile = multipartFile2File(file, DIRECTORY);
// 调用图片处理工具类
// 裁切成600x400的图后,修改分辨率为宽500的图(高度按比例缩小)
CropAttributes cropAttributes = new CropAttributes(600, 400, 200, 300);
ResizeAttributes resizeAttributes = new ResizeAttributes(500, null);
String outputFileName = imageMagickClient.cropAndResize(DIRECTORY, inputFile.getName(), cropAttributes, resizeAttributes);
// 删除上传图片的临时文件
inputFile.delete();
return outputFileName;
}
/**
* 图片分辨率修改
*/
@PostMapping("/resize")
public String resize(@RequestParam MultipartFile file) {
// 生成上传图片的临时文件
File inputFile = multipartFile2File(file, DIRECTORY);
// 调用图片处理工具类
ResizeAttributes resizeAttributes = new ResizeAttributes(800, null);
String outputFileName = imageMagickClient.resize(DIRECTORY, inputFile.getName(), resizeAttributes, ".jpg");
// 删除上传图片的临时文件
inputFile.delete();
return outputFileName;
}
/**
* 将上传的MultipartFile转化为File
*/
private static File multipartFile2File(MultipartFile multipartFile, String directory) {
String suffix = getSuffix(multipartFile.getOriginalFilename());
File tempFile = null;
try {
tempFile = new File(directory + "/" + UUID.randomUUID() + suffix);
multipartFile.transferTo(tempFile);
} catch (IOException e) {
throw new RuntimeException("multipartFile转File失败", e);
}
return tempFile;
}
/**
* 获取文件拓展名
*/
private static String getSuffix(String fileName) {
if (fileName == null) {
throw new RuntimeException("获取文件拓展名失败");
}
int index = fileName.lastIndexOf(".");
if (-1 == index) {
throw new RuntimeException("获取文件拓展名失败");
}
return fileName.substring(index);
}
}
cropAndResize(tempDirectory,inputFileName,cropAttributes,resizeAttributes,outputFileSuffix)
cropAndResize(tempDirectory,inputFileName,cropAttributes,resizeAttributes)
crop(tempDirectory,inputFileName,cropAttributes,outputFileSuffix)
crop(tempDirectory,inputFileName,cropAttributes)
resize(tempDirectory,inputFileName,resizeAttributes,outputFileSuffix)
resize(tempDirectory,inputFileName,resizeAttributes)
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
tempDirectory | String | 是 | 临时文件目录 |
inputFileName | String | 是 | 输入文件名 |
cropAttributes | CropAttributes | 否 | 裁切参数 |
resizeAttributes | ResizeAttributes | 否 | 修改分辨率参数 |
outputFileSuffix | Suffix | 否 | 输出文件格式,未设置则同输入文件格式 |
其中:
CropAttributes
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
width | Integer | 是 | 裁切图片的宽 |
height | Integer | 是 | 裁切图片的高 |
leftOffset | Integer | 是 | 距左边偏移量 |
topOffset | Integer | 是 | 距顶部偏移量 |
ResizeAttributes
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
width | Integer | 否 | 输出图片的宽,只填写宽则高自适应 |
height | Integer | 否 | 输出图片的高,只填写高则宽自适应 |
quality | Integer | 否 | 输出图片的质量,范围0~100,默认100 |
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
outputFileName | String | 是 | 输出文件名 |
getInfo(tempDirectory,inputFileName)
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
tempDirectory | String | 是 | 临时文件目录 |
inputFileName | String | 是 | 输入文件名 |
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
format | FFFormat | 是 | 文件信息 |
videoInfo | VideoInfo | 是 | 视频信息 |
audioInfo | AudioInfo | 是 | 音频信息 |
其中:
FFFormat
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
filename | String | 是 | 文件名全路径名 |
duration | String | 是 | 文件时长 |
size | String | 是 | 文件大小 |
bitRate | String | 是 | 文件比特率 |
VideoInfo
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
codecName | String | 是 | 视频 编码名称 |
codecType | String | 是 | 类型 video |
width | Integer | 是 | 视频 宽度 |
height | Integer | 是 | 视频 高度 |
frameRate | Integer | 是 | 视频 帧率 |
duration | Integer | 是 | 视频 时长 |
bitRate | Integer | 是 | 视频 比特率 |
nbFrames | Integer | 是 | 视频 总帧数 |
AudioInfo
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
codecName | String | 是 | 音频 编码名称 |
codecType | String | 是 | 类型 audio |
duration | Integer | 是 | 音频 时长 |
bitRate | Integer | 是 | 音频 比特率 |
sampleRate | Integer | 是 | 音频 采样率 |
channels | Integer | 是 | 音频 声道数 1:单声道 2:双声道 |
createCover(tempDirectory, inputFileName, outputFileSuffix)
createCover(tempDirectory, inputFileName)
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
tempDirectory | String | 是 | 临时文件目录 |
inputFileName | String | 是 | 输入文件名 |
outputFileSuffix | Suffix | 否 | 输出文件格式,默认jpg |
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
outputFileName | String | 是 | 输出文件名 |
putCompressionTask(tempDirectory, inputFileName, compressionAttributes)
putCompressionTask(tempDirectory, inputFileName, compressionAttributes, outputFileName)
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
tempDirectory | String | 是 | 临时文件目录 |
inputFileName | String | 是 | 输入文件名 |
compressionAttributes | CompressionAttributes | 是 | 压缩参数 |
outputFileName | String | 否 | 输出文件名,默认UUID生成 |
其中:
CompressionAttributes
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
videoAttributes | VideoAttributes | 否 | 视频压缩参数 |
audioAttributes | AudioAttributes | 否 | 音频压缩参数 |
progressUrl | String | 是 | 压缩完成后的回调地址 |
VideoAttributes
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
codec | VideoCodec | 否 | 视频编码(默认libx264,libx265) |
maxFps | Integer | 否 | 最大帧率 |
videoSize | VideoSize | 否 | 视频分辨率(hd480,hd720,hd1080,800x800) |
maxDuration | Integer | 否 | 最大时长 |
maxBitRate | Integer | 否 | 视频最大比特率 |
AudioAttributes
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
maxBitRate | Integer | 否 | 音频最大比特率 |
maxSamplingRate | Integer | 否 | 音频最大采样率 |
参数 | 类型 | 必需 | 注释 |
---|---|---|---|
outputFileName | String | 是 | 输出文件名 |
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。