0


SpringBoot 集成 FFmpeg 解析音视频

文章目录

1 摘要

FFmpeg 是最常用的跨平台的音频、视频处理软件,但是其通过命令行的方式进行操作对于普通用户而言上手难度大,同时 FFmpeg 只是函数库,对于不同的编程语言,需要自行适配API接口,以便于操作文件。本文介绍SpringBoot 集成 FFmpeg 实现对音视频文件的解析。

FFmpeg 官网: https://ffmpeg.org

FFmpeg Java 平台常用适配仓库:

JavaCV : https://github.com/bytedeco/javacv

JavaCV 是一个集成第三方函数库的平台,包括 OpenCV、FFmpeg 等知名函数库,提供统一的 API 操作,应用广泛。在不考虑应用程序体积大小的情况下推荐使用 JavaCV 作为集成方案。

JAVE2: https://github.com/a-schild/jave2

JAVE2 是将 FFmpeg 进行封装,并提供 Java API 以供用户操作音视频文件的依赖库。用户可以根据软件运行的操作系统来自由选择所需平台的依赖。

本文是基于 JAVE2 依赖来实现解析音视频文件的功能。

2 核心 Maven 依赖

  1. demo-ffmpeg-media/pom.xml
  1. <!-- ffmpeg 音视频处理 --><dependency><groupId>ws.schild</groupId><artifactId>jave-core</artifactId><version>${schild-ffmpeg.version}</version></dependency><dependency><groupId>ws.schild</groupId><artifactId>jave-nativebin-win64</artifactId><version>${schild-ffmpeg.version}</version></dependency><dependency><groupId>ws.schild</groupId><artifactId>jave-nativebin-linux64</artifactId><version>${schild-ffmpeg.version}</version></dependency><dependency><groupId>ws.schild</groupId><artifactId>jave-nativebin-osx64</artifactId><version>${schild-ffmpeg.version}</version></dependency><dependency><groupId>ws.schild</groupId><artifactId>jave-nativebin-osxm1</artifactId><version>${schild-ffmpeg.version}</version></dependency>

其中

  1. schild-ffmpeg

版本为:

  1. <schild-ffmpeg.version>3.5.0</schild-ffmpeg.version>

这里分别引入了 Windows、Linux、macOS 系统的依赖,可根据软件运行环境进行删减。

3 核心代码

3.1 FFmpeg 解析音视频工具类

  1. demo-ffmpeg-media/src/main/java/com/ljq/demo/springboot/ffmpeg/common/util/FFmpegMediaUtil.java
  1. packagecom.ljq.demo.springboot.ffmpeg.common.util;importcom.ljq.demo.springboot.ffmpeg.model.response.AudioInfoResponse;importcom.ljq.demo.springboot.ffmpeg.model.response.VideoInfoResponse;importlombok.extern.slf4j.Slf4j;importorg.springframework.util.DigestUtils;importws.schild.jave.MultimediaObject;importws.schild.jave.info.AudioInfo;importws.schild.jave.info.MultimediaInfo;importws.schild.jave.info.VideoInfo;importjava.io.File;importjava.nio.file.Files;importjava.util.Objects;/**
  2. * @Description: FFmpeg 音视频工具类
  3. * @Author: junqiang.lu
  4. * @Date: 2024/5/10
  5. */@Slf4jpublicclassFFmpegMediaUtil{/**
  6. * 获取视频信息
  7. *
  8. * @param videoPath 视频路径
  9. * @return 视频信息
  10. */publicstaticVideoInfoResponsegetVideoInfo(String videoPath){VideoInfoResponse response =null;try{// 解析文件File videoFile =newFile(videoPath);MultimediaObject multimediaObject =newMultimediaObject(videoFile);MultimediaInfo multimediaInfo = multimediaObject.getInfo();VideoInfo videoInfo = multimediaInfo.getVideo();// 判断是否为视频if(Objects.isNull(videoInfo)|| videoInfo.getBitRate()<0){returnnull;}
  11. response =newVideoInfoResponse();
  12. response.setFormat(multimediaInfo.getFormat()).setDuration(multimediaInfo.getDuration()/1000).setSize(videoFile.length()).setMd5(DigestUtils.md5DigestAsHex(Files.readAllBytes(videoFile.toPath())));
  13. response.setBitRate(videoInfo.getBitRate()).setFrameRate(videoInfo.getFrameRate()).setWidth(videoInfo.getSize().getWidth()).setHeight(videoInfo.getSize().getHeight());return response;}catch(Exception e){
  14. log.warn("Error processing video file", e);}return response;}/**
  15. * 获取音频信息
  16. *
  17. * @param audioPath 音频路径
  18. * @return 音频信息
  19. */publicstaticAudioInfoResponsegetAudioInfo(String audioPath){AudioInfoResponse response =null;try{// 解析文件File videoFile =newFile(audioPath);MultimediaObject multimediaObject =newMultimediaObject(videoFile);MultimediaInfo multimediaInfo = multimediaObject.getInfo();AudioInfo audioInfo = multimediaInfo.getAudio();// 判断是否为音频if(Objects.isNull(audioInfo)||Objects.nonNull(multimediaInfo.getVideo())){returnnull;}
  20. response =newAudioInfoResponse();
  21. response.setFormat(multimediaInfo.getFormat()).setDuration(multimediaInfo.getDuration()/1000).setSize(videoFile.length()).setMd5(DigestUtils.md5DigestAsHex(Files.readAllBytes(videoFile.toPath())));
  22. response.setSamplingRate(audioInfo.getSamplingRate()).setBitRate(audioInfo.getBitRate()).setChannels(audioInfo.getChannels()).setBitDepth(audioInfo.getBitDepth());return response;}catch(Exception e){
  23. log.warn("Error processing audio file", e);}return response;}}

3.2 音视频文件信息参数

音视频文件公共信息参数

  1. demo-ffmpeg-media/src/main/java/com/ljq/demo/springboot/ffmpeg/model/response/MediaInfoResponse.java
  1. packagecom.ljq.demo.springboot.ffmpeg.model.response;importlombok.Data;importlombok.experimental.Accessors;importjava.io.Serializable;/**
  2. * @Description: 多媒体信息
  3. * @Author: junqiang.lu
  4. * @Date: 2024/5/10
  5. */@Data@Accessors(chain =true)publicclassMediaInfoResponseimplementsSerializable{privatestaticfinallong serialVersionUID =-326368230008457941L;/**
  6. * 文件格式
  7. */privateString format;/**
  8. * 时长,单位:秒
  9. */privateLong duration;/**
  10. * 文件大小,单位:字节数
  11. */privateLong size;/**
  12. * 文件md5值
  13. */privateString md5;}

视频文件参数信息对象

  1. demo-ffmpeg-media/src/main/java/com/ljq/demo/springboot/ffmpeg/model/response/VideoInfoResponse.java
  1. packagecom.ljq.demo.springboot.ffmpeg.model.response;importlombok.Data;importlombok.ToString;importlombok.experimental.Accessors;/**
  2. * @Description: 视频文件信息返回对象
  3. * @Author: junqiang.lu
  4. * @Date: 2024/5/10
  5. */@Data@Accessors(chain =true)@ToString(callSuper =true)publicclassVideoInfoResponseextendsMediaInfoResponse{privatestaticfinallong serialVersionUID =-9016123624628502571L;/**
  6. * 比特率,单位: bps
  7. */privateInteger bitRate;/**
  8. * 帧率,单位: FPS
  9. */privateFloat frameRate;/**
  10. * 宽度,单位: px
  11. */privateInteger width;/**
  12. * 高度,单位: px
  13. */privateInteger height;}

音频文件参数信息对象

  1. demo-ffmpeg-media/src/main/java/com/ljq/demo/springboot/ffmpeg/model/response/AudioInfoResponse.java
  1. packagecom.ljq.demo.springboot.ffmpeg.model.response;importlombok.Data;importlombok.ToString;importlombok.experimental.Accessors;/**
  2. * @Description: 音频文件信息返回对象
  3. * @Author: junqiang.lu
  4. * @Date: 2024/5/10
  5. */@Data@Accessors(chain =true)@ToString(callSuper =true)publicclassAudioInfoResponseextendsMediaInfoResponse{privatestaticfinallong serialVersionUID =3573655613715240188L;/**
  6. * 采样率
  7. */privateInteger samplingRate;/**
  8. * 音频通道数量,1-单声道,2-立体声
  9. */privateInteger channels;/**
  10. * 比特率,单位: bps
  11. */privateInteger bitRate;/**
  12. * 位深度
  13. */privateString bitDepth;}

3.3 音视频文件上传Controller

  1. demo-ffmpeg-media/src/main/java/com/ljq/demo/springboot/ffmpeg/controller/FFmpegMediaController.java
  1. packagecom.ljq.demo.springboot.ffmpeg.controller;importcom.ljq.demo.springboot.ffmpeg.common.config.UploadConfig;importcom.ljq.demo.springboot.ffmpeg.common.util.FFmpegMediaUtil;importcom.ljq.demo.springboot.ffmpeg.model.response.AudioInfoResponse;importcom.ljq.demo.springboot.ffmpeg.model.response.VideoInfoResponse;importlombok.extern.slf4j.Slf4j;importorg.springframework.http.MediaType;importorg.springframework.http.ResponseEntity;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importorg.springframework.web.multipart.MultipartFile;importjavax.annotation.Resource;importjava.io.File;importjava.io.IOException;/**
  2. * @Description: FFmpeg 媒体文件处理控制层
  3. * @Author: junqiang.lu
  4. * @Date: 2024/5/10
  5. */@Slf4j@RestController@RequestMapping(value ="/api/ffmpeg/media")publicclassFFmpegMediaController{@ResourceprivateUploadConfig uploadConfig;/**
  6. * 视频上传
  7. *
  8. * @param file
  9. * @return
  10. * @throws IOException
  11. */@PostMapping(value ="/upload/video", produces ={MediaType.APPLICATION_JSON_VALUE})publicResponseEntity<VideoInfoResponse>uploadVideo(MultipartFile file)throwsIOException{// 文件上传保存String videoFilePath = uploadConfig.getUploadPath()+File.separator + file.getOriginalFilename();
  12. log.info("videoFilePath: {}", videoFilePath);File videoFile =newFile(videoFilePath);if(!videoFile.getParentFile().exists()){
  13. videoFile.getParentFile().mkdirs();}
  14. file.transferTo(videoFile);// 获取视频信息VideoInfoResponse videoInfoResponse =FFmpegMediaUtil.getVideoInfo(videoFilePath);returnResponseEntity.ok(videoInfoResponse);}/**
  15. * 音频上传
  16. *
  17. * @param file
  18. * @return
  19. * @throws IOException
  20. */@PostMapping(value ="/upload/audio", produces ={MediaType.APPLICATION_JSON_VALUE})publicResponseEntity<AudioInfoResponse>uploadAudio(MultipartFile file)throwsIOException{// 文件上传保存String audioFilePath = uploadConfig.getUploadPath()+File.separator + file.getOriginalFilename();
  21. log.info("audioFilePath: {}", audioFilePath);File audioFile =newFile(audioFilePath);if(!audioFile.getParentFile().exists()){
  22. audioFile.getParentFile().mkdirs();}
  23. file.transferTo(audioFile);// 获取音频信息AudioInfoResponse audioInfoResponse =FFmpegMediaUtil.getAudioInfo(audioFilePath);returnResponseEntity.ok(audioInfoResponse);}}

3.4 application 配置文件

  1. # configserver:port:9250# springspring:application:name: demo-ffmpeg-media
  2. servlet:multipart:max-file-size: 1000MB
  3. max-request-size: 1000MB
  4. # uploadConfigupload:path: D:\\upload # linux/macOS 路径 /opt/upload

4 测试数据

示例文件下载: https://zh.getsamplefiles.com

4.1 视频文件解析

测试文件:

  1. https://zh.getsamplefiles.com/download/mp4/sample-4.mp4

测试结果:

  1. {"format":"mov","duration":30,"size":7588608,"md5":"d7b5155ee54ee9c7dcd8cbb5395823dc","bitRate":2015000,"frameRate":25.0,"width":1280,"height":720}

4.2 音频文件解析

测试文件:

  1. https://zh.getsamplefiles.com/download/mp3/sample-5.mp3

测试结果:

  1. {"format":"mp3","duration":45,"size":1830660,"md5":"843e2916b1c552fb5e8ee3d83faddb8c","samplingRate":44100,"channels":2,"bitRate":320000,"bitDepth":"fltp"}

5 注意事项

5.1 文件必须在本地

在实际项目中,一般会将文件保存到专门的文件服务器,但是 FFmpeg 解析文件必须是本地文件,因此在上传至文件服务器之前需要将文件在本地服务器做中转,解析完毕后再上传,然后删除本地文件。

6 推荐参考文档

SpringBoot集成ffmpeg实现视频转码播放

Convert video to Another Format in Spring Boot(Java-based apps)

springboot如何获取视频文件的视频时间长度

java 视频识别 java 视频转码

JAVE2 官方 Github

JAVE2 官方文档 Getting informations about a multimedia file

javacv-ffmpeg(八)视频文件信息获取

7 Github 源码

Gtihub 源码地址 : https://github.com/Flying9001/springBootDemo/tree/master/demo-ffmpeg-media

个人公众号:404Code,分享半个互联网人的技术与思考,感兴趣的可以关注.
404Code


本文转载自: https://blog.csdn.net/Mrqiang9001/article/details/138708327
版权归原作者 Flying9001 所有, 如有侵权,请联系我们删除。

“SpringBoot 集成 FFmpeg 解析音视频”的评论:

还没有评论