ffmpeg动态库在android上的测试
来源:互联网 发布:linux磁盘分区挂载 编辑:程序博客网 时间:2024/06/05 03:43
上篇文章介绍了怎样用虚拟机把ffmpeg编译成android可用的动态库,这次把动态库引入eclipse android工程,并调用ffmpeg类库
注意,在网页上粘贴的代码,很多符号会变成中文的,导致很难发现的错误...
如果没有so库的朋友,可以参考我的上一篇博客,之中也有编译好的下载地址,ndk版本是r13,ffmpeg版本是3.1.3,abi是armeabi-v7a,在华为4x上运行通过
下面开始:
1.so库和头文件复制到安卓工程jni目录下,并创建Android.mk,Application.mk,HelloJni.c文件,
Android.mk:指明so库如何引入,编译那些c文件,因为ffmpeg是c写的,所以写c++调用可能会有问题,这个文件描述如何编译动态库
Application.mk:可以指明编译时生成那些目标cpu架构的so,我的华为4x是armeabi-v7a
HelloJni.c:实现java的native方法
JniUtils.java
package com.example.ffmpegtest001;public class JniUtils {static {System.loadLibrary("avcodec-57");System.loadLibrary("avfilter-6");System.loadLibrary("avformat-57");System.loadLibrary("avutil-55");System.loadLibrary("swresample-2");System.loadLibrary("swscale-4");System.loadLibrary("hello-jni");}public native String stringFromJNI();public native String avformatinfo();public native String avcodecinfo();public native String avfilterinfo();public native String configurationinfo();}MainActivity.java
package com.example.ffmpegtest001;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.TextView;public class MainActivity extends ActionBarActivity {private TextView textView;JniUtils jniUtils;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);jniUtils = new JniUtils();textView = (TextView) findViewById(R.id.textview);}public void format(View view) {textView.setText(jniUtils.avformatinfo());}public void codec(View view) {textView.setText(jniUtils.avcodecinfo());}public void filter(View view) {textView.setText(jniUtils.avfilterinfo());}public void config(View view) {textView.setText(jniUtils.configurationinfo());}}
Android.mk
LOCAL_PATH := $(call my-dir)#ffmpeginclude $(CLEAR_VARS)LOCAL_MODULE:= avcodecLOCAL_SRC_FILES:= libavcodec-57.soLOCAL_MODULE_FILENAME:=libavcodec-57include $(PREBUILT_SHARED_LIBRARY) ##指明此模块需要预编译include $(CLEAR_VARS)LOCAL_MODULE:= avfilterLOCAL_SRC_FILES:= libavfilter-6.soLOCAL_MODULE_FILENAME:=libavfilter-6include $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE:= avformatLOCAL_SRC_FILES:= libavformat-57.soLOCAL_MODULE_FILENAME:=libavformat-57include $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE:= avutilLOCAL_SRC_FILES:= libavutil-55.soLOCAL_MODULE_FILENAME:=libavutil-55include $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE:= swresampleLOCAL_SRC_FILES:= libswresample-2.soLOCAL_MODULE_FILENAME:=libswresample-2include $(PREBUILT_SHARED_LIBRARY)include $(CLEAR_VARS)LOCAL_MODULE:= swscaleLOCAL_SRC_FILES:= libswscale-4.soLOCAL_MODULE_FILENAME:=libswscale-4include $(PREBUILT_SHARED_LIBRARY)#end#myinclude $(CLEAR_VARS)#指明自己模块的名称LOCAL_MODULE := hello-jni#指明自己模块需要的源代码LOCAL_SRC_FILES := HelloJni.c#指明.so库的头文件路径LOCAL_C_INCLUDES += $(LOCAL_PATH)/include#指明需要使用的ndk自带模块LOCAL_LDLIBS := -llog -lz -landroid#指明自己模块编译时需要依赖的模块LOCAL_SHARED_LIBRARIES := avcodec avfilter avformat avutil swresample swscale#指明自己的模块编译为动态库include $(BUILD_SHARED_LIBRARY)Application.mk
#指明编译时生成armeabi-v7a架构的so文件APP_ABI := armeabi-v7aHelloJni.c
#include <string.h>//#include "com_example_ffmpegtest001_JniUtils.h"#include <stdio.h>#include <libavcodec/avcodec.h>#include <libavformat/avformat.h>#include "include/libavutil/avutil.h"#include "include/libavfilter/avfilter.h"//http://www.pps.tv/w_19rt0grxmx.html 很好的视频//Log#ifdef ANDROID#include <jni.h>#include <android/log.h>#define LOGE(format, ...) __android_log_print(ANDROID_LOG_ERROR, "(>_<)", format, ##__VA_ARGS__)#else#define LOGE(format, ...) printf("(>_<) " format "\n", ##__VA_ARGS__)#endifJNIEXPORT jstring JNICALL Java_com_example_ffmpegtest001_JniUtils_stringFromJNI(JNIEnv* env, jobject thiz) {//return env->NewStringUTF("Hello from JNI ! Compiled with ABI ");return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI ");}JNIEXPORT jstring JNICALL Java_com_example_ffmpegtest001_JniUtils_avformatinfo(JNIEnv* env, jobject thiz) {char info[40000] = { 0 };av_register_all();AVInputFormat *if_temp = av_iformat_next(NULL);AVOutputFormat *of_temp = av_oformat_next(NULL);//Inputwhile (if_temp != NULL) {sprintf(info, "%s[In ][%10s]\n", info, if_temp->name);if_temp = if_temp->next;}//Outputwhile (of_temp != NULL) {sprintf(info, "%s[Out][%10s]\n", info, of_temp->name);of_temp = of_temp->next;}//LOGE("%s", info);//return env->NewStringUTF(info);return (*env)->NewStringUTF(env, info);}JNIEXPORT jstring JNICALL Java_com_example_ffmpegtest001_JniUtils_avcodecinfo(JNIEnv* env, jobject thiz) {char info[40000] = { 0 };av_register_all();AVCodec *c_temp = av_codec_next(NULL);while (c_temp != NULL) {if (c_temp->decode != NULL) {sprintf(info, "%s[Dec]", info);} else {sprintf(info, "%s[Enc]", info);}switch (c_temp->type) {case AVMEDIA_TYPE_VIDEO:sprintf(info, "%s[Video]", info);break;case AVMEDIA_TYPE_AUDIO:sprintf(info, "%s[Audio]", info);break;default:sprintf(info, "%s[Other]", info);break;}sprintf(info, "%s[%10s]\n", info, c_temp->name);c_temp = c_temp->next;}//LOGE("%s", info);return (*env)->NewStringUTF(env, info);// return env->NewStringUTF(info);}JNIEXPORT jstring JNICALL Java_com_example_ffmpegtest001_JniUtils_avfilterinfo(JNIEnv* env, jobject thiz) {char info[40000] = { 0 };avfilter_register_all();AVFilter *f_temp = (AVFilter *) avfilter_next(NULL);int i = 0;while (f_temp != NULL) {sprintf(info, "%s[%10s]\n", info, f_temp->name);f_temp = f_temp->next;}return (*env)->NewStringUTF(env, info);// return env->NewStringUTF( info);}JNIEXPORT jstring JNICALL Java_com_example_ffmpegtest001_JniUtils_configurationinfo(JNIEnv* env, jobject thiz) {char info[10000] = { 0 };av_register_all();sprintf(info, "%s\n", avcodec_configuration());//LOGE("%s", info);//return env->NewStringUTF(info);return (*env)->NewStringUTF(env, info);}其中每个c方法对应一个java的native方法
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.ihubin.ffmpegstudy.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:onClick="format" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Format" /> <Button android:onClick="codec" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Codec" /> <Button android:onClick="filter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Filter" /> <Button android:onClick="config" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Config" /> </LinearLayout> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="match_parent" /> </ScrollView></LinearLayout>
我的华为4x的运行截图
阅读全文
0 0
- ffmpeg动态库在android上的测试
- ffmpeg在android平台上的移植
- 在androidstudio2.2上使用ffmpeg动态库
- 在Nanopi-NEO上编译带Cedrus硬件编码器的ffmpeg动态链接库
- FFmpeg在Android上的移植优化步骤
- FFMPEG 在Android 2.3上运行的问题,求救哈!
- FFmpeg在Android上的移植之第一步
- FFmpeg在Android上的移植优化步骤
- FFmpeg在Android上的移植优化步骤 .
- FFmpeg在Android上的移植优化步骤
- FFmpeg在Android上的移植优化步骤
- ffmpeg开发之旅(5):详解ffmpeg编译与在Android平台上的移植
- ffmpeg开发之旅(6):详解ffmpeg命令在Android平台上的使用
- ffmpeg开发之旅(5):详解ffmpeg编译与在Android平台上的移植
- ffmpeg开发之旅(6):详解ffmpeg命令在Android平台上的使用
- 编译FFmpeg在Android上使用
- FFmpeg在android上多媒体编程
- android ffmpeg 动态库编译
- 为期一周的机器学习
- Centos 6.x python3.6 Django 环境设置
- 系统出错。 发生系统错误 1067。 进程意外终止。
- 求多个数的最小公倍数
- Python中带else子句的for循环执行过程
- ffmpeg动态库在android上的测试
- 文件的简单操作
- Linux内核源码分析(二)--启动汇编上篇
- Spring MVC Ajax Json
- SecurCRT界面乱码的问题解决
- MIT开发出高效「查询方法」,以寻找黑盒机器学习分类器的对抗样本
- ImportError: numpy.core.multiarray failed to import
- 商务图表案例——仿经济学人分组漏斗图~
- PAT训练(乙级)—— 1001. 害死人不偿命的(3n+1)猜想 (15)