基于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文件内容如下:
对应的Android.mk文件内容如下:
Appllication.mk文件内容如下:
jni文件对应的java加载动态库的文件内容如下:
测试界面MainActivity的内容如下:
3.在jni目录执行
编译结果:
生成的库:
4.连上手机调试,查看结果。
从上面测试结果可以看出,成功打印出了avcodec的version, configuration 和 license。说明我们编译出来的库可用。后面可直接使用该库及头文件进行ffmpeg的开发。
FFMPEG是用C编写的。且解构不太清晰,可用的文档很少。中文文档更是稀有。且ffmpeg每个版本之间存在差异。尤其是早起版本,差异很大,很多API的名字及参数个数都做了更改。所以直接下载早起版本的测试程序用这个库编译会报很多错。不过万变不离其宗,只要掌握了ffmpeg的精髓。随便怎么该都没关系。
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的精髓。随便怎么该都没关系。
相关文章推荐
- 基于FFmpeg的视频推流
- 基于ffmpeg的C++播放器1
- 机器学习第一个练手程序 基于决策树的iris数据预测
- 基于最简单的FFmpeg采样读取内存读写:存储转
- 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器
- SAP UI5第一个基于XS的UI5程序
- win7运行第一个opencv程序,基于opencv3.2,官方vc14编译版本,QT5.8 VS2015平台
- 如何基于FFMPEG和SDL写一个少于1000行代码的视频播放器
- 基于jquery的上传插件Uploadify 3.1.1在MVC3中的使用
- 仿微信视频拍摄UI, 基于ffmpeg的视频录制编辑(上)
- 基于Windows8与Visual Studio11开发第一个ring3驱动程序
- 最简单的基于FFMPEG的Helloworld程序
- 基于FFmpeg的音频编码(PCM数据编码成AAC android)
- 最简单的基于FFmpeg的移动端例子附件:Android 自带播放器
- android基于ffmpeg的简单视频播发器 跳到指定帧 av_seek_frame()
- 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0)
- 我的第一个struts2.1-hibernate3.2程序(基于myeclipce2016)
- 基于ffmpeg的Android播放器开源代码
- 最简单的基于FFmpeg的推流器(以推送RTMP为例)
- 基于mac,ndk开发,使用android studio 编译ffmpeg(二)