您的位置:首页 > 移动开发 > Android开发

基于FFMPEG3.1.1的第一个Android测试程序

2016-07-29 19:02 411 查看
上篇使用NDK编译出了ffmpeg3.1.1版本的动态链接库。这篇文章我们就写一个简单的JNI程序来测试我们生成的libffmpeg.so库是否可用。

1.在android studio中建立一个工程。并新建jni目录。在里面新建一个ffmpeg文件夹,放入ffmpeg的库libffmpeg.so和头文件,包括:libavcodec libavdevice libavfilter libavformat libavutil libswscale libswresample 。



2.在jni目录新建一个c文件。具体方法可百度,这里不在详细解释。jni文件只有一个测试函数testFFmpegLib 里面将调用avcodec的API函数来输出avcodec的version、license 和configuration。把这些信息存入字串中,从java中读取。jni文件内容如下:

#include <jni.h>
#include <android/log.h>
#include <stdio.h>
#include <stdlib.h>

<
4000
span class="hljs-preprocessor">#include <libavcodec/avcodec.h>
#include <libavutil/common.h>

#ifndef __JNI_TEST_H__
#define __JNI_TEST_H__

#define LOG_TAG ("Tag")
#define LOGD(...)   __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...)   __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

#ifdef __cplusplus
extern "C"
{
#endif

JNIEXPORT jstring JNICALL Java_com_jjws_testanim_JNITest_testFFmpegLib(JNIEnv *env, jobject thiz) {

unsigned int ver = avcodec_version();
const char *config  = avcodec_configuration();
const char *license = avcodec_license();
char *des = NULL;
const char *version_str = "AVCodec Version:";
const char *config_str = "AVCodec Configuration:";
const char *license_str = "AVCodec license:";

jstring jstr = NULL;

int ver_len = 0, config_len = 0, license_len = 0, len = 0;

ver_len = sizeof(unsigned int);

if(config != NULL) {
config_len = strlen(config);
}

if(license != NULL) {
license_len = strlen(license);
}

len = ver_len + config_len + license_len + strlen(version_str) + strlen(config_str) + strlen(license_str) + 4 + 1;

des = (char*)malloc(len);
if(des == NULL)
return NULL;

memset(des, 0x00, len);

strcpy(des, version_str);
sprintf(des+strlen(version_str), "%d", ver);
strcat(des, "\n");
strcat(des, "\n");

strcat(des, license_str);
strcat(des, license);
strcat(des, "\n");
strcat(des, "\n");

strcat(des, config_str);
strcat(des, config);

jstr = (jstring)(*env)->NewStringUTF(env, des);

(*env)->ReleaseStringUTFChars(env, jstr, (const char*)des);

return jstr;

}

#ifdef __cplusplus
}
#endif


对应的Android.mk文件内容如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_FFMPEG_PATH := $(LOCAL_PATH)/ffmpeg
LOCAL_MODULE := libffmpeg
LOCAL_SRC_FILES := $(LOCAL_FFMPEG_PATH)/libffmpeg.so
LOCAL_C_INCLUDES +=     $(LOCAL_FFMPEG_PATH)/libavcodec \
$(LOCAL_FFMPEG_PATH)/libavutil \
$(LOCAL_FFMPEG_PATH)/libavformat \
$(LOCAL_FFMPEG_PATH)/libswscale \
$(LOCAL_FFMPEG_PATH)/libavdevice \
$(LOCAL_FFMPEG_PATH)/libavfilter \
$(LOCAL_FFMPEG_PATH)/libswresample

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libJNITest
LOCAL_SRC_FILES := JNITest.c
LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/ffmpeg
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := libffmpeg

include $(BUILD_SHARED_LIBRARY)


Appllication.mk文件内容如下:

APP_OPTIM := debug
APP_ABI := armeabi
APP_PLATFORM := android-19


jni文件对应的java加载动态库的文件内容如下:

public class JNITest {

private static JNITest instance = null;

static {
System.loadLibrary("JNITest");
}

public native String testFFmpegLib();

public JNITest() {

}

public static JNITest getInstance() {
if(instance == null) {
instance = new JNITest();
}

return instance;
}
}


测试界面MainActivity的内容如下:

package com.jjws.testanim;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

private TextView jnistr;
private JNITest mJNITest = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

jnistr = (TextView) findViewById(R.id.jnistr);
mJNITest = JNITest.getInstance();
jnistr.setText(mJNITest.testFFmpegLib());
}
}


3.在jni目录执行
ndk-build
编译命令,即可生成相应的libJNITest.so动态库。不出意外会在libs文件夹生成libJNITest.so和libffmpeg.so库。我的工程是用的jniLibs文件夹。可手动拷贝到jniLibs文件夹,也可在Android.mk中添加shell命令自动拷贝
。生成库的结果如下:

编译结果:



生成的库:



4.连上手机调试,查看结果。



从上面测试结果可以看出,成功打印出了avcodec的version, configuration 和 license。说明我们编译出来的库可用。后面可直接使用该库及头文件进行ffmpeg的开发。

FFMPEG是用C编写的。且解构不太清晰,可用的文档很少。中文文档更是稀有。且ffmpeg每个版本之间存在差异。尤其是早起版本,差异很大,很多API的名字及参数个数都做了更改。所以直接下载早起版本的测试程序用这个库编译会报很多错。不过万变不离其宗,只要掌握了ffmpeg的精髓。随便怎么该都没关系。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: