spring boot 整合ffmpeg(java与ffmpeg整合)

java中使用ffmpeg(spring boot)

  • ffmpeg命令百度搜索即可,利用 ffmpeg.addArgumen添加进去即可执行,参考getTargetThumbnail或addSubtitle方法即可。
  • windows版本的整合,其依赖的jar包中有ffmpeg-amd64.exe可执行文件,其他系统原理类似。
  • ffmpeg执行较为耗时,IO密集型操作,cpu负载高,一般配合线程池异步使用,服务端操作音视频,需自行考虑成本。
  • Ffmpeg 通过url直接转码比较方便,但是可能会带来丢帧问题,建议先下载到本地,再转码

pom文件

    <dependency>
      <groupId>ws.schild</groupId>
      <artifactId>jave-all-deps</artifactId>
      <version>3.0.1</version>
      <exclusions>
        <!--  排除windows 32位系统      -->
        <exclusion>
          <groupId>ws.schild</groupId>
          <artifactId>jave-nativebin-win32</artifactId>
        </exclusion>
        <!--  排除linux 32位系统      -->
        <exclusion>
          <groupId>ws.schild</groupId>
          <artifactId>jave-nativebin-linux32</artifactId>
        </exclusion>
        <!-- 排除Mac系统-->
        <exclusion>
          <groupId>ws.schild</groupId>
          <artifactId>jave-nativebin-osx64</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

FfmpegUtil.java

package ruibo.ffmpeg;

import ws.schild.jave.Encoder;
import ws.schild.jave.EncoderException;
import ws.schild.jave.MultimediaObject;
import ws.schild.jave.encode.AudioAttributes;
import ws.schild.jave.encode.EncodingAttributes;
import ws.schild.jave.encode.VideoAttributes;
import ws.schild.jave.info.MultimediaInfo;
import ws.schild.jave.process.ProcessWrapper;
import ws.schild.jave.process.ffmpeg.DefaultFFMPEGLocator;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

/**
 * @author ruibo.duan, <1573434995@qq.com>
 * @since 2021/7/22
 */
public class FfmpegUtil {

  /**
   * 通过本地路径获取多媒体文件信息(宽,高,时长,编码等)
   *
   * @param localPath 本地路径
   * @return MultimediaInfo 对象,包含 (宽,高,时长,编码等)
   * @throws EncoderException
   */
  public static MultimediaInfo getMultimediaInfo(String localPath) {
    MultimediaInfo multimediaInfo = null;
    try {
      multimediaInfo = new MultimediaObject(new File(localPath)).getInfo();
    } catch (EncoderException e) {
      System.out.println("获取多媒体文件信息异常");
      e.printStackTrace();
    }
    return multimediaInfo;
  }

  /**
   * 通过URL获取多媒体文件信息
   *
   * @param url 网络url
   * @return MultimediaInfo 对象,包含 (宽,高,时长,编码等)
   * @throws EncoderException
   */
  public static MultimediaInfo getMultimediaInfoFromUrl(String url) {
    MultimediaInfo multimediaInfo = null;
    try {
      multimediaInfo = new MultimediaObject(new URL(url)).getInfo();
    } catch (Exception e) {
      System.out.println("获取多媒体文件信息异常");
      e.printStackTrace();
    }
    return multimediaInfo;
  }

  private static final int SAMPLING_RATE = 16000;
  private static final int SINGLE_CHANNEL = 1;

  /**
   * 音频格式化为wav,并设置单声道和采样率
   *
   * @param url 需要转格式的音频
   * @param targetPath 格式化后要保存的目标路径
   */
  public static boolean formatAudio(String url, String targetPath) {
    File target = new File(targetPath);
    MultimediaObject multimediaObject;
    try {
      // 若是本地文件: multimediaObject = new MultimediaObject(new File("你的本地路径"));
      multimediaObject = new MultimediaObject(new URL(url));
      // 音频参数
      // TODO: 2023/1/31 此处按需自定义音频参数
      AudioAttributes audio = new AudioAttributes();
      // 采样率
      audio.setSamplingRate(SAMPLING_RATE);
      // 单声道
      audio.setChannels(SINGLE_CHANNEL);
      Encoder encoder = new Encoder();
      EncodingAttributes attrs = new EncodingAttributes();
      // 输出格式
      attrs.setOutputFormat("wav");
      attrs.setAudioAttributes(audio);
      encoder.encode(multimediaObject, target, attrs);
      return true;
    } catch (Exception e) {
      System.out.println("格式化音频异常");
      return false;
    }
  }

  /**
   * 视频格式化为mp4
   *
   * @param url
   * @param targetPath
   * @return
   */
  public static boolean formatToMp4(String url, String targetPath) {
    File target = new File(targetPath);
    MultimediaObject multimediaObject;
    try {
      // 若是本地文件: multimediaObject = new MultimediaObject(new File("你的本地路径"));
      multimediaObject = new MultimediaObject(new URL(url));
      EncodingAttributes attributes = new EncodingAttributes();
      // 设置视频的音频参数
      AudioAttributes audioAttributes = new AudioAttributes();
      attributes.setAudioAttributes(audioAttributes);
      // 设置视频的视频参数
      VideoAttributes videoAttributes = new VideoAttributes();
      // 设置帧率
      videoAttributes.setFrameRate(25);
      attributes.setVideoAttributes(videoAttributes);
      // 设置输出格式
      attributes.setOutputFormat("mp4");
      Encoder encoder = new Encoder();
      encoder.encode(multimediaObject, target, attributes);
      return true;
    } catch (Exception e) {
      System.out.println("格式化视频异常");
      e.printStackTrace();
      return false;
    }
  }

  /**
   * 获取视频缩略图 获取视频第0秒的第一帧图片
   *
   * <p>执行的ffmpeg 命令为: ffmpeg -i 你的视频文件路径 -ss 指定的秒数 生成文件的全路径地址
   *
   * @param localPath 本地路径
   * @param targetPath 存放的目标路径
   * @return
   */
  public static boolean getTargetThumbnail(String localPath, String targetPath) {
    // FIXME: 2023/1/31  该方法基本可作为执行ffmpeg命令的模板方法,之后的几个方法与此类似
    try {
      ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor();
      ffmpeg.addArgument("-i");
      ffmpeg.addArgument(localPath);
      ffmpeg.addArgument("-ss");
      // 此处可自定义视频的秒数
      ffmpeg.addArgument("0");
      ffmpeg.addArgument(targetPath);
      ffmpeg.execute();
      try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
        blockFfmpeg(br);
      }
    } catch (IOException e) {
      System.out.println("获取视频缩略图失败");
      e.printStackTrace();
      return false;
    }
    return true;
  }

  /**
   * 等待命令执行成功,退出
   *
   * @param br
   * @throws IOException
   */
  private static void blockFfmpeg(BufferedReader br) throws IOException {
    String line;
    // 该方法阻塞线程,直至合成成功
    while ((line = br.readLine()) != null) {
      doNothing(line);
    }
  }

  /**
   * 打印日志
   *
   * @param line
   */
  private static void doNothing(String line) {
    // FIXME: 2023/1/31 正式使用时注释掉此行,仅用于观察日志
    System.out.println(line);
  }

  /**
   * 视频增加字幕
   *
   * @param originVideoPath 原视频地址
   * @param targetVideoPath 目标视频地址
   * @param srtPath 固定格式的srt文件地址或存储位置,字母文件名: xxx.srt,样例看博客
   * @return
   * @throws Exception
   */
  public static boolean addSubtitle(
      String originVideoPath, String srtPath, String targetVideoPath) {
    try {
      ProcessWrapper ffmpeg = new DefaultFFMPEGLocator().createExecutor();
      ffmpeg.addArgument("-i");
      ffmpeg.addArgument(originVideoPath);
      ffmpeg.addArgument("-i");
      ffmpeg.addArgument(srtPath);
      ffmpeg.addArgument("-c");
      ffmpeg.addArgument("copy");
      ffmpeg.addArgument(targetVideoPath);
      ffmpeg.execute();
      try (BufferedReader br = new BufferedReader(new InputStreamReader(ffmpeg.getErrorStream()))) {
        blockFfmpeg(br);
      }
    } catch (IOException e) {
      System.out.println("字幕增加失败");
      e.printStackTrace();
    }
    return true;
  }

  /**
   * 常用命令
   *
   * @return
   */
  public static void cmd() {
    // FIXME: 2023/1/31  还有很多类似命令 不再一一列举 ,附上命令,具体写法参考 getTargetThumbnail或addSubtitle方法
    // FIXME: 2023/1/31 ffmpeg命令网上搜索即可

    // 剪切视频
    // ffmpeg -ss 00:00:00 -t 00:00:30 -i test.mp4 -vcodec copy -acodec copy output.mp4
    // * -ss 指定从什么时间开始
    // * -t 指定需要截取多长时间
    // * -i 指定输入文件

    // ffmpeg -ss 10 -t 15 -accurate_seek -i test.mp4 -codec copy cut.mp4
    // ffmpeg -ss 10 -t 15 -accurate_seek -i test.mp4 -codec copy -avoid_negative_ts 1 cut.mp4

    // 拼接MP4
    // 第一种方法:
    // ffmpeg -i "concat:1.mp4|2.mp4|3.mp4" -codec copy out_mp4.mp4
    // 1.mp4 第一个视频文件的全路径
    // 2.mp4 第二个视频文件的全路径

    // 提取视频中的音频
    // ffmpeg -i input.mp4 -acodec copy -vn output.mp3
    // -vn: 去掉视频;-acodec: 音频选项, 一般后面加copy表示拷贝

    // 音视频合成
    // ffmpeg -y –i input.mp4 –i input.mp3 –vcodec copy –acodec copy output.mp4
    // -y 覆盖输出文件

    // 剪切视频
    //  ffmpeg -ss 0:1:30 -t 0:0:20 -i input.mp4 -vcodec copy -acodec copy output.mp4
    // -ss 开始时间; -t 持续时间

    // 视频截图
    //  ffmpeg –i test.mp4 –f image2 -t 0.001 -s 320x240 image-%3d.jpg
    // -s 设置分辨率; -f 强迫采用格式fmt;

    // 视频分解为图片
    //   ffmpeg –i test.mp4 –r 1 –f image2 image-%3d.jpg
    // -r 指定截屏频率

    // 将图片合成视频
    //  ffmpeg -f image2 -i image%d.jpg output.mp4

    // 视频拼接
    //  ffmpeg -f concat -i filelist.txt -c copy output.mp4

    // 将视频转为gif
    //    ffmpeg -i input.mp4 -ss 0:0:30 -t 10 -s 320x240 -pix_fmt rgb24 output.gif
    // -pix_fmt 指定编码

    // 视频添加水印
    //  ffmpeg -i input.mp4 -i logo.jpg
    // -filter_complex[0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10[out] -map [out] -map
    // 0:a -codec:a copy output.mp4
    // main_w-overlay_w-10 视频的宽度-水印的宽度-水印边距;

  }
}

字幕文件 ***.srt

1
00:00:00,000 --> 00:00:01,989
篮网也是哈登的选择

2
00:00:01,989 --> 00:00:04,658
他为了能去布鲁克林颇费心思

  • 16
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
### 回答1: Spring Boot可以很方便地与FFmpeg进行集成,以实现音视频处理的功能。以下是整合步骤: 1. 引入FFmpeg依赖 在pom.xml文件中添加FFmpeg的依赖: ``` <dependency> <groupId>com.github.kokorin</groupId> <artifactId>ffmpeg-java</artifactId> <version>1.2.</version> </dependency> ``` 2. 编写FFmpeg工具类 编写一个FFmpeg工具类,用于调用FFmpeg命令进行音视频处理。例如: ``` public class FFmpegUtil { public static void convert(String inputPath, String outputPath) throws Exception { FFmpeg ffmpeg = new FFmpeg("/usr/local/bin/ffmpeg"); FFprobe ffprobe = new FFprobe("/usr/local/bin/ffprobe"); FFmpegBuilder builder = new FFmpegBuilder() .setInput(inputPath) .overrideOutputFiles(true) .addOutput(outputPath) .setFormat("mp4") .setVideoCodec("libx264") .setAudioCodec("aac") .setStrict(FFmpegBuilder.Strict.EXPERIMENTAL) .done(); FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe); executor.createJob(builder).run(); } } ``` 3. 调用FFmpeg工具类 在Spring Boot应用中调用FFmpeg工具类,例如: ``` @RestController public class VideoController { @PostMapping("/convert") public void convert(@RequestParam("input") String inputPath, @RequestParam("output") String outputPath) throws Exception { FFmpegUtil.convert(inputPath, outputPath); } } ``` 以上就是Spring Boot整合FFmpeg的基本步骤。当然,具体的实现还需要根据实际需求进行调整。 ### 回答2: Spring Boot是一种快速应用程序开发的框架,可以轻松地集成其他应用程序。ffmpeg是用于视频和音频处理的开源软件库。这两种技术可以非常顺利地整合在一起。 Spring Boot提供了一些集成FFmpeg的库,使得开发者能够轻松地将它们集成到应用程序中。这些库不仅提供了轻松配置FFmpeg的方法,还可实现视频和音频的处理和转码。这使开发者不用太多的时间和精力去研究与学习FFmpeg本身的使用。 整合Spring Bootffmpeg主要有以下步骤: 1. 在pom.xml中添加依赖库,以确保应用程序可以使用FFmpeg库。 2. 在应用程序中定义FFmpeg命令,以启动FFmpeg处理。可以在应用程序中定义一个Java类,将FFmpeg命令转化成Java代码,这样就可以集成到Spring Boot应用程序中了。 3. 在Spring Boot应用程序中,使用Spring MVC的REST API接口来处理视频或音频文件的请求。 4. 配置FFmpeg参数,以便将视频或音频文件转换成不同的格式或大小。 总体来说,整合Spring BootFFmpeg可以实现对视频和音频的处理、转码、格式转换和大小调整。这些功能非常有用,特别是对于需要处理大量视频和音频文件的应用程序。使用Spring Boot的特性可以使这一整合过程更加简单,同时也能从中获得更高的效率和更佳的应用程序设计。 ### 回答3: Spring Boot是一款基于Spring Framework的快速开发框架,它可以帮助开发者更快、更简单地构建Spring应用程序。而FFmpeg是一个开源的跨平台音视频处理工具,它支持多种格式的音视频文件处理。将Spring BootFFmpeg进行整合可以实现对音视频数据进行处理的功能。 首先,需要在Spring Boot应用程序中添加FFmpeg相关依赖。常用的依赖有jaffree、ffmpeg-java和xuggle-xuggler等。 然后,需要在Spring Boot应用程序中编写实现对FFmpeg调用的代码。比如,使用jaffree进行FFmpeg命令的构建与执行: ``` FFmpeg.atPath("ffmpegPath") .addInput(Input.fromPath("inputFile.mp4")) .addOutput(Output.toPath("outputFile.mp4")) .execute(); ``` 这段代码可以实现对inputFile.mp4视频文件的处理,并将处理结果保存为outputFile.mp4。其中,ffmpegPath为FFmpeg的可执行程序路径。 同时,可以实现对多个音视频文件的合成、分离、转换等操作,并可以设置FFmpeg命令的各项参数,如视频的分辨率、码率、帧率等。 最后,开发者可以使用Spring Boot的MVC框架将处理结果展示给用户。比如,在网页上实现视频文件的播放。 综上所述,Spring Boot整合FFmpeg可以实现对音视频数据的处理,并且实现较为简单。但是,在使用FFmpeg时需要注意其对系统资源的消耗。如果处理较大的文件或处理操作较多,需要考虑系统资源的限制。同时,需要注意FFmpeg命令的安全性,避免恶意攻击。
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值