Android下编译及修剪FFMPEG插件
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了目前领先的音/视频编码库libavcodec。 FFmpeg是在 Linux 下开发出来的,但它可以在包括 Windows 在内的大多数操作系统中编译。这个项目是由 Fabrice Bellard 发起的,现在由 Michael Niedermayer 主持。可以轻易地实现多种视频格式之间的相互转换,例如可以将摄录下的视频avi等转成现在视频网站所采用的flv格式。
提要
FFMPEG确实是一个神器,支持各种格式,如果嵌入应用的话,遇到的问题就很明显:体积太大
一个大致完整的FFMPEG插件的大小有将近200MB emm,而需求往往只需要特定一些功能,所以裁剪是个必不可少的需求。
下载源代码
可以到FFMPEG官网下载,但与其下载源码自己改,不妨下载安卓适配的mobile-ffmpeg,该插件也存在FFMPEG官网中,是个官方认可的三方编译插件,且star有2.4k。
值得注意的是:FFMPEG
为LGPL/GPL
项目,如果要用在商业用途,请一定避免使用--enable-gpl
以及--enable-nonfree
,若要修改FFMPEG代码,则必须声明修改部分!否则容易引起版权问题!
此处以mobile-ffmpeg
为例说明。
明确需求
此处假定一个最简单的需求:要求将aac
格式的音频文件转为特定码率,特定采样率,1声道的pcm_s16le
原生格式的音频文件。那么我们只需要保留此功能即可。
修剪
mobile-ffmpeg
中使用android.sh
进行安卓版本的编译,若要修剪,则需要修改configure的参数,build/android-ffmpeg.sh
配置了configure参数。
在该文件找到configure参数,在尾部加上:
1
2
3
4
5
6
7
8
--disable-everything
--enable-filter=anull,aresample,aformat \
--enable-parser=aac* \
--enable-demuxer=aac* \
--enable-muxer=pcm_s16le \
--enable-decoder=aac*,pcm_s16le \
--enable-protocol=file \
--enable-encoder=pcm_s16le \
首先使用--disable-everything
关掉所有的组件,再添加需要的内容
- encoder
- 为编码器,由于只需要一种
pcm_s16le
,则只开这个即可
- 为编码器,由于只需要一种
- decoder
- 为解码器,作用于源文件,由于只需要aac(aac也含有多种子类型)格式,此处改为
aac*
,匹配所有类型的aac
- 为解码器,作用于源文件,由于只需要aac(aac也含有多种子类型)格式,此处改为
- parser
- 为解释器,每一个解码器/编码器都需要一个parser从输入中获取一帧数据,所以此处需要同时支持encoder和decoder的类型,为
aac*,pcm_s16le
- 为解释器,每一个解码器/编码器都需要一个parser从输入中获取一帧数据,所以此处需要同时支持encoder和decoder的类型,为
- muxer
- 为合并器,可以将视频和音频数据合并到一个封装格式数据中去。此处也加一个
pcm_s16le
- 为合并器,可以将视频和音频数据合并到一个封装格式数据中去。此处也加一个
- demuxer
- 为分离器,可以将文件拆分,如rmvb中含有视频和字幕文件时,可以用这个进行分离。对于封装的格式也有拆分的作用。作用于源文件。
- muxer
- 与demuxer相反。作用于目标文件。此处为
pcm_s16le
- 与demuxer相反。作用于目标文件。此处为
- protocol
- 支持输入输出的协议,由于只是文件操作,所以这直接为
file
- 支持输入输出的协议,由于只是文件操作,所以这直接为
- filter
- 是对音频/视频做变换的组件,改码率,声道,指定格式要用到,此处测试过用
anull,aresample,aformat
即可(a表示音频滤镜)anull
即直接将源输入导出至输出aresample
表示重新采样aformat
用于约束目标文件的格式
- 是对音频/视频做变换的组件,改码率,声道,指定格式要用到,此处测试过用
之后进行编译,编译日志会出现在build.log
中,如果遇到错误可以这样改
编译失败,如果是说NDK版本不完全一致,可以在
app/build.gradle
改
进一步修剪
此时发现已经很小(1MB)了,能否进一步改呢?
我们发现在configure下有个选项还是开着的
1
--enable-swscale
scale
为缩放的意思SoftWare Scale
。但是处理音频的话,也不变速,所以直接改为--diable-swscale
。进行编译…
发现编译不通过,查看build.log
提示swscale
啥的不存在。奇怪了,视频组件为啥要依赖到cpp层…开始改c++代码。
首先查看报错的android/jni/Android.mk
文件,发现引用了libswscale.so
,注释掉
1
2
3
4
5
#include $(CLEAR_VARS)
#LOCAL_ARM_MODE := $(MY_ARM_MODE)
#LOCAL_MODULE := libswscale
#LOCAL_SRC_FILES := libswscale.so
#include $(PREBUILT_SHARED_LIBRARY)
再逐步编译,查看哪里错误,把相关代码或函数注释掉…
最后也能减小将近200KB的sdk大小。