一,FFmpeg介绍
FFmpeg 是一款流行的开源多媒体处理工具,它可以用于转换、编辑、录制和流式传输音视频文件。FFmpeg 具有广泛的应用场景,包括视频编解码、格式转换、裁剪、合并、滤镜等等。官网:https://ffmpeg.org/
FFmpeg 支持各种常见的音视频格式,例如 MP4、AVI、FLV、MOV、AAC、MP3、M4A 等等,并且可以通过添加插件支持更多的格式。与其他视频处理软件相比,FFmpeg 优势在于它的跨平台性能好,可以在 Windows、macOS 和 Linux IOS Android等平台上运行。
FFmpeg 提供了一个命令行界面(CLI),可以使用它来执行各种操作。以下是一些常用的 FFmpeg 命令:
- 裁剪:从视频中截取指定时间段的视频片段。
- 视频旋转:将视频顺时针或逆时针旋转指定角度。
- 视频拼接:将多个视频文件拼接成一个文件。
- 视频缩放:按比例缩小或放大视频尺寸。
- 音频提取:将视频文件中的音频提取出来。
- 音频合并:将多个音频文件合并为一个文件。
- 视频转码:将一个视频文件转换为另一种格式。
- 视频加减速:将视频的播放速度加快或减慢。
- 音频加减速:将视频中的音频的播放速度加快或减慢。
- 音频重采样
- 视频转Gif并等比例缩放
- 统计I帧数量
- 视频信息查看 开发过程中最常用的命令,没有之一
结果如下:
在FFmpeg工具中,ffprobe是一种用于分析媒体文件的命令行工具,参数解释如下:
profile
在H.264/AVC (Advanced Video Coding)视频编码标准中,有以下四种预定义的profile:
- Baseline Profile:这是最基本的profile,它定义了一组基本功能,包括单个参考帧、CAVLC (Context-adaptive Variable Length Coding)、8x8变换等。Baseline Profile可用于低比特率、低延迟和低复杂度的应用。
- Main Profile:Main Profile扩展了Baseline Profile并增加了一些高级功能,例如B帧、8x8和4x4变换以及熵编码模式自适应技术。Main Profile可以提供更好的视频质量和压缩率,适合于中等比特率的应用。
- Extended Profile:Extended Profile扩展了Main Profile,并添加了更多的高级功能,例如8x8和4x4变换、支持更高分辨率、更高的比特率和更丰富的颜色空间。Extended Profile适用于高清视频和广电级别的视频应用。
- High Profile:High Profile包含所有的H.264/AVC高级功能,例如无损编码、多层编码、亮度调整等。High Profile通常用于专业级别的视频应用,例如数字电视广播、蓝光光盘和高清视频流媒体服务。
除了上述四个预定义的profile之外,H.264/AVC还支持用户定义的profile,以根据具体应用需求自定义编解码器的参数设置。
编码level
在H.264/AVC视频编码标准中,Level指的是视频编码器的限制条件,例如最大分辨率、最高比特率以及其他一些技术参数。这些限制条件与profile不同,因为它们通常受到实时处理硬件设备的限制。以下是H.264/AVC定义的level:
- Level 1:支持最大352x288像素分辨率和1.5 Mbps的解码速度。
- Level 1b:类似于Level 1,但要求使用Baseline Profile。
- Level 1.1:支持最大352x480像素分辨率和12 Mbps的解码速度。
- Level 1.2:支持最大720x480像素分辨率和30 Mbps的解码速度。
- Level 1.3:支持最大1280x720像素分辨率和60 Mbps的解码速度。
- Level 2:支持最大1920x1080像素分辨率和60 Mbps的解码速度。
- Level 2.1:支持最大1920x1080像素分辨率和120 Mbps的解码速度。
- Level 2.2:支持最大1920x1080像素分辨率和120 Mbps的解码速度,并要求使用High Profile。
- Level 3:支持最大1920x1080像素分辨率和240 Mbps的解码速度。
- Level 3.1:支持最大1920x1080像素分辨率和240 Mbps的解码速度,并要求使用High Profile。
- Level 3.2:支持最大1920x1080像素分辨率和240 Mbps的解码速度,并要求使用High Profile和4:2:2色度采样。
- Level 4:支持最大2048x2048像素分辨率和480 Mbps的解码速度。
- Level 4.1:支持最大2048x2048像素分辨率和1 Gbps的解码速度。
- Level 4.2:支持最大2048x2048像素分辨率和1 Gbps的解码速度,并要求使用High Profile和10位色深。
- Level 5:支持最大4096x2304像素分辨率和1 Gbps的解码速度。
- Level 5.1:支持最大4096x2304像素分辨率和2 Gbps的解码速度。
- Level 5.2:支持最大4096x2304像素分辨率和4 Gbps的解码速度。
需要注意的是,level越高,支持的分辨率和比特率就越高,因此所需的处理能力和存储空间也越大。同时,实际可用的level还受到编码器和解码器的硬件限制。
DISPOSITION
DISPOSITION是指多媒体文件流(例如音频、视频)在其容器中的位置以及是否被默认启用的标志。它告诉我们这个特定的流的角色是什么,并且是否应该被自动启用。
以下是一些常见的DISPOSITION标志:
default:表示该流是默认启用的。
dub:表示这个流是一个双语版本的语言流。
original:表示这个流是原始的无损版本。
comment:表示这个流是注释版本的。
lyrics:表示这个流包含歌词信息。
通过查看DISPOSITION标志,我们可以确定每个音频或视频流的作用和启用状态,这对于解析和编辑多媒体文件非常有用。
除了命令行界面之外,FFmpeg 还提供了许多开发库,例如 libavcodec 和 libavformat 等,这些库可以帮助您将 FFmpeg 集成到自己的应用程序中。
总之,FFmpeg 是一款强大的多媒体处理工具,可以让您对音视频文件进行各种操作。如果您需要在自己的应用程序中使用 FFmpeg,可以使用其提供的开发库
二,FFmpeg编译
要想把FFmpeg运行在移动设备上,就需要使用到交叉编译,交叉编译是指在一台计算机上,使用一个编译器将程序或库编译成可以在不同架构的计算机上运行的二进制文件。通常情况下,交叉编译是在开发人员的计算机上完成的,然后将生成的可执行文件或库文件拷贝到目标设备上运行。
2.1 常见的错误
C compiler test failed.
出现这个问题一般有两种情况
- NDK版本不对,NDK 的版本非常重要,因为不同版本的 NDK 可能与不同版本的 FFmpeg 不兼容。在下载 NDK 时,请确保使用与您要构建的 FFmpeg 版本相匹配的 NDK 版本。
-NDK路径写错了
ld: error: relocation R_AARCH64_ADD_ABS_LO12_NC cannot be used against symbol
- 在–extra-ldflags 加入-fPIC
- 在链接的时候加入-Bsymbolic,慎重使用
- 注意链接的时候的顺序 比如libavutil是每个库都需要的,那么就要放在第一个链接
duplicate symbol
–enable-shared --enable-static 同时打开,在合并so的时候会出现重复的方法
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol “cos”
在编译以及在把.a文件链接到SO的时候没有把m,z,android库链接上
2.2 编译步骤
2.2.1 下载Android SDK
2.2.2下载Android NDK
2.2.3 安装必备的软件
2.2.4 Start build
A 基础build
脚本的执行时间比较长,安静的等待脚本执行完成,脚本执行完成之后,生成的SO在output目录下,如图所示:
可以看到,这个脚本构建是不能直接用于开发,主要有以下问题:
- 可以看到这个脚本构建的结构有多个SO,这在开发中显得不是很优雅,我们需要做的是把这些SO合并成一个SO
- 构建出来的SO很大,包大小遭不住
- 在构建的时候我们常用的库libmp3lame,libx264(libx264是GPL协议的,要注意安全合规)没有编译进去
B 多个SO合并成一个SO
要想把多个SO合并成一个SO,那么就需要把FFmpeg编译成静态库,有关静态库与动态库的解释如下:
静态库是编译时链接到应用程序中的,它将库文件的全部内容复制到应用程序中。这意味着在运行时,所有的库函数都已经存在于应用程序中,不需要再进行加载。由于静态库已经被完全链接到应用程序中,因此它们的大小通常比动态库更大,但执行速度更快,因为没有额外的加载和解析操作。同时,使用静态库可以避免版本冲突和依赖问题,因为每个应用程序都会使用自己的一份库文件副本。
相反,动态库是在运行时动态加载的,只有当需要使用库函数时才会被加载到内存中。由于动态库仅在需要时才加载,因此它们的大小通常比静态库小,但执行速度可能稍慢,因为需要进行额外的加载和解析操作。另外,由于多个应用程序可以共享相同的库文件,因此动态库提供了更好的资源利用率。
总之,静态库是在编译时链接到应用程序中的,而动态库是在运行时动态加载的。静态库的优点是执行速度更快,依赖和版本控制更容易,而动态库的优点是更小的库文件大小和更好的资源利用率。可以用文件后缀做简单的区分:静态库文件后缀为.a, 动态库文件后缀为.so
步骤如下:
- 首选我们需要修改ffmpeg-android-maker-master/scripts/ffmpeg/build.sh 文件把–disable-static 改成–enable-static 再次build 的时候就可以在ffmpeg-android-maker-master/build目录下看到.a文件已经生成了(在调试脚本的时候可以在后面加-abis=arm64-v8a 参数,只是构建64位的库,这个构建时间就会短很多)
- 合并.a文件
C FFmpeg裁剪
so合并的文件的问题解决了,但是合并的so会显得很大,这是因为默认是把FFmpeg的代码全部编译了,我们需要做一些裁剪,去掉我们不用的代码
在不知道有那些配置可以选择的时候,可以在FFmpeg源码下执行https://blog.51cto.com/u_/configure 这样默认会把所有支持的配置都列出来,然后依次去掉不必要的配置就好
最终scripts/ffmpeg/build.sh文件的样式如下:
脚本说明
- 从Android 5.0开始,默认情况下所有设备都支持NEON指令集,在编译的时候尽量打开NEON,这样性能会更好
- asm指的是汇编优化,这样代码执行性能会更好,但是在FFmpeg上编译一般使用inline-asm(内联汇编),因为而普通汇编需要单独编写成汇编代码文件,增加了额外的编译链接过程,很容易链接失败,而且内联汇编执行效率更高
D 添加常用的第三方库
3.Android 开发环境搭建
3.1 新建工程
指定ndk版本
ndk版本一般要在各个开发者直接统一,写法为,在build.gradle->android下面写,如下
ndkVersion ‘25.2.’
3.2 cmake简介
其中cpp目录下的CMakeLists.txt文件是构建so的关键文件,俗称cmake文件,如下:
3.2.1 cmake基本语法
cmake的基本语法和C类似,都是通过方法名()的方式来使用的如:
条件语句
循环语句
函数
函数由命令组成,通过 定义,可以在任意位置调用。
3.2.2 cmake变量的使用与定义
变量在 CMake 中以 开头,有以下几种类型:
- 内置变量:如 表示当前 CMake 文件所在的目录。
- 环境变量:如 表示系统环境变量 PATH 的值。
- 用户定义变量:如 ,通过 引用。
3.2.3 常见的用法
其实上面的很少用,我们来看一个稍微复杂一点的,工作中掌握这么多就够用了,如下:
3.2.4 配置支持的CPU架构
默认情况下SO会生成armeabi-v7a,arm64-v8a,x86,x86_64,如果我们只想生成指定的SO,那么在build.gradle文件android->defaultConfig下配置ndk来过滤就好了,如下:
3.3验证FFmpeg编译是否成功
- 执行System.loadLibrary没有任何报错
- 能够成功获取到编码器,解码器,avformat信息,验证代码如下:
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.bianchenghao6.com/h6javajc/24736.html