這部分我們測試一下我們通過自己寫視頻播放器(1) 編譯ffmpeg for android得到的libffmpeg.so是不是基本可以使用。因為我們只是獲取一下版本信息,因此只能稱為基本可用。
JNI說明
Java的JNI (Java Native Interface),又稱為本地接口調(diào)用。這一機(jī)制主要是為了方便人們可以調(diào)用以前c/c++編寫的庫,或者提高效率,亦或者對應(yīng)用進(jìn)行保護(hù)(核心代碼封裝在底層.so庫中,增加破解難度)。
JNI使用方式(以C庫為例)
常見的使用方式有如下幾種:
1.自己寫底層的C源碼
我們需要建java類文件,聲明jni方法,然后生成.h文件,編寫C源文件include之前生成的.h文件并實(shí)現(xiàn)相應(yīng)方法,最后用androidNDK開發(fā)包中的ndk-build腳本生成對應(yīng)的.so共享庫
例子可以參考 NDK開發(fā)入門
2.已有一個C庫
比如我們有了libffmpeg.so 。我們還得編譯一個so文件,這個so里的是jni方法,可以由java層調(diào)用的,而這些jni方法里用到的函數(shù)則來至libffmpeg.so庫
創(chuàng)建 JNIProxy類
package com.example.myplayer1;
public class JNIProxy {
public native boolean ffmpegInit();//Jni方法
public native boolean ffmpegUninit();
public native int ffmpegGetAvcodecVersion();
}
生成 com_example_myplayer1_JNIProxy.h
tip:獲得本地方法頭文件
jdk6.0:在Android工程的bin\classes目錄下執(zhí)行:javah 包名+類名
jdk7.0:在Android工程的src目錄下執(zhí)行:javah 包名+類名
javah com.example.myplayer1.JNIProxy
這個文件和你的工程的包名類名是相關(guān)的,其內(nèi)容如下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_myplayer1_JNIProxy */
#ifndef _Included_com_example_myplayer1_JNIProxy
#define _Included_com_example_myplayer1_JNIProxy
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_myplayer1_JNIProxy
* Method: ffmpegInit
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_example_myplayer1_JNIProxy_ffmpegInit
(JNIEnv *, jobject);
/*
* Class: com_example_myplayer1_JNIProxy
* Method: ffmpegUninit
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_example_myplayer1_JNIProxy_ffmpegUninit
(JNIEnv *, jobject);
/*
* Class: com_example_myplayer1_JNIProxy
* Method: ffmpegGetAvcodecVersion
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_myplayer1_JNIProxy_ffmpegGetAvcodecVersion
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
實(shí)現(xiàn)jni方法
#include <jni.h>
#include "avcodec.h"
#include "avformat.h"
#include "com_example_myplayer1_JNIProxy.h"
//要保證頭文件導(dǎo)入正常
/* Class: com_example_myplayer1_JNIProxy
* Method: ffmpegInit
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_example_myplayer1_JNIProxy_ffmpegInit
(JNIEnv *env, jobject obj){
av_register_all();
return 1;
}
/*
* Class: com_example_myplayer1_JNIProxy
* Method: ffmpegUninit
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_example_myplayer1_JNIProxy_ffmpegUninit
(JNIEnv *env, jobject obj){
return 1;
}
/*
* Class: com_example_myplayer1_JNIProxy
* Method: ffmpegGetAvcodecVersion
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_myplayer1_JNIProxy_ffmpegGetAvcodecVersion
(JNIEnv *env, jobject obj){
return avcodec_version();
}