在我這篇文章中有簡(jiǎn)單的提供一個(gè)NDK交叉編譯FFmpeg,編譯完成之后的集成就比較容易了。當(dāng)然還是需要一點(diǎn)點(diǎn)jni開(kāi)發(fā)的技術(shù),不了解的可以去看看我的這兩篇文章:
集成
我認(rèn)為在編譯好FFmpeg之后,集成FFmpeg有以下幾步:
- 在Android Studio中創(chuàng)建支持c++的Android項(xiàng)目
- 添加FFmpeg的頭文件
- 添加FFmpeg的so文件
- 調(diào)用FFmpeg方法測(cè)試集成是否成功
內(nèi)容不多,下邊就開(kāi)始操作。
創(chuàng)建支持c++項(xiàng)目
這步其實(shí)對(duì)做過(guò)Android開(kāi)發(fā)的同學(xué)毫無(wú)難度。
- new一個(gè)Android Project,然后自定義一下名字和包名,然后在
include C++ support一項(xiàng)前打勾; - 然后next,然后是選擇要開(kāi)發(fā)的目標(biāo)設(shè)備和最低版本,這里以手機(jī)為例,最低版本一般要全兼容就選4.0,不是太嚴(yán)苛的話可以選擇4.1了(4.1以上目前占99.6%);
- 然后next,默認(rèn)選擇的Empty Activity就行;
- 然后next,默認(rèn)的名字就行,也可以自己修改也行;
- 然后next,這里是選擇c++支持,我們選擇c++11就好了;
- 最后finish,等待編譯完成就完成了這一步。
添加FFmpeg的頭文件
編譯好之后,項(xiàng)目文件結(jié)構(gòu)換成Project,個(gè)人習(xí)慣,因?yàn)檫@樣目錄結(jié)構(gòu)比較清晰。
- 將之前編譯好的FFmpeg的頭文件目錄拷貝到app目錄下;
- 再在app下的CMakeLists.txt文件中,添加
include_directories(include)代碼; - 這樣頭文件就算是加進(jìn)來(lái)了。
添加FFmpeg的so文件
在libs目錄下添加你編譯出來(lái)的FFmpeg的cpu目錄,例如我添加的是armeabi-v7a;然后就把之前編譯出來(lái)的所有so包放到新添加的cpu目錄下;然后在app模塊的build.gradle文件的android->defaultConfig下邊添加:
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
表示jni的資源路徑是在libs目錄下的;然后再到app下的CMakeLists.txt文件中添加:
#設(shè)置ffmpeg庫(kù)路徑變量
set(FF ${CMAKE_CURRENT_SOURCE_DIR}/libs/${ANDROID_ABI})
add_library(avcodec SHARED IMPORTED)
add_library(avformat SHARED IMPORTED)
add_library(avutil SHARED IMPORTED)
add_library(swscale SHARED IMPORTED)
add_library(swresample SHARED IMPORTED)
set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${FF}/libavcodec.so)
set_target_properties(avformat PROPERTIES IMPORTED_LOCATION ${FF}/libavformat.so)
set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${FF}/libavutil.so)
set_target_properties(swscale PROPERTIES IMPORTED_LOCATION ${FF}/libswscale.so)
set_target_properties(swresample PROPERTIES IMPORTED_LOCATION ${FF}/libswresample.so)
再把心添加的庫(kù)文件鏈接到native-lib下,也就是將如下代碼:
target_link_libraries(
native-lib
${log-lib})
改成
target_link_libraries(
native-lib
avcodec avformat avutil swscale swresample
${log-lib})
這樣到這里添加so文件也就完成了。主要是CMakeLists.txt文件修改比較多,修改完之后這個(gè)文件的內(nèi)容如下,可以對(duì)比一下(我已經(jīng)把不太需要的注釋刪了):
cmake_minimum_required(VERSION 3.4.1)
#添加頭文件路徑
include_directories(include)
#設(shè)置ffmpeg庫(kù)路徑變量
set(FF ${CMAKE_CURRENT_SOURCE_DIR}/libs/${ANDROID_ABI})
add_library(avcodec SHARED IMPORTED)
add_library(avformat SHARED IMPORTED)
add_library(avutil SHARED IMPORTED)
add_library(swscale SHARED IMPORTED)
add_library(swresample SHARED IMPORTED)
set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${FF}/libavcodec.so)
set_target_properties(avformat PROPERTIES IMPORTED_LOCATION ${FF}/libavformat.so)
set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${FF}/libavutil.so)
set_target_properties(swscale PROPERTIES IMPORTED_LOCATION ${FF}/libswscale.so)
set_target_properties(swresample PROPERTIES IMPORTED_LOCATION ${FF}/libswresample.so)
add_library(native-lib
SHARED
src/main/cpp/native-lib.cpp)
find_library(log-lib log)
target_link_libraries(
native-lib
avcodec avformat avutil swscale swresample
${log-lib})
調(diào)用FFmpeg方法測(cè)試是否集成成功
so添加完,再編譯一下之后;就可以在native-lib.cpp文件中的stringFromJNI方法里添加一句:
hello += avformat_configuration();
這時(shí)候這個(gè)方法是找不到的,然后我們?cè)僖腩^文件:
extern "C" {
#include <libavformat/avformat.h>
}
extern "c"這一個(gè)是表示這部分按照c語(yǔ)言的規(guī)則來(lái)編譯,至于為什么要這樣可以自行查詢。
這樣不出意外,運(yùn)行程序就能在屏幕中看到很長(zhǎng)一串文本,包含的是ffmpeg編譯的配置信息和腳本的./configure 之后的那部分有點(diǎn)類似。
到這里FFmpeg的集成就基本完成了。