本次编译环境:MacOs操作系统,FFmpeg-3.3.4,x264,NDK:r15c
下载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
解压下载好的ndk.tar.gz至~/
terminal
subl ~/.bash_profile
NDK_HOME=~/android-ndk-r15c
export NDK_HOME
export PATH=${PATH}:$NDK_HOME/toolchains:$NDK_HOME
export PREBUILT=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt
export PLATFORM=$NDK_HOME/platforms/android-14/arch-arm
export TOOLCHAIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
# cpu 架构平台,若要编译 x86 则指定 x86
export CPU=armv7-a
编写脚本build_x264.sh
注:编者系统重定向 subl -> 打开sublime text
terminal
subl ~/FFmpeg/build_x264.sh
cd x264
export NDK=$NDK_HOME
#编译生成库路径
export PREFIX=../libx264
export 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 -j8
make install
cd ..
terminal
chmod +x ~/FFmpeg/build_x264.sh
sh ~/FFmpeg/build_x264.sh
该步骤结束后在FFmpeg文件夹下会生成一个libx264文件夹
terminal
subl ~/FFmpeg/FFmpeg-${version}/build.sh
#!/bin/bash
export 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_FLAG
sed -i '' 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.h
sed -i '' 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.h
sed -i '' 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.h
sed -i '' 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.h
sed -i '' 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.h
sed -i '' 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.h
sed -i '' 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.h
sed -i '' 's/HAVE_RINT 0/HAVE_RINT 1/g' config.h
make clean
make -j8
make 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 v7vfp
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
PREFIX=./android/$CPU-vfp
ADDITIONAL_CONFIGURE_FLAG=
build_one
terminal
chmod +x ~/FFmpeg/build.sh
sh ~/FFmpeg/build.sh
创建一个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_program
void 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'])
}
}
在sh build_x264.sh、sh build.sh、ndk-build三步中,一旦出现error代表着编译失败,应谨慎分析原因并排查,祝大家使用愉快