# multimedia-utils **Repository Path**: gnliscream/multimedia-utils ## Basic Information - **Project Name**: multimedia-utils - **Description**: java后端的图片、视频处理工具jar包 1.获取视频信息 2.生成视频封面图 3.异步压缩视频(生成输出文件名后,调用异步压缩视频方法,且同一时间只会处理一个视频,多个请求的视频会进行排队处理) 4.异步压缩视频完成时回调通知 5.图片裁切 6.图片压缩 - **Primary Language**: Java - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 42 - **Forks**: 24 - **Created**: 2020-10-30 - **Last Updated**: 2025-04-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # multimedia-utils ## 介绍 java后端的图片、视频处理工具jar包 1.获取视频信息 2.生成视频封面图 3.异步压缩视频(生成输出文件名后,调用异步压缩视频方法,且同一时间只会处理一个视频,多个请求的视频会进行排队处理) 4.异步压缩视频完成时回调通知 5.图片裁切 6.图片压缩 ## 示例小程序码 ![](https://images.gnloypp.vip/jpg/f977232b734e4f8496e9504152584e12.jpg) ## 客户端安装 运行环境需安装FFmpeg和ImageMagick,官网地址如下: FFmpeg:[https://ffmpeg.org/](https://ffmpeg.org/) ImageMagick:[https://imagemagick.org/](https://imagemagick.org/) ``` CentOS安装命令:sudo yum install ImageMagick ``` FFmpeg解压后需设置/bin目录的环境变量,ImageMagick安装版安装后会自动设置环境变量。 ## 引入依赖 ```xml vip.gnloypp multimedia-utils 1.0.0 ``` ## 配置 ### yml 配置上传文件的临时路径 ```yml spring: servlet: multipart: # 是否支持 multipart 上传文件 enabled: true # 最大支持文件大小 max-file-size: 10MB # 最大支持请求大小 max-request-size: 10MB # 上传文件的临时目录 location: E:/tomcat-temp ``` ### 注入 视频处理类FFmpegUtils 以及 图片处理类 ImageMagickUtils ```java 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 ```java 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); } } ``` ## 文档 ### 图片工具ImageMagickUtils #### 方法 ##### 1.图片裁切后修改分辨率并指定输出文件格式 cropAndResize(tempDirectory,inputFileName,cropAttributes,resizeAttributes,outputFileSuffix) ##### 2.图片裁切后修改分辨率 cropAndResize(tempDirectory,inputFileName,cropAttributes,resizeAttributes) ##### 3.图片裁切并指定输出文件格式 crop(tempDirectory,inputFileName,cropAttributes,outputFileSuffix) ##### 4.图片裁切 crop(tempDirectory,inputFileName,cropAttributes) ##### 5.图片修改分辨率并指定输出文件格式 resize(tempDirectory,inputFileName,resizeAttributes,outputFileSuffix) ##### 6.图片修改分辨率 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|是|输出文件名| ### 视频工具FFmpegUtils #### 方法 ##### 1.获取视频信息 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:双声道| ##### 2.截取视频封面 createCover(tempDirectory, inputFileName, outputFileSuffix) createCover(tempDirectory, inputFileName) ###### 输入参数 |参数|类型|必需|注释| |-|-|-|-| |tempDirectory|String|是|临时文件目录| |inputFileName|String|是|输入文件名| |outputFileSuffix|Suffix|否|输出文件格式,默认jpg| ###### 输出参数 |参数|类型|必需|注释| |-|-|-|-| |outputFileName|String|是|输出文件名| ##### 3.视频压缩 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|是|输出文件名|