为了账号安全,请及时绑定邮箱和手机立即绑定

ubuntu 使用android studio 编译 ffmpeg(二)

标签:
Android

本教程是在你的电脑上已经安装了ndk环境的前提下进行的,如果还没有可以百度一下安装方法,这里就不详述了,不是我要讲的重点。下面讲怎么在ubuntu下利用android studio 和ndkr10e编译ffmpeg并且使用

在教程(一),我们得到了编译出来的so文件。其中不带编号的如libavutil.so是so的链接文件,我们不需要,可以删除,保留带有编号的so文件如libavutil-55.so。


编写调用c方法的java文件,其中so的调用顺序如下

public class FFmpegNative {
    static {

        System.loadLibrary("avutil-55");
        System.loadLibrary("swresample-2");
        System.loadLibrary("avcodec-57");
        System.loadLibrary("avformat-57");
        System.loadLibrary("swscale-4");
        System.loadLibrary("avfilter-6");
        System.loadLibrary("avdevice-57");
        System.loadLibrary("ffmpeg_codec");//自己编写的c文件的so
    }
    public  native String getStringFromNative();
}

执行buildmake project,生成classes文件,使用终端移动到如下目录

5bd42e4300011c3903950156.jpg

输入 java -jni com.bear.ffmpeg.FFmpegNative

其中“com.bear.ffmpeg”是包名,“FFmpegNative”是java文件的名字

此命令会生成一个.h文件,文件的名称会有点长,你可以把它修改一下,这里我就不改了

5bd42e430001ddc701640122.jpg

在android项目的地址进入app/src/main目录,创建jni文件夹

将.h拷贝到jni目录下,编写c文件,名称不必相同

5bd42e430001f83101700129.jpg

将头文件的方法规范拷贝到c文件,实现方法,注意的是,这里的返回值的编写,因为在java里面字符编码是utf16,而安卓是utf8,所以不能直接返回字符串,需要做一个转换(*env)->NewStringUTF(),如下:


JNIEXPORT jstring JNICALL Java_com_bear_ffmpeg_FFmpegNative_getStringFromNative
        (JNIEnv *env , jobject obj){

      av_register_all();

      char wd[512];
      sprintf(wd, "AVCODEC VERSION %u\n"
        , avcodec_version()
        );
      return (*env)->NewStringUTF(env, wd);

  }


在jni目录下编写Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE    := avcodec-57
LOCAL_SRC_FILES := prebuilt/libavcodec-57.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := avdevice-57
LOCAL_SRC_FILES := prebuilt/libavdevice-57.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := avfilter-6
LOCAL_SRC_FILES := prebuilt/libavfilter-6.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := avformat-57
LOCAL_SRC_FILES := prebuilt/libavformat-57.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := avutil-55
LOCAL_SRC_FILES := prebuilt/libavutil-55.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := swresample-2
LOCAL_SRC_FILES := prebuilt/libswresample-2.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := swscale-4
LOCAL_SRC_FILES := prebuilt/libswscale-4.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := ffmpeg_codec
LOCAL_SRC_FILES := com_bear_ffmpeg_FFmpegNative.c

LOCAL_LDLIBS := -llog -ljnigraphics -lz -landroid
LOCAL_SHARED_LIBRARIES := libavformat-57 libavcodec-57 libswscale-4 libavutil-55 libswresample-2 libavdevice-57 libavfilter-6
include $(BUILD_SHARED_LIBRARY)


在jni目录下编写Application.mk(这里的只能够用于arm处理器)


APP_ABI :=armeabi,armeabi-v7a
APP_PLATFORM := android-21
APP_OPTIM := release

APP_STL := gnustl_static


在jni目录下创建prebuilt文件夹将之前得到的so库拷贝进去,并且把教程一编译的所有的头文件拷贝到jni目录下,结构如下

5bd42e43000168ab06490437.jpg

这里有一个空的util.c的文件,至于为什么加上这个是因为有时候ndk编译会报错,找不到编译的规则,你可以先不加这个文件,然后编译,如果没有报错就不用加了

使用终端cd到app/src/main目录,执行“ndk-build”,编译so库


将生成的so库从app/src/main/libs拷贝一份到app/Libs


编写buld.gradle文件如下

android {
    compileSdkVersion 23
    buildToolsVersion '23.0.1'


    defaultConfig {
        applicationId "com.bear.ffmpeg"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        ndk {
            moduleName "ffmpeg_codec"//c库的名字
            ldLibs "log", "z", "m","android","jnigraphics"
            abiFilters "arm64-v8a","armeabi","armeabi-v7a"
        }
        sourceSets.main{
            jni.srcDirs=[]//禁用自动ndk,在编写c代码的时候建议注释掉,因为这句话会停用c的语法提示功能
            jniLibs.srcDir "src/main/libs"
        }


    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}


现在就可以在调用jni的方法了!

运行安卓程序,会得到一串数字,那么你基本上就成功了!

一些注意事项:

so库的文件名不要写错了

最后运行时请禁用ndk自动运行,在build.gradle里面

sourceSets.main{
            jni.srcDirs=[]//禁用自动ndk,在编写c代码的时候建议注释掉,因为这句话会停用c的语法提示功能
            jniLibs.srcDir "src/main/libs"
        }

运行时提示找不到so库,可以再生成一次头文件,并且ndk-build,然后运行

原文链接:http://www.apkbus.com/blog-641094-60519.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 1
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消