如何在Spring Boot中集成FFmpeg实现媒体缩放与上传进度展示?
简便实现Spring Boot集成FFmpeg做媒体缩放方案
嘿,刚好做过类似的需求,给你分享个超省心的集成方案,不用自己折腾原生命令拼接,用现成的Java封装库就能快速搞定:
第一步:搞定FFmpeg环境
首先得确保你的Spring Boot服务器上装好了FFmpeg:
- Linux服务器直接用包管理器装,比如
apt install ffmpeg(Debian/Ubuntu)或者yum install ffmpeg(CentOS) - Windows的话去FFmpeg官网下载静态编译包,解压后把bin目录加到系统环境变量里
验证下:终端输入ffmpeg -version,能正常输出版本信息就没问题。
第二步:Spring Boot引入FFmpeg依赖
用Maven的话,直接在pom.xml里加这个依赖(这是目前最流行的FFmpeg Java封装库,帮你封装了命令调用逻辑,不用自己拼字符串):
<dependency> <groupId>net.bramp.ffmpeg</groupId> <artifactId>ffmpeg</artifactId> <version>0.7.0</version> </dependency>
第三步:编写媒体缩放服务类
创建一个MediaProcessingService,把图片和视频的缩放逻辑封装起来,代码示例:
import net.bramp.ffmpeg.FFmpeg; import net.bramp.ffmpeg.FFmpegExecutor; import net.bramp.ffmpeg.builder.FFmpegBuilder; import net.bramp.ffmpeg.progress.Progress; import net.bramp.ffmpeg.progress.ProgressListener; import org.springframework.stereotype.Service; import java.io.File; import java.io.IOException; @Service public class MediaProcessingService { private final FFmpeg ffmpeg; public MediaProcessingService() throws IOException { // 自动从环境变量查找FFmpeg路径,也可以手动指定,比如new FFmpeg("/usr/bin/ffmpeg") this.ffmpeg = new FFmpeg(); } // 图片缩放:支持JPG/PNG等主流格式 public void scaleImage(File inputFile, File outputFile, int targetWidth, int targetHeight) throws IOException { FFmpegBuilder builder = new FFmpegBuilder() .setInput(inputFile.getAbsolutePath()) .overrideOutputFiles(true) .addOutput(outputFile.getAbsolutePath()) .setVideoFilter("scale=" + targetWidth + ":" + targetHeight) .setFormat("image2") .done(); FFmpegExecutor executor = new FFmpegExecutor(ffmpeg); executor.createJob(builder).run(); } // 视频缩放:保持宽高比,指定宽度后高度自动计算 public void scaleVideo(File inputFile, File outputFile, int targetWidth, ProgressListener listener) throws IOException { FFmpegBuilder builder = new FFmpegBuilder() .setInput(inputFile.getAbsolutePath()) .overrideOutputFiles(true) .addOutput(outputFile.getAbsolutePath()) // 用-2表示自动计算高度,保持原比例 .setVideoFilter("scale=" + targetWidth + ":-2") // 保持视频编码和质量,避免过度压缩 .setVideoCodec("libx264") .setAudioCodec("aac") .done(); FFmpegExecutor executor = new FFmpegExecutor(ffmpeg); executor.createJob(builder, listener).run(); } }
第四步:对接上传接口+处理进度通知
你需要在上传接口里接收前端的媒体文件,调用上面的缩放服务,同时给前端返回进度:
- 上传阶段的进度:React Native上传时可以用
fetch或者第三方上传库(比如react-native-image-picker)自带的进度回调,直接在前端显示百分比就行,示例代码:
const uploadMedia = async (fileUri, mediaType) => { const formData = new FormData(); formData.append('media', { uri: fileUri, name: `media.${mediaType.split('/')[1]}`, type: mediaType }); const response = await fetch('http://your-server/api/media/upload', { method: 'POST', body: formData, onUploadProgress: (progressEvent) => { const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total); // 更新UI显示上传进度 console.log(`上传进度:${percentCompleted}%`); } }); };
- 服务器处理媒体的进度:如果需要展示后端处理缩放的进度,可以用SSE(Server-Sent Events)或者WebSocket实时推送。用上面的
scaleVideo方法时,传入进度监听器就能拿到实时进度:
// 在上传接口中调用 ProgressListener progressListener = progress -> { double percent = progress.progress * 100; // 这里可以把进度推送给前端,比如存入Redis让前端轮询,或者用SSE直接推送 System.out.println(`处理进度:${String.format("%.2f%%", percent)}`); }; mediaProcessingService.scaleVideo(inputFile, outputFile, 720, progressListener);
一些实用注意事项
- 给服务器留足磁盘空间,存储原始文件和处理后的文件
- 处理大视频时,建议用Spring的
@Async异步执行,避免接口阻塞 - 加一层文件格式校验,只允许上传图片和视频格式
内容的提问来源于stack exchange,提问作者Parkash Sbd
相关产品推荐
相关产品推荐

