1、FFmepg基础知识

About FFmpeg
ffmpeg(计算机程序) - 百度百科
FFmpeg/FFmpeg - GitHub
CSDN:FFmpeg 基础知识 @在奋斗的大道

关于FFmpeg
FFmpeg是领先的多媒体框架,能够解码,编码, 转码,复用,解复用,流,过滤和播放几乎任何东西 人类和机器创造的。它支持最晦涩的 古老的格式直到最前沿。不管他们是不是 由一些标准委员会,社区或公司设计。是的 而且高度可移植:FFmpeg 编译、运行并通过我们的测试基础设施 FATE 跨 Linux、Mac OS X、 Microsoft Windows,BSD,Solaris等在各种各样的构建下 环境、计算机体系结构和配置。

它包含libavcodeclibavutillibavformatlibavfilterlibavdevicelibswscalelibswresample 可供应用程序使用。 以及ffmpeg,ffplay和ffprobe,可用于 最终用户进行转码和播放。

FFmpeg项目试图提供最好的技术可能 适用于应用程序开发人员和最终用户的解决方案。要实现 我们结合了可用的最佳免费软件选项。我们稍微 支持我们自己的代码,以保持对其他库的依赖较低,并 最大化 FFmpeg 各部分之间的代码共享。 凡是“最好”的问题无法回答的地方,我们都支持两者 选项,以便最终用户可以选择。

FFmpeg 欢迎所有人,也欢迎所有贡献。 我们很高兴收到补丁,拉取请求,错误报告,捐赠 或任何其他类型的贡献。

安全性是重中之重,代码审查始终使用 牢记安全性。虽然由于大量的代码接触 不受信任的数据安全问题是不可避免的,因此我们提供 在以下情况下尽快更新到我们上一个稳定版本 发现新的安全问题。


FFmpeg 工具


面向开发人员的 FFmpeg 库

  • libavutil 是一个包含函数的库 简化编程,包括随机数生成器、数据 结构、数学例程、核心多媒体实用程序等等 更多。
  • libavcodec是一个包含解码器和编码器的库 用于音频/视频编解码器。
  • libavformat 是一个包含解复用器和 用于多媒体容器格式的复用器。
  • libavdevice 是一个包含输入和输出的库 用于抓取和渲染许多常见多媒体的设备 输入/输出软件框架,包括Video4Linux,Video4Linux2, VfW和ALSA。
  • libavfilter 是一个包含媒体过滤器的库。
  • libswscale 是一个执行高度优化图像的库 缩放和色彩空间/像素格式转换操作。
  • libswresample 是一个执行高度优化的库 音频重新采样、重新矩阵和样本格式转换操作。

1.1 下载 FFmpeg

Download FFmpeg

1.2 FFmpeg 工具使用

  • ffmpeg\bin\ffmpeg.exe
命令 说明
ffmpeg -i input.avi 查询视频信息
ffmpeg -i input.avi -hide_banner 查询只显示视频信息
ffmpeg -i input.avi output.mp4 通过重新编码媒体流,将输入媒体文件转换为其他格式
ffmpeg -i input.avi -b:v 64k -bufsize 64k output.mp4 将输出文件的视频比特率设置为 64 kbit/s
ffmpeg -i input.avi -r 24 output.mp4 强制输出文件的帧速率为 24 fps
ffmpeg -r 1 -i input.m2v -r 24 output.mp4 强制输入文件的帧速率(仅对原始格式有效)为 1 fps,并且 输出文件的帧速率为 24 fps
  • ffmpeg\bin\ffplay.exe
命令 说明
ffplay -i input.avi 读取视频input.avi。不会自动退出,原比例播放
ffplay -autoexit input.avi 视频播放完毕后退出。
ffplay -x 600 -y 800 input.avi 600x800播放
  • ffmpeg\bin\ffprobe.exe
命令 说明
ffprobe input.avi -hide_banner 显示视频信息
ffprobe input.avi -hide_banner -show_format 显示有关输入多媒体的容器格式的信息
ffprobe input.avi -hide_banner -show_format -print_format json 以json数据显示有关输入多媒体的容器格式的信息

2、Java使用

2.1 FFmpeg源码编译

Windows下编译FFmpeg - 知乎
Windows编译和使用ffmpeg

2.2 Java集成FFmpeg

2.2.1 JNI

Java版流媒体编解码和图像处理(JavaCPP+FFmpeg)
Javacv使用ffmpeg实现音视频同步播放

Java通过JNI调用FFmpeg的c语言,Window上需要FFmpeg相应的.dll文件,Linux上需要FFmpeg相应的.so文件

2.2.2 Java调用执行 FFmpeg 工具 命令

Java执行命令方法: ( 工具类:org.apache.commons:commons-exec )
java/lang/Runtime.java
java/lang/ProcessBuilder.java

 // 执行命令
 Process process = Runtime.getRuntime().exec("cmd /c dir /b");
 // 获取命令输出结果
 BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
 String line;
 while ((line = reader.readLine()) != null) {
     XLog.d(line);
 }

 // 等待命令执行完成
 process.waitFor();

在这里插入图片描述

Java通过流获取命令输出结果可能会存在缓存的问题。当使用Java通过Runtime.getRuntime().exec等方法执行指令时,命令本身的输出结果是通过标准输出流(stdout)和标准错误流(stderr)来输出的。而Java读取输出结果的方式是通过获取进程的标准输出流/标准错误流来进行读取的。但当命令输出比较多时,标准输出流和标准错误流会同时存在一定大小的缓存区,如果Java读取不及时,就可能无法获取到完整的输出结果。解决该问题可以采用多线程读取和行缓冲。即为程序开启一个线程去读取进程输出,每读取一行即将其写入缓冲中。这样就能解决输出结果获取不到的问题。

String osname = System.getProperty("os.name").toLowerCase();
XLog.d("osname = " + osname);
String cmd = osname.contains("windows") ? "where.exe ffmpeg" : "which ffmpeg";

Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();

String ffmpeg = IOUtils.toString(p.getInputStream(), Charset.defaultCharset()).trim();

XLog.d(ffmpeg);

在这里插入图片描述

  • 调用ffmpeg -i input.avi -hide_banner:这里配置了环境变量,如ffmpeg\bin

在这里插入图片描述

Process process = Runtime.getRuntime().exec("ffmpeg -i C:\\Users\\Administrator\\Desktop\\input.avi -hide_banner");
process.waitFor();
String ffmpegGetInputStream = IOUtils.toString(process.getInputStream(), Charset.defaultCharset()).trim();
String ffmpegGetErrorStream = IOUtils.toString(process.getErrorStream(), Charset.defaultCharset()).trim();

XLog.d("ffmpegGetInputStream: "+ffmpegGetInputStream);
XLog.d("ffmpegGetErrorStream: "+ffmpegGetErrorStream);
String osname = System.getProperty("os.name").toLowerCase();
XLog.d("osname = " + osname);
String cmd = osname.contains("windows") ? "where.exe ffmpeg" : "which ffmpeg";
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
String ffmpeg = IOUtils.toString(p.getInputStream(), Charset.defaultCharset()).trim();
XLog.d(ffmpeg);

String[] cmdarray = new String[]{ffmpeg, "-i", "C:\\Users\\Administrator\\Desktop\\input.avi", "-hide_banner"};
Process process = Runtime.getRuntime().exec(cmdarray);
process.waitFor();
String ffmpegGetInputStream = IOUtils.toString(process.getInputStream(), Charset.defaultCharset()).trim();
String ffmpegGetErrorStream = IOUtils.toString(process.getErrorStream(), Charset.defaultCharset()).trim();
XLog.d("ffmpegGetInputStream: "+ffmpegGetInputStream);
XLog.d("ffmpegGetErrorStream: "+ffmpegGetErrorStream);

1> 这里比较奇怪,输出结果在process.getErrorStream()获取
2> 可以研究一下ProcessBuilderJava ProcessBuilder类源码分析(开发“Java命令执行器”前期准备)
3> 建议使用线程池ExecutorService、Executors

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐