Cross compile FFmpeg on MacOS for Android
1. Prepare FFmpeg and Android NDK FFmpeg
1 2 3 4 5 6 7 8 // 1. Download FFMpeg (4.2.2 for this tutotial) https://ffmpeg.org/releases/ // 2. unzip tar -jxvf ffmpeg-4.2.2.tar.bz2 // 3. configure ./configure --disable-x86asm 
Android NDK
1 https://developer.android.google.cn/ndk/downloads 
2. Build In the unzipped folder ffmpeg-4.2.2, create a new shell script build_android.sh.
build_android.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #!/bin/sh NDK=~/Library/Android/sdk/ndk/26.1.10909125 ARCH=aarch64 CPU=arm64-v8a API=21 OUTPUT=$(pwd )/android/$CPU  TOOLCHAIN=$NDK /toolchains/llvm/prebuilt/darwin-x86_64 SYSROOT_L=$TOOLCHAIN /sysroot/usr/lib/aarch64-linux-android GCC_L=$NDK /toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/lib/gcc/aarch64-linux-android/4.9.x build_arm64     echo  "\033[32m Compiling FFmpeg for $CPU  \033[0m"    ./configure \   --target-os=android \   --prefix=$OUTPUT  \   --arch =$ARCH  \   --sysroot=$TOOLCHAIN /sysroot \   --enable-neon  \   --enable-hwaccels  \   --enable-gpl   \   --disable-postproc \   --disable-debug \   --enable-small \   --enable-jni \   --enable-mediacodec \   --enable-decoder=h264_mediacodec \   --enable-static \   --enable-shared \   --disable-doc \   --enable-ffmpeg \   --disable-ffplay \   --disable-ffprobe \   --disable-avdevice \   --disable-doc \   --disable-symver \   --enable-cross-compile \   --cross-prefix=$TOOLCHAIN /bin/aarch64-linux-android- \   --cc=$TOOLCHAIN /bin/aarch64-linux-android$API -clang \   --cxx=$TOOLCHAIN /bin/aarch64-linux-android$API -clang++ \   --extra-cflags="-fpic -I$OUTPUT /include"  \   --extra-ldflags="-lc -ldl -lm -lz -llog -lgcc -L$OUTPUT /lib"    make clean all   make -j8   make install   echo  "\033[32m The Compilation of FFmpeg for $CPU  is completed \033[0m"  } build_arm64 
To build
1 2 chmod +x build_android.sh ./build_android.sh 
After successful build, we will have needed libs and headers under android/arm64-v8a
    
    
3. Test FFmpeg on Android Build a simple demo in Android studio to test if FFmpeg works.
    
We place the ffmpeg headers under cpp/include and all the libraries under jniLibs/arm64-v8a.
Java client code
MainActivity.java 1 2 3 4 5 6 7 8 9 10 public  class  MainActivity  extends  AppCompatActivity  {    @Override      protected  void  onCreate (Bundle savedInstanceState)  {         super .onCreate(savedInstanceState);         EdgeToEdge.enable(this );         setContentView(R.layout.activity_main);         ((TextView)findViewById(R.id.text_view)).setText(FFmpegPlay.getFFmpegVersion());     } } 
FFmpegplay.java 1 2 3 4 5 6 7 8 9 10 11 public  class  FFmpegPlay  {    static  {         System.loadLibrary("ffmpegtest" );     }     public  static  String getFFmpegVersion ()  {         return  nativeGetFFmpegVersion();     }     private  static  native  String nativeGetFFmpegVersion () ; } 
Native code
ffmpegtest.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include  <jni.h>  #include  <cstring>  #include  "util/log.h"  extern  "C"  {#include  <libavcodec/version.h>  #include  <libavcodec/avcodec.h>  #include  <libavformat/version.h>  #include  <libavutil/version.h>  #include  <libavfilter/version.h>  #include  <libswresample/version.h>  #include  <libswscale/version.h>  } extern  "C" JNIEXPORT jstring JNICALL Java_com_example_ffmpegtest_FFmpegPlay_nativeGetFFmpegVersion (JNIEnv *env, jclass clazz)      char  strBuffer[1024  * 4 ] = {0 };     strcat (strBuffer, "libavcodec : " );     strcat (strBuffer, AV_STRINGIFY (LIBAVCODEC_VERSION));     strcat (strBuffer, "\nlibavformat : " );     strcat (strBuffer, AV_STRINGIFY (LIBAVFORMAT_VERSION));     strcat (strBuffer, "\nlibavutil : " );     strcat (strBuffer, AV_STRINGIFY (LIBAVUTIL_VERSION));     strcat (strBuffer, "\nlibavfilter : " );     strcat (strBuffer, AV_STRINGIFY (LIBAVFILTER_VERSION));     strcat (strBuffer, "\nlibswresample : " );     strcat (strBuffer, AV_STRINGIFY (LIBSWRESAMPLE_VERSION));     strcat (strBuffer, "\nlibswscale : " );     strcat (strBuffer, AV_STRINGIFY (LIBSWSCALE_VERSION));     strcat (strBuffer, "\navcodec_configure : \n" );     strcat (strBuffer, avcodec_configuration ());     strcat (strBuffer, "\navcodec_license : " );     strcat (strBuffer, avcodec_license ());     LOGCATE ("GetFFmpegVersion\n%s" , strBuffer);     return  env->NewStringUTF (strBuffer); } 
CMakeLists.txt 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 cmake_minimum_required (VERSION 3.4 .1 )set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11" )set (jnilibs ${CMAKE_SOURCE_DIR} /../jniLibs)set (libname ffmpegtest)include_directories (        ${CMAKE_SOURCE_DIR} /include          ${CMAKE_SOURCE_DIR} /util ) link_directories (        ${jnilibs} /${ANDROID_ABI} ) file (GLOB src-files        ${CMAKE_SOURCE_DIR} /*.cpp) add_library (        ${libname}          SHARED         ${src-files}  ) set (third-party-libs        avformat         avcodec         avfilter         swresample         swscale         avutil ) set (native-libs        android         mediandk         EGL         GLESv3         OpenSLES         log         m         z ) target_link_libraries (        ${libname}          ${log-lib}          ${third-party-libs}          ${native-libs}  ) 
Result