Android Studio上进行ffmpeg开发

来源:互联网 发布:java ee 6权威指南 编辑:程序博客网 时间:2024/06/02 04:39

闲来无事,学习下手机直播相关的知识。其中ffmpeg是必不可少的,下面简单介绍下如何在Android Studio上搭建一个可用的ffmpeg开发环境。


0.前置条件

首先你要准备以下环境:

Android Studio:我用的是2.3.3版本的,然后尝试编译一个非常一般的apk,并可以编译通过

其他的Android Build Tools:CMake、LLDB、NDK,这些都可以在SDK Manager里面下载到,如下图


编译出的ffmpeg的so文件:如何编译ffmpeg网上教程很多,这里不再赘述了,我们需要编译出来的include、libavcodec-57.so、libavdevice-57.so、libavfilter-6.so、libavformat-57.so、libavutil-55.so、libswresample-2.so、libswscale-4.so


1.新建工程,勾选C++ Support,然后无脑下一步,完成(有一步会有两个复选框和一个下拉框,下拉框是编译工具、复选框一个是C++异常处理,一个是运行时支持)


新建出来的工程应该是可以直接运行的,其中已经包含了C++代码和Jni调用,大家可以先看一下。


2.添加ffmpeg到Android工程,在项目根目录中新建ffmpeg文件夹,将我们编译好的so文件按照如下文件结构复制进去 


3.修改CMakeLists.txt,添加ffmpeg模块

# For more information about using CMake with Android Studio, read the# documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.cmake_minimum_required(VERSION 3.4.1)# Creates and names a library, sets it as either STATIC# or SHARED, and provides the relative paths to its source code.# You can define multiple libraries, and CMake builds them for you.# Gradle automatically packages shared libraries with your APK.set(FFMPEG_HOME ${CMAKE_SOURCE_DIR}/../ffmpeg)add_library( # Sets the name of the library.             native-lib             # Sets the library as a shared library.             SHARED             # Provides a relative path to your source file(s).             src/main/cpp/native-lib.cpp )# Searches for a specified prebuilt library and stores the path as a# variable. Because CMake includes system libraries in the search path by# default, you only need to specify the name of the public NDK library# you want to add. CMake verifies that the library exists before# completing its build.find_library( # Sets the name of the path variable.              log-lib              # Specifies the name of the NDK library that              # you want CMake to locate.              log )# Import ffmpeg partadd_library( avcodec             SHARED             IMPORTED )set_target_properties( avcodec                       PROPERTIES IMPORTED_LOCATION                       ${FFMPEG_HOME}/libs/${ANDROID_ABI}/libavcodec-57.so )add_library( avdevice             SHARED             IMPORTED )set_target_properties( avdevice                       PROPERTIES IMPORTED_LOCATION                       ${FFMPEG_HOME}/libs/${ANDROID_ABI}/libavdevice-57.so )add_library( avfilter             SHARED             IMPORTED )set_target_properties( avfilter                       PROPERTIES IMPORTED_LOCATION                       ${FFMPEG_HOME}/libs/${ANDROID_ABI}/libavfilter-6.so )add_library( avformat             SHARED             IMPORTED )set_target_properties( avformat                       PROPERTIES IMPORTED_LOCATION                       ${FFMPEG_HOME}/libs/${ANDROID_ABI}/libavformat-57.so )add_library( avutil             SHARED             IMPORTED )set_target_properties( avutil                       PROPERTIES IMPORTED_LOCATION                       ${FFMPEG_HOME}/libs/${ANDROID_ABI}/libavutil-55.so )add_library( swresample             SHARED             IMPORTED )set_target_properties( swresample                       PROPERTIES IMPORTED_LOCATION                       ${FFMPEG_HOME}/libs/${ANDROID_ABI}/libswresample-2.so )add_library( swscale             SHARED             IMPORTED )set_target_properties( swscale                       PROPERTIES IMPORTED_LOCATION                       ${FFMPEG_HOME}/libs/${ANDROID_ABI}/libswscale-4.so )include_directories(${FFMPEG_HOME}/include/)# Specifies libraries CMake should link to your target library. You# can link multiple libraries, such as libraries you define in this# build script, prebuilt third-party libraries, or system libraries.target_link_libraries( # Specifies the target library.                       native-lib                       avcodec                       avdevice                       avfilter                       avformat                       avutil                       swresample                       swscale                       # Links the target library to the log library                       # included in the NDK.                       ${log-lib} )

4.添加测试代码(接下来会解决我遇到的一些问题

在MainActivity中添加一个native方法string2FromJNI,然后点击左侧红色感叹号,让IDE自动生成C++对应方法,生成后会是多出这部分代码

JNIEXPORT jstring JNICALLJava_coding_yu_helloffmpeg_MainActivity_string2FromJNI(JNIEnv *env, jobject instance) {    return env->NewStringUTF(result);}


然后我们稍加修改,返回ffmpeg的编译信息,改成如下样子

#include "libavcodec/avcodec.h"extern "C"JNIEXPORT jstring JNICALLJava_coding_yu_helloffmpeg_MainActivity_string2FromJNI(JNIEnv *env, jobject instance) {    char info[10000] = {0};    sprintf(info, "%s\n", avcodec_configuration());    return env->NewStringUTF(info);}

在loadLibrary中添加avcodec-57,然后让textview显示这个方法返回内容,然后点击运行按钮。。。然后遇到一堆问题。。。这些问题都是依次出现的,我就一起说了吧。

问题1:提示不能解决mips的依赖

解决方法:在gradle的defaultConfig中添加ndk平台指定

ndk {    abiFilters "armeabi"}

原因分析:因为当时编译的时候只编译了arm的ffmpeg二进制库,因此咱们只创建了armeabi文件夹,详情在第二步。编译器为什么会去找其他平台的呢?因为在CMakeLists.txt文件中有个变量是这样写的 /libs/${ANDROID_ABI}/libswscale-4.so,详情见第三步。因此我们只要指定apk的abi平台即可。


问题2:loadLibrary失败,Link不到 avcodec-57.so

解决方法:在app/src/main下新建jniLibs,将armeabi复制进去

原因分析:不是工程下已经导入了ffmpeg的so和include了么?为什么找不到?咱们在第二步导入的是编译用的,apk打包并不会打进去,Studio默认会把jniLibs的so打入apk,加上可以了(和集成第三方API的so一致)


问题3:avcodec_configuration方法未定义、string2FromJNI方法未实现

解决方法:添加extern “C”标识,修改后效果如下

#include <jni.h>#include <string>extern "C" {#include "libavcodec/avcodec.h"}extern "C"JNIEXPORT jstring JNICALLJava_coding_yu_helloffmpeg_MainActivity_string2FromJNI(JNIEnv *env, jobject instance) {    char info[10000] = {0};    sprintf(info, "%s\n", avcodec_configuration());    return env->NewStringUTF(info);}extern "C"JNIEXPORT jstring JNICALLJava_coding_yu_helloffmpeg_MainActivity_stringFromJNI(        JNIEnv *env,        jobject /* this */) {    std::string hello = "Hello from C++";    return env->NewStringUTF(hello.c_str());}

然后应该没啥问题了吧。。。

这是项目地址:https://github.com/yuruxuan/HelloFFMpeg




阅读全文
0 0
原创粉丝点击