本文介绍了在编译用于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代表着编译失败,应谨慎分析原因并排查,祝大家使用愉快

更多相关文章

  1. Android国际化资源 文件夹命名规范
  2. Android安装apk文件并适配Android 7.0详解
  3. Android 列表数据写入到本地Excel文件(包括图片)
  4. linux 配置安装android sdk自动下载缺少文件
  5. Android在MTP模式下,只显示指定文件夹
  6. android 使用html5作布局文件: webview跟javascript交互
  7. Android - Manifest 文件 详解
  8. android 下写文件性能测试

随机推荐

  1. Android自定义控件之自定义属性解析
  2. Android(安卓)优雅地退出App
  3. Android(安卓)软件盘不自动弹出解决办
  4. android(NDK+JNI)---JNI数据类型
  5. Flutter踩坑记录
  6. Android适配概要
  7. hello-world.html
  8. android 打包时报错解决
  9. Android类似朋友圈评论视图Dialog实现
  10. Binder驱动之Buffer Size