因为工作的关系,接触到音视屏方面的。而音视频就离不开开源FFmpeg,之前一直有写博客,一年的沉淀,还是要把博客继续下去,也算是一个总结。
要想学习FFmpeg,首先要学会编译FFmpeg,其实很多不是从事音视频的人,很可能没有继续研究,就是倒在第一大关第一小关上面。
雷神博客
https://blog.csdn.net/leixiaohua1020/article/details/15811977
闲话少说
ffmpeg在git上的地址
git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
但是一般下载会比较慢,也可以直接去官网下载,这里我使用的是最新版本ffmpeg-4.1.3
http://www.ffmpeg.org/download.html
另外我们需要下载ndk平台,根据自己的需要去下载,这里因为工作的原因我使用的是android-ndk-r16b-linux-x86_64.zip
https://developer.android.google.cn/ndk/downloads/older_releases.html#ndk-16b-downloads
下载压缩包后,分别到linux系统下解压,这里就不多说,主要说之后的环境配置和遇到的编译问题
这里说一下,如果我们不是要编译在Android环境可以使用的FFmepg可执行程序,只是为了在linux下学习使用一番,我们只需要进入ffmpeg目录,然后执行下面的命令。
./configure --target-os=linux --prefix=$(pwd)/android/arm --disable-doc --enable-shared --disable-static --disable-symver --enable-gpl
make -j8
如果要编译出Android 环境中可以使用的可执行程序,就需要按我下面的方法改一些东西,才可以
进入ffmpeg目录,修改configure,如果你不修改的话,编译出来过后的.so文件后面会有一串数字,无法使用,所以得修改他的命名规则。
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'
修改为
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
接下来是NDK的环境配置,可以根据我的配置,设置自己的编译链路径,可以自己写一个脚本,把下面的环境每次都运行脚本运行一次,也可以每次一行一行输。
export NDK=/home/moonright83/samba/android_2851/android-ndk-r16b
export SYSROOT=$NDK/platforms/android-24/arch-arm
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
export ASM=$NDK/sysroot/usr/include/arm-linux-androideabi
接下来是配置configure,这一步最关键,自己有踩到很多坑。如果配置不正确,之后的编译会出现各种问题,经过不断的尝试,这个是成功的版本
./configure --target-os=android --prefix=$(pwd)/android/arm --arch=arm --disable-doc --disable-network --disable-shared --enable-static --disable-symver --enable-gpl --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- --enable-cross-compile --sysroot=$SYSROOT --extra-cflags="-I$ASM -isysroot $NDK/sysroot -Os -fpic -pie -fPIE -march=armv7-a -mfloat-abi=softfp -mfpu=neon -static" --enable-neon
开始编译
make -j8
// 可以根据自己的虚拟机处理器进行选择,我的电脑是6核心12线程,所以我给虚拟机分
// 配4个处理器,2个核心。一般-j后的数字选择为自己处理器的2倍为最佳。
下面是我在编译的过程中遇到的一些问题
关于ndk-r14b 编译ffmpeg 4.1.3 遇到的udp.c 中的mreqs.imr_multiaddr.s_addr 的s_addr未定义之解决方案
目前未找到好的解决办法,所以直接在configure文件中注释掉
--disable-network
编译报错
libavcodec/aaccoder.c: In function 'search_for_ms':
libavcodec/aaccoder.c:803:25: error: expected identifier or '(' before numeric constant
int B0 = 0, B1 = 0;
解决:将libavcodec/aaccoder.c文件B0变量替换成b0解决:将libavcodec/aaccoder.c文件B0变量替换成b0
编译报错
libavcodec/hevc_mvs.c: In function 'derive_spatial_merge_candidates':
libavcodec/hevc_mvs.c:208:15: error: 'y0000000' undeclared (first use in this function)
((y ## v) >> s->ps.sps->log2_min_pu_size))
解决:将libavcodec/hevc_mvs.c文件的变量B0改成b0,xB0改成xb0,yB0改成yb0
编译报错
libavcodec/opus_pvq.c: In function 'quant_band_template':
libavcodec/opus_pvq.c:498:9: error: expected identifier or '(' before numeric constant
int B0 = blocks;
解决:将libavcodec/opus_pvq.c文件的变量B0改成b0
编译好之后
make install
产生android的目录
此时可以将编译生成的ffmpeg可执行程序,导入到我们的android板子里system/bin下,修改权限重启后,将U盘中的flv格式文件转换成MP4文件,运行成功。
ffmpeg -i XXX.flv output.mp4