FFmpeg(四):CMake移植FFmpeg的靜態庫到AndroidStudio中

前言

本文將介紹如何把FFmpeg(二):Windows下編譯全平臺架構的FFmpeg中編譯出的支持全平臺的FFmpeg靜態so庫,采用CMake方式移植到AndroidStudio中,并打印出FFmpeg的信息。

正文

  • 1 相關文件拷貝

    • 1.1 添加FFmpeg編譯出的靜態庫

      FFmpeg(二):Windows下編譯全平臺架構的FFmpeg中我們將FFmpeg編譯生成了各個平臺適用的靜態庫,我們將每個CPU下的lib路徑下的所有so包提取出來,在Android工程中的libs下建立各個平臺對應的文件名稱,并拷貝進去,如圖所示:

    • 1.2 拷貝頭文件

      FFmpeg(二):Windows下編譯全平臺架構的FFmpeg中android_more下任意平臺下的include文件夾全部拷貝至項目工程中src/main/cpp中,如圖所示:

    • 1.3 拷貝H264頭文件

      在項目工程src/main/cpp/include下新建文件夾libx264,并把FFmpeg-3.2.5/libx264/android/任意CPU/include下編譯出的x264.h和x264_config.h拷貝進去

  • 2 編寫CMakeList.txt鏈接添加共享包

    看不懂第2步驟的請回頭FFmpeg(三):初識CMakeList和native-lib

    • 2.1 以CMakeList.txt為基準設置相對路徑
      set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../libs)
      
    • 2.2 加載頭文件和設置源碼路徑
      include_directories(
              # 加載頭文件
               src/main/cpp/include
              #源碼路徑為絕對路徑,下載后請記得修改你的源碼路徑
               E:/Workspace/OtherDemo/FFmpeg4Android-master/ffmpeg-3.2.5  ) 
      
    • 2.3 add_library添加共享庫

      我們把libavcodec.so、libavfilter.so、libavformat.so、libavutil.so、libfdk-aac.so、libswresample.so、libswscale.so這七個庫導入添加到共享庫(這里不關注CPU架構),IMPORTED指2.4中根據CPU架構導入指定的so庫。

      add_library(
         avcodec
         SHARED
         IMPORTED   )
      add_library(
         avfilter
         SHARED
         IMPORTED  )
      add_library(
         avformat
         SHARED
         IMPORTED  )
      add_library(
         avutil
         SHARED
         IMPORTED  )
      add_library(
         swresample
         SHARED
         IMPORTED  )
      add_library(
         swscale
         SHARED
         IMPORTED  )
      add_library(
         fdk-aac
         SHARED
         IMPORTED  )
      
      • 2.4 設置目標版本庫

      判斷當前機型是哪個CPU架構,就加載libs下對應的so包:

       #判斷目標版本并設置
       if(${ANDROID_ABI} STREQUAL "armeabi")
       set_target_properties(
         avcodec
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi/libavcodec.so
       )
       set_target_properties(
         avfilter
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi/libavfilter.so
       )
       set_target_properties(
         avformat
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi/libavformat.so
         )
      
       set_target_properties(
         avutil
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi/libavutil.so
         )
       set_target_properties(
         swresample
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi/libswresample.so
          )
       set_target_properties(
         swscale
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi/libswscale.so
          )
       set_target_properties(
         fdk-aac
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi/libfdk-aac.so
          )
       endif(${ANDROID_ABI} STREQUAL "armeabi")
      
       if(${ANDROID_ABI} STREQUAL "armeabi-v7a")
      
       set_target_properties(
         avcodec
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi-v7a/libavcodec.so
       )
      
       set_target_properties(
        avfilter
        PROPERTIES IMPORTED_LOCATION
        ../../../../libs/armeabi-v7a/libavfilter.so
        )
      
       set_target_properties(
         avformat
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi-v7a/libavformat.so
         )
      
       set_target_properties(
         avutil
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi-v7a/libavutil.so
         )
      
       set_target_properties(
         swresample
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi-v7a/libswresample.so
          )
      
       set_target_properties(
         swscale
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi-v7a/libswscale.so
          )
      
       set_target_properties(
         fdk-aac
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/armeabi-v7a/libfdk-aac.so
          )
       endif(${ANDROID_ABI} STREQUAL "armeabi-v7a")
      
       if(${ANDROID_ABI} STREQUAL "arm64-v8a")
       set_target_properties(
       avcodec
       PROPERTIES IMPORTED_LOCATION
       ../../../../libs/arm64-v8a/libavcodec.so
        )
      
       set_target_properties(
       avfilter
       PROPERTIES IMPORTED_LOCATION
       ../../../../libs/arm64-v8a/libavfilter.so
        )
      
       set_target_properties(
         avformat
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/arm64-v8a/libavformat.so
         )
      
       set_target_properties(
         avutil
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/arm64-v8a/libavutil.so
         )
      
       set_target_properties(
         swresample
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/arm64-v8a/libswresample.so
          )
      
       set_target_properties(
         swscale
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/arm64-v8a/libswscale.so
          )
      
      
       set_target_properties(
         fdk-aac
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/arm64-v8a/libfdk-aac.so
          )
       endif(${ANDROID_ABI} STREQUAL "arm64-v8a")
      
       if(${ANDROID_ABI} STREQUAL "x86")
       set_target_properties(
        avcodec
        PROPERTIES IMPORTED_LOCATION
        ../../../../libs/x86/libavcodec.so
       )
      
       set_target_properties(
         avfilter
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86/libavfilter.so
       )
      
       set_target_properties(
         avformat
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86/libavformat.so
         )
      
       set_target_properties(
         avutil
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86/libavutil.so
         )
      
       set_target_properties(
         swresample
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86/libswresample.so
          )
      
       set_target_properties(
         swscale
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86/libswscale.so
          )
      
       set_target_properties(
         fdk-aac
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86/libfdk-aac.so
          )
       endif(${ANDROID_ABI} STREQUAL "x86")
      
       if(${ANDROID_ABI} STREQUAL "x86_64")
       set_target_properties(
         avcodec
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86_64/libavcodec.so
       )
      
       set_target_properties(
        avfilter
        PROPERTIES IMPORTED_LOCATION
        ../../../../libs/x86_64/libavfilter.so
       )
      
       set_target_properties(
         avformat
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86_64/libavformat.so
         )
      
       set_target_properties(
         avutil
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86_64/libavutil.so
         )
      
       set_target_properties(
         swresample
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86_64/libswresample.so
          )
      
       set_target_properties(
         swscale
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86_64/libswscale.so
          )
      
       set_target_properties(
         fdk-aac
         PROPERTIES IMPORTED_LOCATION
         ../../../../libs/x86_64/libfdk-aac.so
          )
       endif(${ANDROID_ABI} STREQUAL "x86_64")
      
      • 2.5連接共享庫

      將所有添加進來的共享庫和NDK中查到到已有的庫鏈接起來:

       target_link_libraries(
                    native-lib
                    fdk-aac
                    avcodec
                    avfilter
                    avformat
                    avutil
                    swresample
                    swscale
                    ${log-lib}  )      
      
  • 3 相關代碼編寫

    • 3.1新建java文件FFmpegKit,內容如下:
    /**
     * Created by MouShao on 2018/2/28.
     */
    public class FFmpegKit {
    static {
      //加載CMakeList中連接的共享庫
      System.loadLibrary("native-lib");
      System.loadLibrary("avutil");
      System.loadLibrary("fdk-aac");
      System.loadLibrary("avcodec");
      System.loadLibrary("avformat");
      System.loadLibrary("swscale");
      System.loadLibrary("swresample");
      System.loadLibrary("avfilter");
      }
      public static native String stringFromFFmpeg();
    }
    
  • 3.2 native-lib.cpp編寫
    #include <jni.h>
    #include <string>
    #include <android/log.h>
    
    extern "C" {
    #include "libavcodec/avcodec.h"
    #include "libavfilter/avfilter.h"
    #include "libavformat/avformat.h"
    #include "libavutil/imgutils.h"
    #include "libswresample/swresample.h"
    #include "libswscale/swscale.h"
    #include "libx264/x264.h"
    
    #define  LOG_TAG    "videoplayer"
    #define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
    
    JNIEXPORT jstring JNICALL Java_com_pvirtech_ffmpeg4android_FFmpegKit_stringFromFFmpeg(
      JNIEnv *env,
      jobject /* this */ obj) {
          char info[10000] = {0};
          sprintf(info, "%s\n", avcodec_configuration());
          return env->NewStringUTF(info);
       }
    };
    
  • 3.3 app下build.gradle的配置
      android {
      ···
      defaultConfig {
      ···
      externalNativeBuild {
          cmake {
              //配置C++11標準
              cppFlags "-std=c++11"
          }
          ndk{
              //abi兼容設置
              abiFilters "armeabi-v7a","armeabi","arm64-v8a","x86","x86_64"
          }
      }
    }
        //導入app/libs下庫
        sourceSets.main {
        jniLibs.srcDirs = ['libs']
        jni.srcDirs = []
      }
    }
    
  • 3.4 MainActivity調用
  • 4 運行如圖所示:

結語

到此,FFmpeg的首秀就完成了,下一篇我們將如何用JNI動態注冊的方式調用FFmpeg播放視頻。

下一節講:
FFmpeg(五):JNI動態注冊方法調用FFmpeg播放視頻

github源碼

簡書半停更說明

碎碎念:如果諸君喜歡,請點個贊
更多問題,歡迎加群:584275290
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容