NO.5 FFmpeg 4.2.2 集成

10 篇文章 0 订阅 ¥79.90 ¥99.00
本文详细介绍了如何将FFmpeg 4.2.2集成到Android应用中,包括生成Android.so包的步骤、Android Studio 3.5的配置以及测试过程。在生成.so文件时,强调了配置configure文件的重要性,并提供了使用特定版本NDK(NDK-r20b)的建议。接着,文章说明了在Android Studio中添加jniLibs和配置CMakeList.txt的细节。最后,讨论了NDK编写的测试部分,提醒注意头文件的包含路径。附带了相关资源链接以帮助读者完成整个集成过程。
摘要由CSDN通过智能技术生成

零蚀


生成Android.so包

  • step 1

    下载开发包

    [🔗 ffmpeg 安装包下载]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T0rA179w-1586757565653)(media/15866172495096/15866175607201.jpg)]

  • step 2

    打包生成支持Android平台的.so动态库(重点)

    这里如果失败,后面一路飘红,走向无尽深渊。所以要认真对待每一个步骤。而且,也许你能打包成功,有了你想要的所有文件,但是当你跑上手机,那就是另一个美丽的故事了:可能缺少libnative.so,可能nijia报错,可能你的libxxx_arm_android_xxx.so库找不到,或者直接闪退,不给报错。

    开始之前你要配置下载的configure文件内容(没错就是改执行文件的操作内容)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ne59RwF1-1586757565654)(media/15866172495096/15867544399255.jpg)]

    首先找到CMDLINE_SET可以找到以下代码,然后新增一个命令行选项:cross_prefix_clang

    CMDLINE_SET="
        $PATHS_LIST
        ar
        arch
        as
        assert_level
        ....
        cross_prefix
        # 新增命令行参数
        cross_prefix_clang
        .....
    "
    

    修改编译工具路径设置,搜索 ar_default="${cross_prefix}${ar_default}"修改cc_default&cxx_default

    原有内容

    ar_default="${cross_prefix}${ar_default}"
    # 原始内容 cc_default="${cross_prefix}${cc_default}"
    # 原始内容 cxx_default="${cross_prefix}${cxx_default}"
    # ---------------修改内容------------------------
    cc_default="${cross_prefix_clang}${cc_default}"
    cxx_default="${cross_prefix_clang}${cxx_default}"
    # ----------------------------------------------
    nm_default="${cross_prefix}${nm_default}"
    pkg_config_default="${cross_prefix}${pkg_config_default}"
    

    需要看一下 ./configure 看看缺少什么,(如果没有yasm/nasm下载以下工具,着主要是为了提高效率使用了汇编指令)其次./configure会补充你缺少的文件

    brew install yasm
    
    

    或者选择不用

    // 屏蔽掉yasm
    ./configure --disable-x86asm
    

    然后不能用自己的ndk可能不匹配,会有一系列的问题,每个版本的ndk改动都不一样所以,这里我一开始使用的ndk21,这里打包虽然没问题,但是后面配置运行就会无限深渊,所以,这里使用ndk-r20b,然后放在一个方便的位置(我这里将自己as的ndk也改为了20)。

    [🔗 NDK-R20b的下载链接]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0fglGaYu-1586757565654)(media/15866172495096/15867551858972.jpg)]

    在下载的文件ffmpeg根文件下创建一个build_android.sh文件。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TktCFQjh-1586757565654)(media/15866172495096/15867552743195.jpg)]

    执行 ./build_android.sh

    # 将sh文件设置为all可执行
    ➜  ffmpeg-4.2.2 chmod a+x build_android.sh
    # 运行脚本
    ➜  ffmpeg-4.2.2 ./build_android.sh 
    

    build_android.sh内容

    #!/bin/bash
    #这个配置生成的是一整套完整功能的库,没有剪裁掉功能
    #cd ffmpeg-4.2.2#在ffmpeg所在路径下编译
    
    set -x
    # 目标Android版本
    API=21
    CPU=armv7-a
    # 记得换成自己的路径
    NDK_PATH=/Users/{client_your_name}/Desktop/ffmpeg-4.2.2/android-ndk-r20b 
    # 编译工具链路径
    TOOLCHAIN=$NDK_PATH/toolchains/llvm/prebuilt/darwin-x86_64
    # 编译环境
    SYSROOT=$TOOLCHAIN/sysroot
    #这里是写你输出文件要存放的位置
    PREFIX=/Users/{client_your_name}/Desktop/ffmpeg-4.2.2/android/armeabi-v7a
    
    function configure_deal
    {
      ./configure \
      --prefix=$PREFIX \
      --target-os=android \
      --arch=arm \
      --cpu=armv7-a \
      --enable-asm \
      --enable-neon \
      --enable-cross-compile \
      --enable-shared \
      --disable-static \
      --disable-doc \
      --disable-ffplay \
      --disable-ffprobe \
      --disable-symver \
      --disable-ffmpeg \
      --sysroot=$SYSROOT \
      --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
      --cross-prefix-clang=$TOOLCHAIN/bin/armv7a-linux-androideabi$API- \
      --extra-cflags="-fPIC"
    
    }
    
    function build
    {
        configure_deal
        make clean
        # 设置运行的cpu核数
        make -j4
        make install
    }
    
    build
    
    
    

    ⚠️ 如果出现以下情况,说明你打包这个流程没问题,但是不一定会产生so库,如果没有生成so库,你要想想自己的build_android.sh这个脚本是不是哪里有问题里(就像如果你脚本里少写了个function关键字,程序是不报错的,甚至能像模像样走完,且不报错,但是就没有文件生成)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sn2YpFQZ-1586757565655)(media/15866172495096/15867555586123.jpg)]

    运行后会根据PREFIX路径生成文件,然后就是我们导入需要的文件,到此打包环节就结束了。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6H1z9C0q-1586757565655)(media/15866172495096/15867556640298.jpg)]


Android Studio 3.5 配置

  • 添加jniLibs

    其实是可以将so库到添加libs中的,但是我不想多添加代码,多一步,可能多错一步,所以采用jniLibs了,如果你用libs的话需要添加如下代码:

    //导入app/libs下库
    sourceSets.main {
        jniLibs.srcDirs = ['libs']
        jni.srcDirs = []
    }
    

    lib动态库介绍:

    • avcodes:编码库
    • avformat:封装格式处理
    • avfliter:滤镜特效处理
    • avdevice:设备的各种输入输出
    • avutil:工具库(格式算法,加解密算法etc)
    • swresample:音频采样数据格式转换
    • swscale: 视屏像素格式转换

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXZaqv7C-1586757565655)(media/15866172495096/15867558843821.jpg)]

    jniLibs大家清楚,最好不要在其中创建子目录,因为程序会直接根据其中的各个兼容的平台来区分so库。所以这里命名一定要是armeabi-v7a(这里目前已经不再支持armeabi)

    配置CMakeList.txt

    cmake_minimum_required(VERSION 3.4.1)
    
    # 支持gnu++11
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
    
    # 1. 定义so库和头文件所在目录,方面后面使用
    set(ffmpeg_lib_dir ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
    set(ffmpeg_head_dir ${CMAKE_SOURCE_DIR}/ffmpeg)
    
    # 2. 添加头文件目录
    include_directories(${ffmpeg_head_dir}/include)
    
    # 3. 添加ffmpeg相关的so库
    add_library( avutil
            SHARED
            IMPORTED )
    set_target_properties( avutil
            PROPERTIES IMPORTED_LOCATION
            ${ffmpeg_lib_dir}/libavutil.so )
    
    add_library( swresample
            SHARED
            IMPORTED )
    set_target_properties( swresample
            PROPERTIES IMPORTED_LOCATION
            ${ffmpeg_lib_dir}/libswresample.so )
    
    add_library( avcodec
            SHARED
            IMPORTED )
    set_target_properties( avcodec
            PROPERTIES IMPORTED_LOCATION
            ${ffmpeg_lib_dir}/libavcodec.so )
    
    add_library( avfilter
            SHARED
            IMPORTED)
    set_target_properties( avfilter
            PROPERTIES IMPORTED_LOCATION
            ${ffmpeg_lib_dir}/libavfilter.so )
    
    add_library( swscale
            SHARED
            IMPORTED)
    set_target_properties( swscale
            PROPERTIES IMPORTED_LOCATION
            ${ffmpeg_lib_dir}/libswscale.so )
    
    add_library( avformat
            SHARED
            IMPORTED)
    set_target_properties( avformat
            PROPERTIES IMPORTED_LOCATION
            ${ffmpeg_lib_dir}/libavformat.so )
    
    add_library( avdevice
            SHARED
            IMPORTED)
    set_target_properties( avdevice
            PROPERTIES IMPORTED_LOCATION
            ${ffmpeg_lib_dir}/libavdevice.so )
    
    
    
    # 查找代码中使用到的系统库
    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 )
    
    # 配置目标so库编译信息
    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).
            native-lib.cpp
            )
    
    # 指定编译目标库时,cmake要链接的库
    target_link_libraries(
    
            # 指定目标库,native-lib 是在上面 add_library 中配置的目标库
            native-lib
    
            # 4. 连接 FFmpeg 相关的库
            avutil
            swresample
            avcodec
            avfilter
            swscale
            avformat
            avdevice
    
            # Links the target library to the log library
            # included in the NDK.
            ${log-lib} )
    

    gradle添加ffmpeg的配置平台

    android {
        ......
        defaultConfig {
            ......
            externalNativeBuild {
                cmake {
                    cppFlags ""
                    abiFilters 'armeabi-v7a'
                }
    
            }
        }
       .....
        externalNativeBuild {
            cmake {
                path "src/main/cpp/CMakeLists.txt"
                version "3.10.2"
            }
        }
    }
    

    rebuild & make project


测试

  • NDK 编写

    ⚠️ 在这里首先看看你的include能否搜到头文件,这里要注意的是,所有关于ffmpeg的include都要在extern "C"{}的作用域内,这样就可以使用,如果在作用域外,自求多福。

    #include <jni.h>
    #include <string>
    
    extern "C"{
        #include "libavcodec/avcodec.h"
        JNIEXPORT jstring JNICALL
        Java_com_example_ffmpeg_MainActivity_stringFromJNI(
                JNIEnv *env,
                jobject /* this */) {
    
            # 获取信息
            auto string = avcodec_configuration();
            return env->NewStringUTF(string);
        }
    
    }
    

    打印

    static {
        System.loadLibrary("native-lib");
    }
     public native String stringFromJNI();
     
     .....
     tv.setText(stringFromJNI());
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6zTUWdGP-1586757565656)(media/15866172495096/WechatIMG3.jpeg)]

    我将所需的文件内容都已经上传,需要的自领🔗 ffmpeg4.2.2百度网盘链接] 密码:w9rm

    想了解build_android.sh怎么编写,看看configure的源码,里面有关于脚本编写的所有内容。(在这种配置上,浪费一天的时间,是件血亏的事情,心里憋了一天的mmp,可不舒服了,如果我再牛逼一点<指尖宇宙>,我肯定自己做一个比这更牛逼(傻瓜式)的东西)


🔗 前言
🔗 Android NDK列表
🔗 NO.1 Android NDK 前言
🔗 NO.2 Android CMake
🔗 NO.3 JNI调用java成员
🔗 NO.4 NDK常见函数&音视频初
🔗 NO.6 FFmpeg 4.2视频转码
🔗 NO.7 SDL2.0.12 播放本地YUV视频
🔗 NO.8 音频处理
🔗 NO.9 播放音频
🔗 NO.10 FFmpeg添加水印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零蚀zero eclipse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值