多媒体开源库ffmpeg+x264+aac+lame源码编译

做Android UI 方面的开发已经3年多了,感觉遇到了瓶颈,后期打算往音视频方面发展,恰好最近公司不忙,编译了下音视频领域常用的几个开源库,特此记录,分享出来,希望能帮助到有用到这些开源库的网友们~

由于版权的原因,现在ffmpeg库默认是不支持视频x264格式,音频aac格式,音频mp3格式的编码的,仅支持上述格式的解码(可通过 命令 ffmpeg -codecs 查看支持的音视频编解码格式);所以才有后面这些库的集成工作需要做;网上其实也有这些开源库的编译脚本,不过比较零散,我这里再统一整理出来一份:先编译x264,第二步编译aac,第三步编译lame,最后再编译ffmpeg(其中ffmpeg编译出来的动态库有好几个,再加上前三步编译出来的三个静态库,最终编译为一个libffmpeg.so共享库)

后面的编译脚本中会用到一些环境变量,网友注意要替换成自己系统中的路径

NDK路径:NDK=/opt/software/android-ndk-r14b 

Android版本:$NDK/platforms/android-19/arch-arm(你可以采用自己的)

编译后库的CPU目标平台是arm-v7a(你可以将编译的目标平台变成你自己的)

x264和aac以及lame这几个较轻的开源库的静态库生成路径最好和ffmpeg的设置得一样,因为它们最终都是要和ffmpeg编译出来的8个静态库打包成一个的

编译环境

Linux:Ubuntu 12.04.2

NDK:android-ndk-r14b

ffmpeg-4.1.3http://ffmpeg.org/download.html
x264-20180212-2245http://download.videolan.org/x264/snapshots/x264-snapshot-20180212-2245-stable.tar.bz2
aac-0.1.6https://jaist.dl.sourceforge.net/project/opencore-amr/fdk-aac/
lame-3.100https://sourceforge.net/projects/lame/files/lame/3.100/

x264源码编译:最终生成有头文件 (include文件夹下的 x264_config.h  x264.h)和静态库文件 (lib文件夹下的 libx264.a)头文件和库文件 都是在最后打包成为一个共享库libffmpeg.so要用到的 ,后面的几个库编译后生成的文件类似就不再赘述

#!/bin/bash
export NDK=/opt/software/android-ndk-r14b
export SYSROOT=$NDK/platforms/android-19/arch-arm
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
#x264库的生成路径(建议和ffmpeg库的生成路径配置得一样,因为最后生成的静态库都会和ffmpeg的库打包为一个,如果配置得不一致就得手动拷贝到一起了-- 我是手动拷贝的)
export PREFIX=/home/xpzhi/x264-snapshot-20180212-2245-stable/install

function build_one
 {
 ./configure \
 --prefix=$PREFIX \
 --host=arm-linux \
 --enable-pic \
#生成的是.a结尾的静态库 .so结尾的是共享库
 --enable-static \
 --disable-cli \
 --cross-prefix=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi- \
 --sysroot=$SYSROOT
 }
build_one
make
make install

aac源码编译(终端中直接运行):

NDK_HOME=/opt/software/android-ndk-r14b
ANDROID_API=android-19

SYSROOT=$NDK_HOME/platforms/$ANDROID_API/arch-arm

ANDROID_BIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/

CROSS_COMPILE=${ANDROID_BIN}/arm-linux-androideabi-
 
ARM_INC=$SYSROOT/usr/include

ARM_LIB=$SYSROOT/usr/lib

LDFLAGS=" -nostdlib -Bdynamic -Wl,--whole-archive -Wl,--no-undefined -Wl,-z,noexecstack  -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$NDK_HOME/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a -L$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86/arm-linux-androideabi/lib -L$ARM_LIB  -lc -lgcc -lm -ldl  "
#enable-static --disable-shared生成的.a静态库,不是.so的共享库
FLAGS="--host=arm-androideabi-linux --enable-static --disable-shared"

export CXX="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}"

export LDFLAGS="$LDFLAGS"

export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"

./configure $FLAGS \
#aac库的生成路径 建议和ffmpeg最终生成的库配置得一起 否则最终合并的时候就得手动拷贝了--
--prefix='/home/xpzhi/fdk-aac-0.1.6/install'

再执行 make && make install 命令,即可在指定的 prefix 目录看到 fdk-aac的静态库了 

 

lame源码编译(终端中直接运行):

NDK_HOME=/opt/software/android-ndk-r14b
ANDROID_API=android-19
SYSROOT=$NDK_HOME/platforms/$ANDROID_API/arch-arm
ANDROID_BIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/
CROSS_COMPILE=${ANDROID_BIN}/arm-linux-androideabi-
export PATH=$PATH:$ANDROID_SDK/tools:$ANDROID_SDK/platform-tools
 
ARM_INC=$SYSROOT/usr/include
ARM_LIB=$SYSROOT/usr/lib
 
LDFLAGS=" -nostdlib -Bdynamic -Wl,--whole-archive -Wl,--no-undefined -Wl,-z,noexecstack  -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$NDK_HOME/sources/cxx-stl/gnu-libstdc++/libs/armeabi -L$NDK_HOME/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/arm-linux-androideabi/lib -L$ARM_LIB  -lc -lgcc -lm -ldl  "
 
FLAGS="--host=arm-linux --enable-static --disable-shared"
 
export CXX="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}"
export LDFLAGS="$LDFLAGS"
export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"
CPU=armv7-a
 
./configure $FLAGS \
--prefix=$(pwd)/android/$CPU

再执行 make && make install 命令,即可在指定的 prefix 目录看到 lame 的静态库了 

 

ffmpeg源码编译:

对于x264库 要增加编译配置参数 --enable-encoder=libx264 --enable-libx264

对于aac库 要增加编译配置参数 --enable-encoder=libfdk_aac --enable-decoder=libfdk_aac --enable-libfdk-aac   --disable-encoder=aac(表示针对aac格式的音频,禁用ffmpeg默认的编码库 aac 采用libfdk-aac库进行编码)

对于lame库 要增加编译配置参数 --enable-libmp3lame

--extra-cflags="-I${PREFIX}/include" 表示引入第三方库(x264和aac以及lamp)的头文件路径

--extra-ldflags="-L${PREFIX}/lib" 表示引入第三方库(libx264.a和 libfdk-aac.a 以及 libmp3lame.a)的路径

#!/bin/bash
set -x
export NDK=/opt/software/android-ndk-r14b
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
export PLATFORM=$NDK/platforms/android-19/arch-arm
export CPU=armv7-a
export PREFIX=/home/xpzhi/ffmpeg-4.1.3/install
#路径必须要存在
#export TMPDIR=/home/temp

build_one(){
  ./configure --target-os=linux --prefix=$PREFIX  --enable-cross-compile  --enable-runtime-cpudetect  --disable-asm  --arch=arm  --cc=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi-gcc  --cross-prefix=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi-  --disable-stripping  --nm=$PREBUILT/linux-x86_64/bin/arm-linux-androideabi-nm  --sysroot=$PLATFORM  --enable-gpl --enable-libmp3lame --disable-shared --enable-static --enable-nonfree --enable-version3 --enable-small --disable-iconv  --disable-encoders  --disable-muxers --enable-muxer=mov --enable-muxer=ipod --enable-muxer=psp --enable-muxer=mp4 --enable-muxer=avi  --disable-decoders --enable-encoder=libx264 --enable-libx264 --enable-encoder=libfdk_aac --enable-decoder=libfdk_aac --enable-libfdk-aac --disable-decoder=aac --enable-decoder=aac_latm --enable-decoder=h264 --enable-decoder=mpeg4  --disable-demuxers --enable-demuxer=h264 --enable-demuxer=avi --enable-demuxer=mpc --enable-demuxer=mov  --disable-parsers --enable-parser=aac --enable-parser=ac3 --enable-parser=h264  --disable-protocols --enable-protocol=file  --disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb  --disable-indevs --enable-zlib  --disable-outdevs --disable-ffprobe --disable-ffplay --disable-ffmpeg --disable-debug  --extra-cflags="-I${PREFIX}/include"  --extra-ldflags="-L${PREFIX}/lib -dynamic-linker=/system/bin/linker -lm -llog -lc"
}
build_one
make
make install

最后将前面几步编译出来的静态库编译为一个libffmpeg.so动态库:

就是将ffmpeg的静态库 libavcodec.a libavfilter.a libswresample.a libavformat.a libavutil.a libswscale.a libpostproc.a libavdevice.a 和 libx264.a libfdk-aac.a libmp3lame.a等第三方库 打包成为一个,注意保证这些库能找到(最好自己命令验证下这些路径),最终的库的路径是 /home/xpzhi/ffmpeg-4.1.3/install/libffmpeg.so (库的名字可以随意更改)

#!/bin/bash
set -x
export NDK=/opt/software/android-ndk-r14b
export PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
export PLATFORM=$NDK/platforms/android-19/arch-arm
export CPU=armv7-a
export PREFIX=/home/xpzhi/ffmpeg-4.1.3/install

$PREBUILT/linux-x86_64/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -L$PREFIX/lib -soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg.so libavcodec/libavcodec.a libavfilter/libavfilter.a libswresample/libswresample.a libavformat/libavformat.a libavutil/libavutil.a libswscale/libswscale.a libpostproc/libpostproc.a libavdevice/libavdevice.a ${PREFIX}/lib/libx264.a ${PREFIX}/lib/libfdk-aac.a ${PREFIX}/lib/libmp3lame.a -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker $PREBUILT/linux-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/armv7-a/libgcc.a

=====================更新编译和开发过程中遇到的坑=======================

 

1.libavcodec.a(mpegvideodata.o): error adding symbols: File in wrong format

这个错误是在生成64位动态库的时候出现的,32位的库其实我已经生成成功了,然后为了获得更好的兼容性,我是想再生成一遍64位的库,但是却忘记清理编译的临时文件了--,忘记了 make clean命令,因为在编译过程中会产生很多临时文件如XXX.s XXX.o等,编译64位的动态库却使用32位的临时文件自然就会报格式错误,这里再附带上检查临时文件的到底是32位还是64的方法 可以通过命令 objdump -p libavcodec.a ;要注意编译新的架构平台的库时注意make clean 清理 临时文件

参考博客:https://blog.csdn.net/nxstack/article/details/77926447

 

2.libavformat/udp.c: In function 'udp_set_multicast_sources':
libavformat/udp.c:290:28: error: request for member 's_addr' in something not a structure or union
mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;

遇到这种编译错误的概率蛮大的,网上一般都说是NDK的版本问题,个人感觉不像,因此参考下面的博客修改了下源码再编译就通过了~

参考博客:https://blog.csdn.net/nxstack/article/details/77926447

 

3.将编译出来的库移植到Android平台后,进行音视频的编解码,发现编解码的速度特别的慢

后来咨询了下专业多媒体的同事才发现,可以开启硬解码,仅使用FFmpeg编解码是属于软解码,Android设备的CPU本身就具有解码功能,这里附带上编译ffmpeg开启硬解码的相关参数:

--enable-jni --enable-mediacodec --enable-decoder=h264_mediacodec --enable-hwaccels --enable-decoder=hevc_mediacodec --enable-decoder=mpeg4_mediacodec --enable-decoder=vp8_mediacodec --enable-decoder=vp9_mediacodec --enable-version3   另外  --target-os=android  目标平台选择Android 不能再是Linux  网上资料据说3.1版本以后才支持h264的硬解码,4.0+又不支持了,还是说参数设置的有问题?请遇到的童靴们帮忙指点下!

ffmpeg3.1版本硬解码的实现:https://blog.csdn.net/lakebobo/article/details/79619584

实现硬解码的方法:https://blog.csdn.net/zhangpengzp/article/details/88943867

软解码和硬解码的区别:https://blog.csdn.net/u010072711/article/details/52413766

ffmpeg-4.1.3版本硬解码H264编码的MP4视频文件时 ,硬解码几帧视频后出现   avcodec_send_packet(pCodecCtx, &packet)  返回 -11 的错误 ,但是该版本的软解码又是正常的!目前没有找到解决办法

 

4.集成aac和mp3的库时报错  ERROR: libfdk_aac not found和ERROR: libmp3lame >= 3.98.3 not dound

这是间隔一年后再次编译ffmpeg-4.1.6和ffmpeg-4.0.6版本(ffmpeg-4.1.3版本无法下载了)时遇到的错误,目前没有找到解决办法

 

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值