使用Android Studio开发FFmpeg的正确姿势

原文地址:https://www.jianshu.com/p/0a7f3175c1b9

2018-04-21: 更新至 ffmpeg-4.0

使用AndroidStudio 开发 FFmpeg
Keywords: gradle, cmake
关键步骤,编译FFmpeg,Android Studio 集成。

abi support: armeabi armeabi-v7a arm64-v8a x86 x86_64
ndk version android-ndk-r14b

export NDK_HOME=/opt/android/android-ndk-r14b
export NDK_HOST_PLATFORM=linux-x86_64

第一步,编译ffmpeg


首先下载并解压

wget https://ffmpeg.org/releases/ffmpeg-4.0.tar.bz2
tar xvf ffmpeg-4.0.tar.bz2

然后编写编译脚本

#!/bin/sh

PREFIX=android-build

COMMON_OPTIONS="\
    --prefix=android/ \
    --target-os=android \
    --disable-static \
    --enable-shared \
    --enable-small \
    --disable-programs \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-doc \
    --disable-symver \
    --disable-asm \
    "

function build_android {
    ./configure \
    --libdir=${PREFIX}/libs/armeabi-v7a \
    --incdir=${PREFIX}/includes/armeabi-v7a \
    --pkgconfigdir=${PREFIX}/pkgconfig/armeabi-v7a \
    --arch=arm \
    --cpu=armv7-a \
    --cross-prefix="${NDK_HOME}/toolchains/arm-linux-androideabi-4.9/prebuilt/${NDK_HOST_PLATFORM}/bin/arm-linux-androideabi-" \
    --sysroot="${NDK_HOME}/platforms/android-19/arch-arm/" \
    --extra-cflags="-march=armv7-a -mfloat-abi=softfp -mfpu=neon" \
    --extra-ldexeflags=-pie \
    ${COMMON_OPTIONS}
    make clean
    make -j8 && make install

    ./configure \
    --libdir=${PREFIX}/libs/arm64-v8a \
    --incdir=${PREFIX}/includes/arm64-v8a \
    --pkgconfigdir=${PREFIX}/pkgconfig/arm64-v8a \
    --arch=aarch64 \
    --cpu=armv8-a \
    --cross-prefix="${NDK_HOME}/toolchains/aarch64-linux-android-4.9/prebuilt/${NDK_HOST_PLATFORM}/bin/aarch64-linux-android-" \
    --sysroot="${NDK_HOME}/platforms/android-21/arch-arm64/" \
    --extra-ldexeflags=-pie \
    ${COMMON_OPTIONS} 
    make clean
    make -j8 && make install

    ./configure \
    --libdir=${PREFIX}/libs/x86 \
    --incdir=${PREFIX}/includes/x86 \
    --pkgconfigdir=${PREFIX}/pkgconfig/x86 \
    --arch=x86 \
    --cpu=i686 \
    --cross-prefix="${NDK_HOME}/toolchains/x86-4.9/prebuilt/${NDK_HOST_PLATFORM}/bin/i686-linux-android-" \
    --sysroot="${NDK_HOME}/platforms/android-19/arch-x86/" \
    --extra-ldexeflags=-pie \
    ${COMMON_OPTIONS} 
    make clean
    make -j8 && make install

    ./configure \
    --libdir=${PREFIX}/libs/x86_64 \
    --incdir=${PREFIX}/includes/x86_64 \
    --pkgconfigdir=${PREFIX}/pkgconfig/x86_64 \
    --arch=x86_64 \
    --cpu=x86_64 \
    --cross-prefix="${NDK_HOME}/toolchains/x86_64-4.9/prebuilt/${NDK_HOST_PLATFORM}/bin/x86_64-linux-android-" \
    --sysroot="${NDK_HOME}/platforms/android-21/arch-x86_64/" \
    --extra-ldexeflags=-pie \
    ${COMMON_OPTIONS}
    make clean
    make -j8 && make install

};

build_android

此脚本实现了armeabi-v7a,arm64-v8a,x86,x86_64 4个平台的编译。

  • 需要添加系统环境变量 $NDK_PATH
  • --target-os=android指定android平台。
  • make install-libs 表示只安装so文件

编译完成结果:

ffmpeg

第二步,项目集成


  • 新建项目,增加C++支持。手动创建jniLibs文件夹
  • 然后将上一步生成的所有文件复制到jniLibs文件夹下面
    最终目录结构:

project


然后修改CMakeLists.txt文件,集成so

cmake_minimum_required(VERSION 3.4.1)

find_library(log-lib log)

add_library(native-lib
            SHARED
            src/main/cpp/native-lib.cpp )

set(JNI_LIBS_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs)

add_library(avutil
            SHARED
            IMPORTED )
set_target_properties(avutil
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavutil.so )

add_library(swresample
            SHARED
            IMPORTED )
set_target_properties(swresample
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libswresample.so )

add_library(swscale
            SHARED
            IMPORTED )
set_target_properties(swscale
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libswscale.so )

add_library(avcodec
            SHARED
            IMPORTED )
set_target_properties(avcodec
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavcodec.so )

add_library(avformat
            SHARED
            IMPORTED )
set_target_properties(avformat
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavformat.so )

add_library(avfilter
            SHARED
            IMPORTED )
set_target_properties(avfilter
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavfilter.so )

add_library(avdevice
            SHARED
            IMPORTED )
set_target_properties(avdevice
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavdevice.so )

include_directories(${JNI_LIBS_DIR}/includes)

target_link_libraries(native-lib
                      avutil swresample swscale avcodec avformat avfilter avdevice
                      ${log-lib} )

简要说明:

最后再放出效果图:

FFPlayerDemo

示例代码:https://github.com/coopsrc/FFPlayerDemo



作者:Coopsrc
链接:https://www.jianshu.com/p/0a7f3175c1b9
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 

个人补充说明:

加添头文件的时候,要注意一下,不然会报undefined reference to `avcodec_configuration()'的错误。

因为ffmpeg是用C写的,所以在引用它的头文件的时候,需要用extern "c"包起来。

下面是具体的例子:

#include <jni.h>
#include <string>
#ifdef __cplusplus
    extern "C" {
#endif
    #include "libavcodec/avcodec.h"
#ifdef __cplusplus
    }
#endif

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_turner_iplayer_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = avcodec_configuration();//"Hello from C++";
    //std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

猜你喜欢

转载自blog.csdn.net/zdhsoft/article/details/84025909