编译用于Android的FFmpeg&x264
本文介绍了在编译用于Android端的FFmpeg与x264库
本次编译环境:MacOs操作系统,FFmpeg-3.3.4,x264,NDK:r15c
0x00 资源准备
下载Android NDK : Google中国开发者网站
terminal
mkdir ~/FFmpeg
cd ~/FFmpeg
git clone http://git.videolan.org/git/x264.git
git clone https://git.ffmpeg.org/ffmpeg.git
0x01 配置NDK环境变量
解压下载好的ndk.tar.gz至~/
terminal
subl ~/.bash_profile
NDK_HOME=~/android-ndk-r15cexport NDK_HOMEexport PATH=${PATH}:$NDK_HOME/toolchains:$NDK_HOMEexport PREBUILT=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuiltexport PLATFORM=$NDK_HOME/platforms/android-14/arch-armexport TOOLCHAIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64# cpu 架构平台,若要编译 x86 则指定 x86export CPU=armv7-a
0x02 编译x264
编写脚本build_x264.sh
注:编者系统重定向 subl -> 打开sublime text
terminal
subl ~/FFmpeg/build_x264.sh
cd x264export NDK=$NDK_HOME#编译生成库路径export PREFIX=../libx264export SYSROOT=$TOOLCHAINS/arm/sysroot ./configure \ --prefix=$PREFIX \ --enable-static \ --enable-shared \ --enable-pic \ --disable-asm \ --disable-cli \ --host=arm-linux-androideabi \ --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \ --sysroot=$PLATFORM \ --disable-avs \ --disable-swscale \ --disable-lavf \ --disable-ffms \ --disable-gpac \ --disable-lsmash make -j8make installcd ..
terminal
chmod +x ~/FFmpeg/build_x264.sh
sh ~/FFmpeg/build_x264.sh
该步骤结束后在FFmpeg文件夹下会生成一个libx264文件夹
0x03 编译FFmpeg
terminal
subl ~/FFmpeg/FFmpeg-${version}/build.sh
#!/bin/bashexport TMPDIR=/Users/${uesr}/FFmpeg/ffmpeg-${version} #指向FFmpeg根目录function build_one{EXTRA_CFLAGS="-I./libx264/include"EXTRA_LDFLAGS="-L./libx264/lib"./configure \ --prefix=$PREFIX \ --target-os=android \ --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \ --disable-stripping \ --disable-asm \ --disable-doc \ --arch=arm \ --sysroot=$PLATFORM \ --extra-cflags="-I$PLATFORM/usr/include" \ --cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \ --nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \ --disable-shared \ --enable-runtime-cpudetect \ --enable-gpl \ --enable-small \ --enable-cross-compile \ --enable-static \ --enable-version3 \ --disable-vda \ --disable-iconv \ --disable-encoders \ --enable-libx264 \ --enable-encoder=libx264 \ --disable-muxers \ --enable-muxer=mov \ --enable-muxer=ipod \ --enable-muxer=psp \ --enable-muxer=mp4 \ --enable-muxer=avi \ --disable-decoders \ --enable-decoder=aac \ --enable-decoder=aac_latm \ --enable-decoder=h264 \ --enable-decoder=mpeg4 \ --disable-demuxers \ --enable-demuxer=h264 \ --enable-demuxer=mov \ --disable-parsers \ --enable-parser=aac \ --enable-parser=ac3 \ --enable-parser=h264 \ --disable-protocols \ --enable-protocol=file \ --enable-protocol=rtmp \ --disable-bsfs \ --enable-bsf=aac_adtstoasc \ --enable-bsf=h264_mp4toannexb \ --disable-indevs \ --enable-zlib \ --disable-outdevs \ --disable-ffprobe \ --disable-ffplay \ --disable-ffmpeg \ --disable-postproc \ --disable-avdevice \ --disable-symver \ --disable-ffserver \ --disable-debug \ --extra-cflags=$EXTRA_CFLAGS \ --extra-ldflags=$EXTRA_LDFLAGS $ADDITIONAL_CONFIGURE_FLAGsed -i '' 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.hsed -i '' 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.hsed -i '' 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.hsed -i '' 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.hsed -i '' 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.hsed -i '' 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.hsed -i '' 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.hsed -i '' 's/HAVE_RINT 0/HAVE_RINT 1/g' config.hmake cleanmake -j8make install$TOOLCHAIN/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 \ libx264/lib/libx264.a \ libavcodec/libavcodec.a \ libavfilter/libavfilter.a \ libswresample/libswresample.a \ libavformat/libavformat.a \ libavutil/libavutil.a \ libswscale/libswscale.a \ -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \ $TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a}# arm v7vfpCPU=armv7-aOPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "PREFIX=./android/$CPU-vfpADDITIONAL_CONFIGURE_FLAG=build_one
terminal
chmod +x ~/FFmpeg/build.sh
sh ~/FFmpeg/build.sh
0x04 Android工程
创建一个Android工程
在app/src/main下创建文件夹jni
复制文件 ~/FFmpeg下的android/arm…/libffmpeg.so到jni/
复制文件 ffmpeg.c ffmpeg.h ffmpeg_filter.c cmdutils.c cmdutils.h cmdutils_common_opt.c ffmpeg_opt.c 到jni/
修改文件:ffmpeg.c
int main(int argc,char **argv) //改变为int run(int argc,char **argv)//在函数 ffmpeg_cleanup 的最后添加ffmpeg_exited = 1;nb_filtergraphs = 0;nb_output_files = 0;nb_output_streams = 0;nb_input_files = 0;nb_input_streams = 0;
修改文件:ffmpeg.h
//在定义函数的末添加int run(int argc,char **argv);
修改文件cmdutils.c
//函数exit_programvoid exit_program(int ret){ if(program_exit){ program_exit(ret) } exit(ret);}//改变为void exit_program(int ret){ if(program_exit){ program_exit(ret) }}
创建一个调用类如:FFmpegUtil.java
并在类中声明原生方法
private static native int run(String[] recommend);
此处打开AndroidStudio中的终端
terminal
cd app/src/main/java
// javah ${包名}.FFmpegUtil
如:javah com.exmaple.ffmpegsimple.FFmpegUtil
会在app/src/main/java目录下生成c头文件,将其移动到jni/
创建文件${刚才创建的头文件}.c
编写该文件
#include "com.example.ffmpegsimple.h"#include "ffmpeg.h"#include /* * Class: com_example_ffmpegsimple_FFmpegUtil * Method: run * Signature: (Ljava/lang/String;)I */JNIEXPORT jint JNICALL Java_com_example_ffmpegsimple_FFmpegUtil_run(JNIEnv *env, jclass obj, jobjectArray commands) { int argc = (*env)->GetArrayLength(env, commands); char *argv[argc]; int i; for (i = 0; i < argc; i++) { jstring js = (jstring) (*env)->GetObjectArrayElement(env, commands, i); argv[i] = (char*) (*env)->GetStringUTFChars(env, js, 0); } return run(argc, argv);}
terminal
cd app/src/main/jni
ndk-build
等待执行完成
会在app/src/main下生成两个文件夹
编写app的build.gradle
sourceSets{ main{ jniLibs.srcDir(['src/main/libs']) } }
0x05 最后说两句
在sh build_x264.sh、sh build.sh、ndk-build三步中,一旦出现error代表着编译失败,应谨慎分析原因并排查,祝大家使用愉快
更多相关文章
- android地图定位
- Android—— 4.2 Vold挂载管理_主体构建main (一)
- Android预安装软件&adb命令&编译源码
- Android国际化资源 文件夹命名规范
- Android系统权限和root权限大全
- android 五种存储
- ANDROID AIDL
- Android中设置中文粗体的方法
- NPM 和webpack 的基础使用