去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???

去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第1张图片

分享一下字节面试被问的一个问题,Java使用FFmpeg处理视频文件的相关内容

能进大厂真的香,你先搞定这些问题。

今天给大家带来用Java + FFmpeg实现对视频文件的信息提取、码率压缩、分辨率转换等功能;在网上转了一大圈用Java使用FFmpeg处理音视频的文章,没有我特别满意的回答,于是自己上手来一篇。希望你们看到这些后能完美避坑!

1. 什么是FFmpeg

Fmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPLGPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

提醒一下,更多详情可以去百度了解一下

2. 开发前准备

在使用Java调用FFmpeg处理音视频之前,需要先安装FFmpeg,安装方法分为两种:

  • 引入封装了FFmpeg的开源框架
  • 在系统中手动安装FFmpeg

2.1 引入封装了FFmpeg的开源框架

JAVE.jar是一个封装了FFmpegJava框架,在项目中能直接调用它的API来处理音视频文件;

优点:使用方便,直接在项目中引入JAVE.jar即可处理媒体文件,且开发完成后可以随工程一起打包发布,不需要在目标运行环境内手动安装FFmpeg相关的类库

缺点:JAVE.jar最后一次更新是2009年,其封装的FFmpeg版本是09年或更早前的版本,比较老旧,无法使用一些新特性 (当然也可以看看有没有其他比较新的封装了FFmpeg在这里插入代码片的框架) Maven坐标如下:

<dependency>
 <groupId>org.ffmpeg</groupId>
 <artifactId>sdk</artifactId>
 <version>1.0.2</version>
</dependency>

2.2在系统中手动安装FFmpeg

在运行环境中手动安装FFmpeg稍微有一些麻烦,可以百度 windows/mac安装FFmpeg 这样的关键字,根据网上的安装教程将FFmpeg安装到系统中;


## **懒人安装链接可找我要哒**

优点:可以直接调用FFmpeg的相关API处理音视频,FFmpeg版本可控

缺点:手动安装较为麻烦,开发环境与目标运行环境都需要先安装好FFmpeg

3. 使用FFmpeg处理音视频

使用JAVE.jar进行开发与直接使用FFmpeg开发的代码有一些不同,这里以直接使用FFmpeg进行开发的代码进行讲解(开发环境MacOS);(使用JAVE的代码、、直接使用FFmpeg的代码都会附在文末供大家下载参考) 通过MediaUtil.java类及其依赖的类,你将可以实现:

- 解析源视频的基本信息,包括视频格式、时长、码率等;

- 解析音频、图片的基本信息;

- 将源视频转换成不同分辨率、不同码率、带或不带音频的新视频;

- 抽取源视频中指定时间点的帧画面,来生成一张静态图;

- 抽取源视视频中指定时间段的帧画面,来生成一个GIF动态图

- 截取源视频中的一段来形成一个新视频;

- 抽取源视频中的音频信息,生成单独的MP3文件;

- 对音视频等媒体文件执行自定义的FFmpeg命令;

3.1 代码结构梳理

  • MediaUtil.java是整个解析程序中的核心类,封装了各种常用的解析方法供外部调用;
  • MetaInfo.java定义了多媒体数据共有的一些属性.VideoMetaInfo.java MusicMetaInfo
    ImageMetaInfo.java都继承自MetaInfo.java,分别定义了视频、音频、图片数据相关的一些属性;
  • AnimatedGifEncoder.java LZWEncoder.java
    NeuQuant.java在抽取视频帧数、制作GIF动态图的时候会使用到;

CrfValueEnum.java 定义了三种常用的FFmpeg压缩视频时使用到的crf值,PresetVauleEnum.java定义了FFmpeg压缩视频时常用的几种压缩速率值;

3.2 MediaUtil.java主程序类解析

3.2.1 使用前需要注意的几点

1、指定正确的FFmpeg程序执行路径

MacOS安装好FFmpeg后,可以在控制台中通过which ffmpeg命令获取FFmpeg程序的执行路径,在调用MediaUtil.java前先通过其 setFFmpegPath() 方法设置好FFmpeg程序在系统中的执行路径,然后才能顺利调用到FFmpeg去解析音视频;

Windows系统下该路径理论上应设置为:FFmpeg可执行程序在系统中的绝对路径(实际情况有待大家补充)

2、指定解析音视频信息时需要的正则表达式

因项目需要解析后缀格式为 .MP4 .WMV .AAC 的视频和音频文件,所以我研究了JAVE.jar底层调用FFmpeg时的解析逻辑后,在MediaUtil.java中设置好了匹配这三种格式的正则表

注意:如果你需要解析其他后缀格式如 .MKV .MP3 这样的媒体文件时,你很可能需要根据实际情况修改durationRegex videoStreamRegex musicStreamRegex 这三个正则表达式的值,否则可能无法解析出正确的信息;

3、程序中的很多默认值你可以根据实际需要修改,比如视频帧抽取的默认宽度或高度值、时长等等;

3.2.2 MediaUtil.java代码
去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第2张图片
去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第3张图片
去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第4张图片
去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第5张图片
去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第6张图片
去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第7张图片
去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第8张图片
去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第9张图片
去字节面试,竟然出了这个?如何使用FFmpeg处理视频文件???_第10张图片
卖个关子,不会吧真有人看到这里了,是不是卡住了,不用担心,自己做一遍,源码可call me我发现尽管我一顿卡卡卡没有用,你得真正接收到我的信号才行。咱们接着

3.2.3 踩坑&填坑

1、在Linux等服务器上部署Java程序进行视频压缩时,多注意一下运行账号的权限问题,有时候可能是由于运行程序没有足够的文件操作权限,导致压缩过程失败;

2、第一版程序上线后,偶尔会出现这样的问题:

  • 调用MediaUtil.java进行视频压缩过程中,整个程序突然“卡住”,后台也没有日志再打印出来,此时整个压缩过程还没有完成,像是线程突然阻塞住了;
  • 经过多番查找,发现Java调用FFmpeg时,实际是在JVM里产生一个子进程来执行压缩过程,这个子进程与JVM建立三个通道链接(包括标准输入、标准输出、标准错误流),在压缩过程中,实际会不停地向标准输输出和错误流中写入信息;
  • 因为本地系统对标准输出及错误流提供的缓冲区大小有限,当写入标准输出和错误流的信息填满缓冲区时,执行压缩的进程就会阻塞住;
  • 所以在压缩过程中,需要单独创建两个线程不停读取标准输出及错误流中的信息,防止整个压缩进程阻塞;(参考MediaUtil.java中的
    executeCommand() 方法中的 errorStream

这下可以去面试了吧,字节等你

想要更清晰的源码可以告诉我

整理不易,记得三连

你可能感兴趣的:(编程语言,java,架构人生,java,数据库,ffmpeg,面试,大数据)