Android --ffmpeg(三) 使用编译好的动态库

478 阅读1分钟

在Android项目中使用ffmpeg

  • 新建一个Module

image.png

  • 选择Android Native Library image.png

  • src->main目录下新建jniLibs

  • jniLibs目录下新建 arm64-v8a armeabi-v7a目录,将编译生成的lib目录下的动态库分别拷贝过来

image.png

  • 将编译生成的include 拷贝到cpp文件下

image.png

image.png

  • 修改CMakeLists.txt文件
cmake_minimum_required(VERSION 3.10.2)

project("ffmpeg")
# 包含头文件
include_directories(src/main/cpp/include)

add_library(
        native-lib
        SHARED
        src/main/cpp/ffmpeg.cpp)
add_library(avcodec SHARED IMPORTED)
set_target_properties(avcodec
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavcodec.so)
add_library(avdevice SHARED IMPORTED)
set_target_properties(avdevice
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavdevice.so)
add_library(avfilter SHARED IMPORTED)
set_target_properties(avfilter
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavfilter.so)
add_library(avformat SHARED IMPORTED)
set_target_properties(avformat
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavformat.so)
add_library(avutil SHARED IMPORTED)
set_target_properties(avutil
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libavutil.so)
add_library(swresample SHARED IMPORTED)
set_target_properties(swresample
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswresample.so)
add_library(swscale SHARED IMPORTED)
set_target_properties(swscale
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libswscale.so)


find_library(
        log-lib
        log)
target_link_libraries(
        native-lib
        ${log-lib}
        avcodec
        avdevice
        avfilter
        avformat
        avutil
        swresample
        swscale)
  • 在build.gradle中添加支持的平台
ndk {
    abiFilters "arm64-v8a", "armeabi-v7a"
}
  • 如果提示有多个动态库,添加如下代码
packagingOptions {
   pickFirst 'lib/arm64-v8a/libswscale.so'
   pickFirst 'lib/arm64-v8a/libavcodec.so'
   pickFirst 'lib/arm64-v8a/libavutil.so'
   pickFirst 'lib/arm64-v8a/libavformat.so'
   pickFirst 'lib/arm64-v8a/libavfilter.so'
   pickFirst 'lib/arm64-v8a/libswresample.so'
   pickFirst 'lib/arm64-v8a/libavdevice.so'
}
  • 在java中加载动态库
static {
    System.loadLibrary("native-lib");
    System.loadLibrary("avutil");
    System.loadLibrary("swresample");
    System.loadLibrary("avcodec");
    System.loadLibrary("avformat");
    System.loadLibrary("swscale");
    System.loadLibrary("avfilter");
    System.loadLibrary("avdevice");
}
  • 在cpp文件中获得配置信息,能成功显示则ffmpeg调用成功
#include <jni.h>
#include <string>
#include <android/log.h>
#define LOGI(FORMAT,...) __android_log_print(ANDROID_LOG_INFO,"cpp",FORMAT,##__VA_ARGS__);
#define LOGE(FORMAT,...) __android_log_print(ANDROID_LOG_ERROR,"cpp",FORMAT,##__VA_ARGS__);
extern "C" {
#include <libavcodec/avcodec.h>
}


extern "C" JNIEXPORT jstring JNICALL
Java_com_tdy_ffmpeg_NativeLib_stringFromJNI(
        JNIEnv* env,
        jclass clazz) {
    std::string config = avcodec_configuration();

    LOGE("configuration %s\n",config.c_str());

    return env->NewStringUTF(config.c_str());
}

image.png

注意#include <libavcodec/avcodec.h>,要用extern "C" {}括起来,因为ffmpeg是纯c写的,不括起来会报错无法使用