近期项目需要解析苹果的HLS流媒体协议,而FFmpeg从0.11.1“Happiness”版本开始,才增加了对HLS协议的支持。目前网上关于FFmpeg编译移植的文章有很多,但大多都是对旧版本的说明。新版本的源码对很多地方做了改动,包括一些变量名、常量名、函数名、函数参数、结构体等,所以在用旧版本的JNI接口时,需要相应地做出改动。这个编译移植工作确实花了本人不少时间,现在总结一下,希望能给到大家一些帮助。说明一点,本文阐述的不一定都正确,大家在编译过程中,难免会遇到各种各样的错误,可以提出来,一起讨论。
编译环境:Ubuntu 12.04、Android NDK r8
一、下载源码、新建工程
下载地址:http://ffmpeg.org/download.html ,下载最新ffmpeg-0.11.1压缩包。
在$NDK_HOME/samples/目录下(我的是/root/Develop/android-ndk-r8/samples/)创建一个FFMPEG-0.11目录,在里面新建一个jni目录,然后把ffmpeg源码解压放在jni里面,源码的文件夹重命名为libffmpeg,所以最后源码的路径是:
二、配置源代码
1. 创建config_common.sh脚本
在jni目录下创建一个config_common.sh,内容如下:
#!/bin/bash FFCONFIG_COMMON=' --enable-version3 --disable-gpl --disable-nonfree --disable-debug --disable-ffmpeg --disable-ffplay --disable-ffserver --disable-ffprobe --disable-encoders --disable-muxers --disable-devices --disable-protocols --enable-protocol=file --disable-swscale --disable-avfilter --enable-network --disable-avdevice --enable-parsers --disable-decoders --disable-demuxers --enable-demuxer=matroska --disable-demuxer=rm --disable-demuxer=avi --disable-demuxer=flv --disable-demuxer=mov --enable-demuxer=mp3 --enable-demuxer=mpegps --enable-demuxer=mpegvideo --enable-demuxer=asf --enable-decoder=aac --enable-decoder=ac3 --enable-decoder=dca --enable-decoder=flv --disable-decoder=h263 --disable-decoder=h264 --enable-decoder=svq3 --enable-decoder=amrnb --enable-decoder=nellymoser --enable-decoder=pcm_alaw --enable-decoder=pcm_dvd --enable-decoder=pcm_mulaw --enable-decoder=pcm_s16be --enable-decoder=pcm_s16le --enable-decoder=pcm_s16le_planar --enable-decoder=pcm_s24be --enable-decoder=pcm_s24daud --enable-decoder=pcm_s24le --enable-decoder=pcm_s32be --enable-decoder=pcm_s32le --enable-decoder=pcm_s8 --enable-decoder=pcm_u16be --enable-decoder=pcm_u16le --enable-decoder=pcm_u24be --enable-decoder=pcm_u24le --enable-decoder=pcm_u32be --enable-decoder=pcm_u32le --enable-decoder=atrac3 --enable-decoder=pcm_u8 --enable-decoder=sipr --enable-decoder=mjpeg --enable-decoder=mp1 --enable-decoder=mp2 --enable-decoder=mp3 --enable-decoder=tscc --enable-decoder=mpeg1video --enable-decoder=mpeg2video --enable-decoder=mpeg4 --enable-decoder=ra_144 --enable-decoder=ra_288 --enable-decoder=cook --enable-decoder=rv10 --enable-decoder=rv20 --enable-decoder=rv30 --enable-decoder=rv40 --enable-decoder=wmav1 --enable-decoder=wmav2 --enable-decoder=wmapro --disable-decoder=wmv1 --disable-decoder=wmv2 --disable-decoder=wmv3 --enable-decoder=vc1 --enable-decoder=msmpeg4v1 --enable-decoder=msmpeg4v2 --enable-decoder=msmpeg4v3 '
可以根据需要自行配置以上参数。
2. 创建config.sh脚本
在jni目录下创建一个config.sh,内容如下:
#!/bin/bash source config_common.sh /*这里执行上面的config_common.sh脚本*/ cd libffmpeg /*进入libffmpeg目录*/ PREBUILT=/root/Develop/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86 PLATFORM=/root/Develop/android-ndk-r8/platforms/android-14/arch-arm ./configure --target-os=linux \ --arch=arm \ --enable-shared \ --enable-cross-compile \ --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \ --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \ --strip=$PREBUILT/bin/arm-linux-androideabi-strip \ --extra-cflags="-fPIC -DANDROID" \ --extra-ldflags="-Wl,-T,$PREBUILT/arm-linux-androideabi/lib/ldscripts/armelf_linux_eabi.x -Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/crtbegin.o $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/crtend.o -lc -lm -ldl" \ $FFCONFIG_COMMON cd .. /*返回jni目录*/ ndk-build clean
3. 执行config.sh脚本
然后打开终端,执行以下命令:
如果配置正确的话,显示出来的最后两行是这样的:
若出现WARNING:/root/Develop/android-ndk-8/.............../arm-linux-androideabi-pkg-config not found, library detection may fail. 可忽略。
4. 修改config.h
进入jni/libffmpeg/目录,在刚刚生成的config.h中找到这句:
因为Android的gcc并不认得restrict这个关键字,所以把它改写成:
如果需要联网的话,还需要将config.h中的以下定义置为1:
相应的,config.mak中也需要修改为:
5. 修改libm.h文件
将/libavutil/libm.h中所有的static函数全部注释掉。
6. 修改Makefile文件
分別修改libavcodec、libavfilter、libavformat、libavutil、libpostproc和libswscale目录下的Makefile文件,将下面一句注释掉:
7. 新建av.mk脚本
在/jni/libffmpeg下建立一个脚本文件av.mk,內容如下:
8. 新建Android.mk脚本
在jni目录下新建Android.mk,內容如下:
在jni/libffmpeg目录下新建Android.mk:
在jni/libffmpeg/libavformat目录下新建Android.mk:
在jni/libffmpeg/libavcodec目录下新建Android.mk:
在libavfilter、libavutil、libpostproc和libswscale目录下都分別新建Android.mk:
9. 新建Application.mk脚本
在jni目录下创建一个Application.mk,内容如下:
三、 NDK编译
在FFMPEG-0.11/下执行ndk-build:
编译过程需要十分钟左右,最后会在FFMPEG-0.11/obj/local/armeabi/目录下生成libavcodec.a、libavformat.a、libavutil.a、libffmpeg.a、libswscale.a和libpostproc.a以及libexport.so,在FFMPEG-0.11/libs/armeabi/目录下生成libexport.so。