在Android下编译ffmpeg+x264+libfdk-aac的常见问题和解决方法
来源:互联网 发布:黄岩深孔钻编程招聘 编辑:程序博客网 时间:2024/06/05 00:08
搞多媒体开发的对ffmpeg、libfdk-aac、x264这几个库应该都比较熟悉,在此不多做介绍。最近公司需要升级多媒体库,第一步工作就是将ffmpeg+x264+libfdk-aac移植到Android平台。关于ffmpeg+libfdk-aac+x264的交叉编译步骤,网上相关的内容很多。不过由于ffmpeg的配置选项丰富,在网上查到的脚本几乎都不符合我们的需求,了解ffmpeg的编译过程后自己写了个脚本,进行简单修改后就可以对不同的CPU架构和Android API level生成不同的二进制文件。去掉公司的业务代码后,我把编译脚本和相应的开源库放到了github上,欢迎大家前去围观。github地址:https://github.com/x5miao/ffmpeg-android
和交叉编译相关的脚本主要包括项目目录下的set-build.sh,ffmpeg/config-android.sh, x264/config-android.sh, libfdk-aac/config-android.sh。set-build.sh主要用来设置环境变量,以及根据命令行启动不同组件的configure和编译过程。几个config-android.sh主要就是调用开源库里自带的configure脚本进行配置生成makefile文件,然后调用make生成静态库文件。
最重要的脚本就是set-build.sh,其主要内容如下所示:
#!/bin/bash#本脚本用于设置交叉编译环境并编译libmedia各子模块,用户请根据自身的编译环境修改#相应的环境变量.#libmedia的编译仅在ubuntu下测试通过,推荐使用ubuntu14.04-64TLS.#注意:不要使用cygwin编译,否则可能出现无法编译的bug.#set -xLIBMEDIA_TARGET_PLATFORM=android-22LIBMEDIA_TARGET_ARCH_ABI=arm64-v8a #armeabi-v7a armeabi#NDK_ROOT_PATH指向Android NDK开发包的根路径NDK_ROOT_PATH=/home/xxm/android_dev/android-ndk-r13b#TOOLCHAIN版本号,请参考${NDK_ROOT_PATH}/toolchains目录下的文件夹名字修改TOOLCHAIN_VERSION=4.9#TMPDIR用来指定ffmpeg编译过程中间生成文件的保存目录,编译时请根据用户自己的本地环境指定,#编译前必须保证该temp文件夹存在FFMPEG_TMPDIR=/home/xxm/android_dev/workspace/tmpexport LIBMEDIA_TARGET_PLATFORM LIBMEDIA_TARGET_ARCH_ABI FFMPEG_TMPDIR NDK_ROOT_PATH TOOLCHAIN_VERSION#编译ffmpeg需要按照Android开发者论团的介绍先建立离线交叉编译工具链#参考网址:https://developer.android.com/ndk/guides/standalone_toolchain.html#wwc#STANDLONE_ROOT_PATH=/home/xxm/android_dev/workspace/arm-linux-androideabi#export STANDLONE_ROOT_PATH#set +xprint_helpmsg(){echo "usage:source set-env.sh [option]" echo "option is:"printf "\t all: rebuild all opensource library and interface files(GGCodec*.c)\n"printf "\t x264: rebuild x264 and interface files\n"printf "\t libfdk-aac: rebuild libfdk-aac and interface files\n"printf "\t ffmpeg: rebuild ffmpeg and interface files\n"printf "\t help: print this message\n\n"}build_x264(){ cd x264 && ./config-android.sh && cd ..}build_libfdk-aac(){ cd libfdk-aac && ./config-android.sh && cd ..}build_ffmpeg(){ cd ffmpeg && ./config-android.sh $1 && cd ..}build_module(){ cp out/Android.mk out/${LIBMEDIA_TARGET_ARCH_ABI}/ ndk-build clean && ndk-build all}build(){if test "$1" = "all"; then build_x264 && build_libfdk-aac && build_ffmpeg 2elif test "$1" = "x264"; then build_x264 && build_ffmpeg 2elif test "$1" = "libfdk-aac"; then build_libfdk-aac && build_ffmpeg 2elif test "$1" = "ffmpeg"; then build_ffmpeg 2elif test "$1" = "help"; then print_helpmsg && eixt 0else printf "no option, just rebuild interface files\n\n" && print_helpmsgfiif test $? -eq 0;then build_modulefi}build "$@"
set-build.sh通过如下方式调用:
source set-build.sh [all|ffmpeg|x264|libfdk-aac|help] all: 所有组件都重新构建; ffmpeg:重新构建ffmpeg的静态库; x264:重新构建x264和ffmpeg; libfdk-aac:重新构建libfdk-aac和ffmpeg; help:打印command的帮助信息。
如果需要修改目标平台的ABI和Platform,请修改LIBMEDIA_TARGET_ARCH_ABI和LIBMEDIA_TARGET_PLATFORM两个环境变量,修改这两个变量中任何一个之后必须重新用all选项重新编译所有组件。
交叉编译的时候遇到一些坑,分享出来希望对其他人有所帮助。
(1) 编译ffmpeg时提示找不到libfdk-aac或libx264。这个问题是由于ffmpeg时交叉编译器找不到libfdk-aac/x264的头文件或静态库.a文件导致的。解决方法是将ffmpeg、libfdk-aac、libx264的--prefix选项赋值为相同的目录,并给configure脚本加上--extra-cflags=“-I${PREFIX}/include”和--extra-ldflags=“-L${PREFIX}/lib -lx264 -lfdk-aac”选项。编写脚本时注意libfdk-aac(小短线)和libfdk_aac(下划线)的区别,configure有时候需要是短线版本有时候又需要下划线版本,容易搞错。
(2) 编译了32位so文件后再编译64位so文件时,提示strtod.o的文件格式不对。这是由于对于3.2版本的ffmpeg,make clean不会删除compat下的strtod.o,strtod.d, msvcrt/snprintf.o, msvcrt/snprintf.d四个文件,只要手动删除后重新编译即可。具体可以参考简书上esonyf的这篇文章:http://www.jianshu.com/p/612ef67e42bd
(3) 调用avodec_find_decoder|encoder(AVCODEC_ID_AAC|AVCODEC_ID_H264)返回失败。造成这个问题的原因是虽然动态库里面包含了libfdk-aac和x264编解码相关的代码,却没有将其注册到ffmpeg。解决方法是configure时通过--enable-encoder=libx264|libfdk_aac选项显示启用libfdk-aac和libx264作为编解码器。
(4) configure时有时候会遇到‘C Compiler is not working’之类的错误,但是交叉编译器明显就在正确的路劲下。因为这个问题耽误了大半天的时间,后来通过分析config.log才发现当configure时如果指定了错误的编译链接选项,比如--arch指定了configure脚本不识别的体系架构、--extra-cflags里面指定了不支持的编译器选项,或者--extra-ldflags里有--nostdlib之类的选项,导致交叉编译器在测试生成可执行文件命令后返回了非0值, configure脚本就会打印出这个很有误导性的消息。对于ffmpeg可以通过分析configure的输出日志文件config.log来定位问题。不过x264的configure脚本生成的config.log里面却得不到任何线索,只能通过在其configure脚本开头添加set -x调试选项来跟踪configure脚本的执行来排查问题了。这也提醒我们,不管是写脚本或者程序文件是错误报告消息的重要性,不准确的日志消息太有误导性了。
- 在Android下编译ffmpeg+x264+libfdk-aac的常见问题和解决方法
- 编译Android下可用的FFmpeg(包含libx264与libfdk-aac)
- 编译Android下可用的全平台FFmpeg(包含libx264与libfdk-aac)
- <android编译ffmpeg+x264+faac> <Android/NDK环境下FFmpeg及AAC,MP3,X264的编译>
- ubuntu 14.10下安装带有libfdk-aac的ffmpeg
- iOS编译libx264+libfdk-aac+FFmpeg
- Android/NDK环境下FFmpeg及AAC,MP3,X264的编译
- Ubuntu下 Android NDK 编译 FFmpeg + x264 + fdk-aac (arm/x86)的配置脚本
- ffmpeg和x264在mingw下编译
- iOS ffmpeg + libfdk-aac
- 编译Android下可用的FFmpeg+x264
- 编译libfdk-aac 库,使用根目录下的android.mk直接包含所有子目录下的android.mk文件
- qt for android从编译ffmpeg x264 aac 到在qtcreator上使用
- 在CentOS中编译FFmpeg for Android静态库(含fdk aac,x264)
- 【编译脚本】macos下libfdk-aac三个ios平台最新的编译脚本i386 arm7 arm7s
- 在Ubuntu下FFmpeg编译,支持x264和x265。
- 在Ubuntu下FFmpeg编译,支持x264和x265。
- ios ffmpeg(libfdk-aac) aac encode
- php 怎么判断为顺子,三个相邻的数字
- UE4这些扰人的坑
- Java的io流的使用
- laravel5中使用七牛云存储、上传图片
- 02_计算机语言发展史
- 在Android下编译ffmpeg+x264+libfdk-aac的常见问题和解决方法
- 达克效应
- 简单对称加解密(一)
- 归并排序
- 学生学籍管理系统~~登录界面(Java、SQL)
- 编写高质量代码:改善JavaScript程序建议--面向对象编程
- Activity
- Java基础知识点(常量 变量)
- Java压缩、解压zip文件(依赖第三方类库zip4j_1.3.1.jar)