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

上篇使用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>

#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的精髓。随便怎么该都没关系。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值