热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

3.Android工程中使用FFmpeg的so库JNI头文件的生成

白话:由于习惯了使用Linux终端的命令行,因此以下介绍Android工程的创建不依赖任何IDE工具(如:eclipse、a
白话:

    由于习惯了使用Linux终端的命令行,因此以下介绍Android工程的创建不依赖任何IDE工具(如:eclipse、android studio等),本文的操作全部是在命令行中操作,仅仅是个人习惯。还有Android开发环境的正确配置是本文的基础。如果为配置Android开发环境,需要先配置好Android开发环境。另外本文通过介绍一个”使用FFmpeg抓取视频文件中的一帧图像“的例子介绍如何在Android工程中使用FFmpeg的库。


3.1 创建Android工程




  • 使用Android SDK中的工具察看机器中所安装的所有SDK版本,命令:


android list targets


注:android命令工具是在SDK的tools目录下,其是一个脚本文件。



  • 根据使用的SDK版本创建Android工程,target-id处填写你需要的版本,我使用的是android 7.0因此对应的是android-24,命令:

android create project --target --name MyFirstApp --path /MyFirstApp --activity MainActivity --package com.example.myapp



  • 在生成的Android工程目录下创建jni目录,将2文中生成的包含FFmpeg头文件的”include“目录和包含so库文件的”lib“目录拷贝到此jni目录下。
  • 编写MainActivity.java文件和main.xml(MainActivity对应的layout文件)文件:

MainActivity.java:




package com.rk.myapp;import android.app.Activity;
import android.os.Bundle;
import android.graphics.Bitmap;
import android.util.Log;
import android.widget.ImageView;import com.rk.myapp.R;public class MainActivity extends Activity
{private static final String TAG = "FFMpeg_JNI";private ImageView mImageView;/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);mImageView = (ImageView) findViewById(R.id.image_frame);}public void onStart() {super.onStart();nativeInit();/*20151010_132114.mp42a8s.mkvdb.tsshiziwang.rmvb*/nativeSetUri("/mnt/usb/AD0C-15F0/Test/video/db.ts");nativePrepare();nativeStart();Log.i(TAG, "onstart end");}public void onResume() {super.onResume();Bitmap b = nativeGetFrameBitmap();mImageView.setImageBitmap(b);Log.i(TAG, "onResume(), bitmap is " + b);Log.i(TAG, "onResume(), w = " + b.getWidth() + ", h = " + b.getHeight());}public void onStop() {super.onStop();nativeDeinit();}// 加载FFMpegJni库,我们在此库的原文件中将调用FFmpeg的so库里的方法完成我们需要的功能。static{System.loadLibrary("FFMpegJni");}// 使用FFmpeg获取视频里某一帧的图像的过程:// (1)初始化FFmpeg,这是使用FFmpeg的第一步。// (2)使用FFmpeg解码视频,找到那一帧。// (3)将那一帧的图像原始数据转为native层的bitmap对象。// (4)java层获取native的bitmap对象,并且在imageview上显示。private native void nativeInit(); //FFmpeg初始化的native接口private native void nativeSetUri(String uri); //设置视频的路径的native接口private native Bitmap nativeGetFrameBitmap(); //获取视频帧的native接口private native void nativePrepare(); //FFmpeg解码之前的准备工作private native void nativeStart(); //FFmpeg开始解码,并且将解码的数据保存为bitmap对象。private native void nativeDeinit(); //使用完FFmpeg后,资源的释放。
}



main.xml:










  • 在Android工程目录运行命令编译Android工程(我一般使用debug版本先开发测试),编译成功后在工程目录下会多出bin、gen、libs目录:

ant debug





  • 进入bin目录下的classes目录,使用javah生成JNI接口的头文件, 命令:

javah -d ./ -bootclasspath ~/Android/android-sdk-linux/platforms/android-24/android.jar -jni com.rk.myapp.MainActivity


注:(1)”~/Android/android-sdk-linux/platforms/android-24/android.jar“是sdk的android.jar,生成头文件的时候需要用到,否这找不到 Android框架的一些类而报错。


        (2)"com.rk.myapp.MainActivity"既是定义native接口class,其在的目录为 ”MyFirstApp/bin/classes/com/rk/myapp目录下。




  • 在当前目录下生成的头文件为:com_rk_myapp_MainActivity.h,红色标注的为与MainActivity文件中所定义native接口相对应的头文件中的定义。

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_rk_myapp_MainActivity */#ifndef _Included_com_rk_myapp_MainActivity
#define _Included_com_rk_myapp_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_rk_myapp_MainActivity_BIND_ABOVE_CLIENT
#define com_rk_myapp_MainActivity_BIND_ABOVE_CLIENT 8L
#undef com_rk_myapp_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_rk_myapp_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_rk_myapp_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_rk_myapp_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_rk_myapp_MainActivity_BIND_AUTO_CREATE
#define com_rk_myapp_MainActivity_BIND_AUTO_CREATE 1L
#undef com_rk_myapp_MainActivity_BIND_DEBUG_UNBIND
#define com_rk_myapp_MainActivity_BIND_DEBUG_UNBIND 2L
#undef com_rk_myapp_MainActivity_BIND_EXTERNAL_SERVICE
#define com_rk_myapp_MainActivity_BIND_EXTERNAL_SERVICE -2147483648L
#undef com_rk_myapp_MainActivity_BIND_IMPORTANT
#define com_rk_myapp_MainActivity_BIND_IMPORTANT 64L
#undef com_rk_myapp_MainActivity_BIND_NOT_FOREGROUND
#define com_rk_myapp_MainActivity_BIND_NOT_FOREGROUND 4L
#undef com_rk_myapp_MainActivity_BIND_WAIVE_PRIORITY
#define com_rk_myapp_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef com_rk_myapp_MainActivity_CONTEXT_IGNORE_SECURITY
#define com_rk_myapp_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_rk_myapp_MainActivity_CONTEXT_INCLUDE_CODE
#define com_rk_myapp_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_rk_myapp_MainActivity_CONTEXT_RESTRICTED
#define com_rk_myapp_MainActivity_CONTEXT_RESTRICTED 4L
#undef com_rk_myapp_MainActivity_MODE_APPEND
#define com_rk_myapp_MainActivity_MODE_APPEND 32768L
#undef com_rk_myapp_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_rk_myapp_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_rk_myapp_MainActivity_MODE_MULTI_PROCESS
#define com_rk_myapp_MainActivity_MODE_MULTI_PROCESS 4L
#undef com_rk_myapp_MainActivity_MODE_NO_LOCALIZED_COLLATORS
#define com_rk_myapp_MainActivity_MODE_NO_LOCALIZED_COLLATORS 16L
#undef com_rk_myapp_MainActivity_MODE_PRIVATE
#define com_rk_myapp_MainActivity_MODE_PRIVATE 0L
#undef com_rk_myapp_MainActivity_MODE_WORLD_READABLE
#define com_rk_myapp_MainActivity_MODE_WORLD_READABLE 1L
#undef com_rk_myapp_MainActivity_MODE_WORLD_WRITEABLE
#define com_rk_myapp_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef com_rk_myapp_MainActivity_DEFAULT_KEYS_DIALER
#define com_rk_myapp_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef com_rk_myapp_MainActivity_DEFAULT_KEYS_DISABLE
#define com_rk_myapp_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_rk_myapp_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_rk_myapp_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
#undef com_rk_myapp_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_rk_myapp_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_rk_myapp_MainActivity_DEFAULT_KEYS_SHORTCUT
#define com_rk_myapp_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_rk_myapp_MainActivity_RESULT_CANCELED
#define com_rk_myapp_MainActivity_RESULT_CANCELED 0L
#undef com_rk_myapp_MainActivity_RESULT_FIRST_USER
#define com_rk_myapp_MainActivity_RESULT_FIRST_USER 1L
#undef com_rk_myapp_MainActivity_RESULT_OK
#define com_rk_myapp_MainActivity_RESULT_OK -1L
/** Class: com_rk_myapp_MainActivity* Method: nativeInit* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_rk_myapp_MainActivity_nativeInit(JNIEnv *, jobject);/** Class: com_rk_myapp_MainActivity* Method: nativeSetUri* Signature: (Ljava/lang/String;)V*/
JNIEXPORT void JNICALL Java_com_rk_myapp_MainActivity_nativeSetUri(JNIEnv *, jobject, jstring);/** Class: com_rk_myapp_MainActivity* Method: nativeGetFrameBitmap* Signature: ()Landroid/graphics/Bitmap;*/
JNIEXPORT jobject JNICALL Java_com_rk_myapp_MainActivity_nativeGetFrameBitmap(JNIEnv *, jobject);/** Class: com_rk_myapp_MainActivity* Method: nativePrepare* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_rk_myapp_MainActivity_nativePrepare(JNIEnv *, jobject);/** Class: com_rk_myapp_MainActivity* Method: nativeStart* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_rk_myapp_MainActivity_nativeStart(JNIEnv *, jobject);/** Class: com_rk_myapp_MainActivity* Method: nativeDeinit* Signature: ()V*/
JNIEXPORT void JNICALL Java_com_rk_myapp_MainActivity_nativeDeinit(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif



这样JNI接口的头文件就自动生成了,下一步将实现JNI头文件所定义的接口,将在4文中介绍。







推荐阅读
author-avatar
墙脚等红线_987
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有