前言
本文將介紹如何把FFmpeg(二):Windows下編譯全平臺(tái)架構(gòu)的FFmpeg中編譯出的支持全平臺(tái)的FFmpeg靜態(tài)so庫(kù),采用CMake方式移植到AndroidStudio中者娱,并打印出FFmpeg的信息请敦。
正文
-
1 相關(guān)文件拷貝
-
1.1 添加FFmpeg編譯出的靜態(tài)庫(kù)
在 FFmpeg(二):Windows下編譯全平臺(tái)架構(gòu)的FFmpeg中我們將FFmpeg編譯生成了各個(gè)平臺(tái)適用的靜態(tài)庫(kù)空执,我們將每個(gè)CPU下的lib路徑下的所有so包提取出來(lái),在Android工程中的libs下建立各個(gè)平臺(tái)對(duì)應(yīng)的文件名稱,并拷貝進(jìn)去嘀韧,如圖所示:
-
1.2 拷貝頭文件
將 FFmpeg(二):Windows下編譯全平臺(tái)架構(gòu)的FFmpeg中android_more下任意平臺(tái)下的include文件夾全部拷貝至項(xiàng)目工程中src/main/cpp中,如圖所示:
-
1.3 拷貝H264頭文件
在項(xiàng)目工程src/main/cpp/include下新建文件夾libx264棍矛,并把FFmpeg-3.2.5/libx264/android/任意CPU/include下編譯出的x264.h和x264_config.h拷貝進(jìn)去
-
-
2 編寫(xiě)CMakeList.txt鏈接添加共享包
看不懂第2步驟的請(qǐng)回頭FFmpeg(三):初識(shí)CMakeList和native-lib
-
2.1 以CMakeList.txt為基準(zhǔn)設(shè)置相對(duì)路徑
set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../libs)
-
2.2 加載頭文件和設(shè)置源碼路徑
include_directories( # 加載頭文件 src/main/cpp/include #源碼路徑為絕對(duì)路徑安疗,下載后請(qǐng)記得修改你的源碼路徑 E:/Workspace/OtherDemo/FFmpeg4Android-master/ffmpeg-3.2.5 )
-
2.3 add_library添加共享庫(kù)
我們把libavcodec.so、libavfilter.so够委、libavformat.so荐类、libavutil.so、libfdk-aac.so茁帽、libswresample.so玉罐、libswscale.so這七個(gè)庫(kù)導(dǎo)入添加到共享庫(kù)(這里不關(guān)注CPU架構(gòu)),IMPORTED指2.4中根據(jù)CPU架構(gòu)導(dǎo)入指定的so庫(kù)潘拨。
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 設(shè)置目標(biāo)版本庫(kù)
判斷當(dāng)前機(jī)型是哪個(gè)CPU架構(gòu)吊输,就加載libs下對(duì)應(yīng)的so包:
#判斷目標(biāo)版本并設(shè)置 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連接共享庫(kù)
將所有添加進(jìn)來(lái)的共享庫(kù)和NDK中查到到已有的庫(kù)鏈接起來(lái):
target_link_libraries( native-lib fdk-aac avcodec avfilter avformat avutil swresample swscale ${log-lib} )
-
-
-
3 相關(guān)代碼編寫(xiě)
-
3.1新建java文件FFmpegKit,內(nèi)容如下:
/** * Created by MouShao on 2018/2/28. */ public class FFmpegKit { static { //加載CMakeList中連接的共享庫(kù) 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編寫(xiě)
#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標(biāo)準(zhǔn) cppFlags "-std=c++11" } ndk{ //abi兼容設(shè)置 abiFilters "armeabi-v7a","armeabi","arm64-v8a","x86","x86_64" } } } //導(dǎo)入app/libs下庫(kù) sourceSets.main { jniLibs.srcDirs = ['libs'] jni.srcDirs = [] } }
-
3.4 MainActivity調(diào)用
-
4 運(yùn)行如圖所示:
結(jié)語(yǔ)
到此铁追,F(xiàn)Fmpeg的首秀就完成了季蚂,下一篇我們將如何用JNI動(dòng)態(tài)注冊(cè)的方式調(diào)用FFmpeg播放視頻。
下一節(jié)講:
FFmpeg(五):JNI動(dòng)態(tài)注冊(cè)方法調(diào)用FFmpeg播放視頻