前言

在此之前,博主写了很多关于如何使用JavaCV的教程,例如《JavaCV五合一教程合集》《JavaCV入门教程》《JavaCV实战教程》等等,不一一赘述,这些都是通过JavaCV的跨平台能力调用ffmpeg/opencv/tesserac等库的api。本章,博主将带领小伙伴们认识一个新的“跨平台”调用ffmpeg的方式。

咱们先来看看ffmpeg命令和javacv方式对比。

ffmpeg命令与JavaCV方式对比

例如这个转流的简单例子:
ffmpeg -i rtmp:/A -f flv -vcodec copy -acodec copy rtmp://B

ffmpeg命令的JavaCV跨平台等价替换

在JavaCV中,这个命令的等价替换代码是:

FFmpegFrameGrabber grabber = new FFmpegFrameGrabber("rtmp:/A");
grabber.start();
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("rtmp://B");
recorder.setFormat("flv");
recorder.start(grabber.getFormatContext());
for(;;){
     recorder.recordPacket(grabber.grabPacket());
}

使用JavaCV方式的优点
借助JavaCV和ffmpeg的api,可以获取每个音/视频帧和图像、音频采样,并可以二次处理后(使用opencv进行人脸检测识别或者添加视频滤镜、音频滤波),再进行推流或者是录制成hls/mp4分片文件等等操作。

通过上述对比,大家应该都看出来当然是使用FFmpeg更简单易用。但是ffmpeg本身并不能跨平台,如果要在代码中以跨平台方式执行ffmpeg命令,还需要编译各个平台下和各个指令集的ffmpeg。比如windows平台下需要编译和加载各个指令集(x86、amd64、arm64、armel、armhf、i386、mips、mips64el、mipsel、ppc64el、s390x)的
的ffmpeg.exe。
而想要让ffmpeg在linux各个发行版上跨平台,还需要知道ffmpeg在各个发行版都不通用,需要编译和加载各个发行版(debian、ubuntu、fedora、redhat/centos)下的各个指令集(x86、amd64、arm64、armel、armhf、i386、mips、mips64el、mipsel、ppc64el、s390x。
苹果mac平台就不讲了。

那么,有没有更简单的办法能够跨平台调用ffmpeg命令行呢?

如何基于JavaCV跨平台调用ffmpeg命令

在项目中引入JavaCV依赖

maven方式:

 <dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.5.6</version>
  </dependency>

gradle方式:

dependencies {
    implementation group: 'org.bytedeco', name: 'javacv-platform', version: '1.5.6'
  }

Leiningen方式

 :dependencies [
    [org.bytedeco/javacv-platform "1.5.6"]
  ]

sbt方式:

libraryDependencies += "org.bytedeco" % "javacv-platform" % "1.5.6"

基于JavaCV跨平台调用ffmpeg命令

通过String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);就可以获取JavaCV中的ffmpeg本地库的调用路径。

/**
 * 史上最简单的方式调用javacv中的ffmpeg本地程序
 * @author eguid
 */
 public static void main(String[] args){
	String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
	ProcessBuilder pb = new ProcessBuilder(ffmpeg, "-i", "/path/to/input.mp4", "-vcodec", "h264", "/path/to/output.mp4");
     pb.inheritIO().start().waitFor();
}

通过这种方式,就可以不需要编译各个平台(windows/linux各个发行版/安卓/mac/ios)下各个指令集的ffmpeg了。直接借助JavaCV的跨平台性,与原生ffmpeg一样执行各种ffmpeg命令了。

是不是很简单?

如果觉得博主写得还不错,欢迎大家“关注、点赞、收藏”一键三连支持博主原创!!!