在系列一中講述瞭如何編譯FFmpeg的源碼,如今就在Android項目中引入咱們編譯出來的庫,並實現播放一個在線視頻的功能java
新建一個支持ndk的Android工程,在AS中新建工程就再也不詳述了,詳細的新建ndk工程,能夠參考AndroidStudio中使用JNI/NDK示例 須要注意的一點就是在新建導航中注意勾選Support C++這個選項,這樣新建的Android工程就會有CMakeLists等進行NDK編譯時必要的東東了。android
新建的Android工程須要對項目中的app/build.gradle作一些修改,其中主要修改的地方以下:git
android {
……
defaultConfig {
……
externalNativeBuild {
// -Wno-deprecated-declarations 添加這個保證編譯出的不少文件再也不報錯
cmake {
cppFlags "-frtti -fexceptions -Wno-deprecated-declarations"
cFlags "-DSTDC_HEADERS"
}
}
ndk { // 聲明編譯的架構類型,指定爲armeabi-v7a便可
abiFilters "armeabi-v7a"
}
}
externalNativeBuild {
cmake { // 配置咱們本身的CMakeLists文件
path file('CMakeLists.txt')
}
}
sourceSets {
main {
// 指定存放native代碼的目錄,這裏指定爲jni和cpp皆可
jni.srcDirs = ['src/main/jni', 'src/main/cpp/']
// 指定jni庫的存放目錄爲libs
jniLibs.srcDirs = ['libs']
}
}
}
複製代碼
上面配置須要特別說明的一點是,在cmake配置中的cppFlags務必添加-Wno-deprecated-declarations,這樣確保咱們能使用一些過時的接口。另外在後面導入FFmpeg編譯生成的代碼到AS中會有不少標紅,添加了這個配置屬性後,各類討厭的標紅就去無蹤了😏。github
導入以前,先在咱們工程中的app/下新建libs文件夾,而後繼續在libs下新建armeabi-v7a和include兩個文件夾 架構
咱們編寫一個NDK的橋接類NDKBridge,並在其中定義咱們本身的native庫:
NDKBridge.javaapp
public class NDKBridge {
static {
// 自定義的native庫
System.loadLibrary("ndk_test_jni");
}
……
}
複製代碼
定義一個簡單的播放器類FFVideoPlayer,並在其中聲明一個名爲render的native方法:
FFVideoPlayer.javaide
public class FFVideoPlayer extends SurfaceView {
……
public void play(final String url) {
new Thread(new Runnable() {
@Override
public void run() {
render(url, FFVideoPlayer.this.getHolder().getSurface());
}
}).start();
}
// 播放器渲染的方法,須要在native層中實現
public native void render(String url, Surface surface);
}
複製代碼
此時咱們尚未配置CMakeLists文件,也沒有新建任何native代碼,因此上面聲明的native方法是會標紅報錯的post
配置CMakeLists文件,指定咱們的native代碼入口,並指定編譯成的native庫,以及引用的哪些native代碼。下面列出一些須要注意的點,詳細內容能夠到項目工程中查看gradle
# 添加庫——本身編寫的庫
# 庫名稱:ndk_test_jni
# 庫類型:SHARED,表示動態庫,後綴爲.so(若是是STATIC,則表示靜態庫,後綴爲.a)
# 庫源碼文件:src/main/jni/ndk_test_jni.cpp
add_library(ndk_test_jni
SHARED
src/main/jni/ndk_test_jni.cpp)
……
# 引入頭文件,不然沒法在ndk_test_jni.cpp中導入FFmpeg編譯出的源文件
include_directories(libs/include)
複製代碼
暫時先別執行syc操做,由於都沒有ndk_test_jni.cpp文件,確定會失敗!ui
根據CMakeLists中的配置,咱們須要在工程的src/main/jni中新建一個ndk_test_jni.cpp文件,而後再執行syc操做。
到上面聲明native方法的地方,此時應該仍是標紅報錯。用鼠標點擊右邊標紅的地方,使錯誤處於選中狀態,而後點擊ALT+Enter快捷鍵,此時AS會彈出建立須要的native方法,點擊確認後就會自動在咱們的ndk_test_jni.cpp中新建一個空的Java_cain_tencent_com_androidexercisedemo_ffmpeg_FFVideoPlayer_render方法,這就是咱們在java層聲明的native方法的實現。而後就能夠愉快地到ndk_test_jni.cpp中去盡情發揮,實現各個native方法了。
具體的代碼這裏就不貼出來了,具體的能夠到項目查看,當中註釋也寫得很明朗了。這裏須要注意的一點就是咱們須要將各個native方法包裹在extern "C" {}中
extern "C" {
#include <cstdio>
#include "lame/lame.h"
//封裝格式處理
#include <libavformat/avformat.h>
#include <android/native_window_jni.h>
#include <libavfilter/avfilter.h>
#include <libavcodec/avcodec.h>
//封裝格式處理
#include <libavformat/avformat.h>
//像素處理
#include <libswscale/swscale.h>
#include <unistd.h>
/** * 解碼視頻播,渲染播放 */
extern "C"
JNIEXPORT void JNICALL Java_cain_tencent_com_androidexercisedemo_ffmpeg_FFVideoPlayer_render(JNIEnv *env, jobject instance,jstring url_,jobject surface) {
……
}
}
複製代碼
不然在編譯時會報各類unresolved錯誤
這裏須要播放在線視頻,所以也須要記得申請聯網權限