Android Studio 整合FFmpeg
先看效果圖

arm-v7a
我用的是FFmpeg4.02的版本,目前編譯出arm-v7a 和x86CPU架構的so檔案,如果需要可以編譯出全部平臺,不過目前移動端的已經足夠了。需要用到的有標頭檔案和對應架構的so檔案。
首先得先弄懂CMake檔案的使用,如果不是理解的話,可以去官網檢視用法(地址: ofollow,noindex">https://developer.android.com/studio/projects/add-native-code )
CMake檔案具體的描述
指定cmake的版本
cmake_minimum_required(VERSION 3.4.1)
可以把生成的so檔案指定到某個目錄下
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
生成so檔案(注意:一個CMake檔案只能生成一個so檔案,如果想生成多個so檔案,後期會寫出來怎麼做=。=!),這裡最好是跟對接的c檔案的名稱一樣,需要指定需要哪些需要參與的cpp檔案(如果你想增加附加c檔案的話,需要繼續增加引用就行);SHARED表示生成的庫的動態連結
add_library( # Sets the name of the library. zplay-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). ${CMAKE_SOURCE_DIR}/src/main/cpp/zplay-lib.cpp)
把對應的so檔案引入進來,set_target_properties:是設定對應的路徑
# 編解碼 add_library(libavcodec SHARED IMPORTED) set_target_properties(libavcodec PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec.so) # 和多媒體裝置互動的類庫 add_library(libavdevice SHARED IMPORTED) set_target_properties(libavdevice PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavdevice.so) # 影象的pixel format處理 add_library(libavfilter SHARED IMPORTED) set_target_properties(libavfilter PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavfilter.so) # 格式 add_library(libavformat SHARED IMPORTED) set_target_properties(libavformat PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavformat.so) # 工具函式 add_library(libavutil SHARED IMPORTED) set_target_properties(libavutil PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavutil.so) # 音訊重取樣,取樣格式轉換和混合庫 add_library(libswresample SHARED IMPORTED) set_target_properties(libswresample PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswresample.so) # 縮放處理 add_library(libswscale SHARED IMPORTED) set_target_properties(libswscale PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswscale.so)
再把標頭檔案的路徑也引進來
include_directories( ${CMAKE_SOURCE_DIR}/src/main/cpp/include/${ANDROID_ABI} )
最後再把這些資源全部關聯起來
target_link_libraries( # Specifies the target library. zplay-lib # Links the target library to the log library # included in the NDK. ${log-lib} libavcodec libavdevice libavfilter libavformat libavutil libswresample libswscale)
這是CMake檔案全部的程式碼
# For more information about using CMake with Android+Studio/">Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}) # Specifies a library name, specifies whether the library is STATIC or # SHARED, and provides relative paths to the source code. You can # define multiple libraries by adding multiple add.library() commands, # and CMake builds them for you. When you build your app, Gradle # automatically packages shared libraries with your APK. add_library( # Sets the name of the library. zplay-lib # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). ${CMAKE_SOURCE_DIR}/src/main/cpp/zplay-lib.cpp ${CMAKE_SOURCE_DIR}/src/main/cpp/pcm/ZPcm2wav.cpp) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # Specifies the target library. zplay-lib # Links the target library to the log library # included in the NDK. ${log-lib} libavcodec libavdevice libavfilter libavformat libavutil libswresample libswscale) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log) include_directories( ${CMAKE_SOURCE_DIR}/src/main/cpp/include/${ANDROID_ABI} ) # 編解碼 add_library(libavcodec SHARED IMPORTED) set_target_properties(libavcodec PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec.so) # 和多媒體裝置互動的類庫 add_library(libavdevice SHARED IMPORTED) set_target_properties(libavdevice PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavdevice.so) # 影象的pixel format處理 add_library(libavfilter SHARED IMPORTED) set_target_properties(libavfilter PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavfilter.so) # 格式 add_library(libavformat SHARED IMPORTED) set_target_properties(libavformat PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavformat.so) # 工具函式 add_library(libavutil SHARED IMPORTED) set_target_properties(libavutil PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavutil.so) # 音訊重取樣,取樣格式轉換和混合庫 add_library(libswresample SHARED IMPORTED) set_target_properties(libswresample PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswresample.so) # 縮放處理 add_library(libswscale SHARED IMPORTED) set_target_properties(libswscale PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswscale.so)
再看下build.gradle檔案的相關配置
如果你是在非app module裡面的就需要增加
defaultConfig { ndk { abiFilters 'armeabi-v7a','x86' } } packagingOptions { pickFirst 'lib/armeabi-v7a/libzplay-lib.so' pickFirst 'lib/x86/libzplay-lib.so' }
最後顯示FFmpeg的配置資訊作為編譯成功的驗證
JNIEXPORT jstring JNICALL Java_com_zasko_ffmpeg_RenderManager_getConfig(JNIEnv *env, jclass type) { char info[10000] = {0}; sprintf(info, "%s\n", avcodec_configuration()); return env->NewStringUTF(info); }