专栏首页包子的书架FFmpeg4.0.2编译32位和64位动态库,并且引入到Android项目中
原创

FFmpeg4.0.2编译32位和64位动态库,并且引入到Android项目中

前言

近期刚好用到FFmpeg来处理视频编码,由于网上各种版本的so库大部分都32位的,所以打算自己来编译32位和64位的库,我之前有写编译32位的库https://cloud.tencent.com/developer/article/1661468里面有关于ndk和32位的相关配置。今天主要是总结一下FFmpeg的64位的动态库编译。

资料

版本下载:http://ffmpeg.org/releases/

FFmpeg的相关选项的介绍:https://blog.csdn.net/yzhang6_10/article/details/77104211?utm_source=blogxgwz7

回顾32位库的编译

先看看32位的编译脚本:采用的ndk14b的,编译版本是Android6.0,编译的abi是arm-linux-androideabi,sysroot是$NDK/platforms/android-21/arch-arm/ , ARCH是arm

#!/bin/bash
# 清空上次的编译
make clean
#你自己的NDK路径。
export NDK=/usr/ndk/android-ndk-r14b
# 设置你的android平台编译器的版本 这里采用Android6.0 
export SYSROOT=$NDK/platforms/android-21/arch-arm/
#编译使用的toolchain
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
export NDK_ABI=arm-linux-androideabi
export CROSS=$TOOLCHAIN/bin/$NDK_ABI-
export ARCH=arm
export CPU=armv7a
# 这个是输出的路径
export PREFIX=$(pwd)/android/$CPU
export ADDI_CFLAGS="-marm"

function build_one
{
./configure \
--target-os=linux \
--prefix=$PREFIX \
--arch=$ARCH \
--disable-doc \
--enable-shared \
--disable-static \
--disable-asm \
--enable-pic \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
--disable-encoders \
--disable-muxers \
--enable-avresample \
--disable-pthreads \
--cross-prefix=$TOOLCHAIN/bin/$NDK_ABI- \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}

rm -rf $PREFIX
make distclean
build_one

瞅瞅64位的编译脚本

64位的编辑内容和32位不同的地方在:64位的编译脚本:编译的abi是aarch64-linux-android, SYSROOT是$NDK/platforms/android-21/arch-arm64/, TOOLCHAIN的要采用aarch64-linux-android-4.9, ARCH是aarch64

#!/bin/bash
# 清空上次的编译
make clean
#你自己的NDK路径。
export NDK=/usr/ndk/android-ndk-r14b
# 设置你的android平台编译器的版本 这里采用Android6.0 
export SYSROOT=$NDK/platforms/android-21/arch-arm64/
#编译使用的toolchain
export TOOLCHAIN=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64
export NDK_ABI=aarch64-linux-android
export CROSS=$TOOLCHAIN/bin/$NDK_ABI-
export ARCH=aarch64
export CPU=arm64
# 这个是输出的路径
export PREFIX=$(pwd)/android/$CPU
#export ADDI_CFLAGS="-marm=$CPU"


function build_one
{
./configure \
--target-os=linux \
--prefix=$PREFIX \
--arch=$ARCH \
--disable-doc \
--enable-shared \
--disable-static \
--disable-asm \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--enable-avresample \
--disable-symver \
--cross-prefix=$TOOLCHAIN/bin/$NDK_ABI- \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-fPIE -pie" \
--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
}

rm -rf $PREFIX
make distclean
build_one

编译过程出现的问题

  • 问题一:
image.png

解决方法:将libavcodec/aaccoder.c文件B0变量替换成b0

  • 问题二:
image.png

解决方法:将libavcodec/hevc_mvs.c文件的变量B0改成b0,xB0改成xb0,yB0改成yb0

  • 问题三
image.png

解决方法:将libavcodec/opus_pvq.c文件的变量B0改成b0

32位和64位编译后

分别得到arm64和armv7a的像个项目

image.png

导入到Android项目中

  • 这边以导入64位的为例子, Android studio为4.0 1.将生成的动态库和头文件放到项目libs下
image.png

2.配置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)


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 )

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 )

set(LIB_PATH ${PROJECT_SOURCE_DIR}/../../../libs)
include_directories(${LIB_PATH}/include)
set(DIR  ${LIB_PATH}/${ANDROID_ABI})

MESSAGE("路径==" ${LIB_PATH})
MESSAGE("路径==" ${DIR})

# 开始添加FFmpeg的相关库的依赖
# 添加编码库
add_library(avcodec-58
            SHARED
            IMPORTED)

set_target_properties(
        avcodec-58
        PROPERTIES IMPORTED_LOCATION
        ${DIR}/libavcodec-58.so
)

# 添加各种设备的输入输出的库
add_library(avdevice-58
            SHARED
            IMPORTED)

set_target_properties(
        avdevice-58
        PROPERTIES IMPORTED_LOCATION
        ${DIR}/libavdevice-58.so
)

# 添加滤镜特效处理库
add_library(avfilter-7
        SHARED
        IMPORTED)

set_target_properties(
        avfilter-7
        PROPERTIES IMPORTED_LOCATION
        ${DIR}/libavfilter-7.so
)

#  添加封装格式处理库
add_library(avformat-58
        SHARED
        IMPORTED)

set_target_properties(
        avformat-58
        PROPERTIES IMPORTED_LOCATION
        ${DIR}/libavformat-58.so
)

#  添加工具库
add_library(avutil-56
        SHARED
        IMPORTED)

set_target_properties(
        avutil-56
        PROPERTIES IMPORTED_LOCATION
        ${DIR}/libavutil-56.so
)

#  添加
add_library(avresample-4
        SHARED
        IMPORTED)

set_target_properties(
        avresample-4
        PROPERTIES IMPORTED_LOCATION
        ${DIR}/libavresample-4.so
)

#  添加音频采样数据格式转换库
add_library(swresample-3
        SHARED
        IMPORTED)

set_target_properties(
        swresample-3
        PROPERTIES IMPORTED_LOCATION
        ${DIR}/libswresample-3.so
)

#  添加音频采样数据格式转换库
add_library(swscale-5
        SHARED
        IMPORTED)

set_target_properties(
        swscale-5
        PROPERTIES IMPORTED_LOCATION
        ${DIR}/libswscale-5.so
)


# 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-58
                       avdevice-58
                       avfilter-7
                       avformat-58
                       avutil-56
                       avresample-4
                       swresample-3
                       swscale-5
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

3.build.gradle 的配置(这边是因为只导入64位的,所以需要配置):

 externalNativeBuild {
      cmake {
        cppFlags "-frtti -fexceptions"
        abiFilters "arm64-v8a"//, "armeabi-v7a" //, "arm64-v8a", "x86", "x86_64"
      }
    }

    ndk{
      abiFilters "arm64-v8a"
    }

4.Java代码中的加载FFmpeg的库

  static {
    System.loadLibrary("avcodec-58");
    System.loadLibrary("avdevice-58");
    System.loadLibrary("avfilter-7");
    System.loadLibrary("avformat-58");
    System.loadLibrary("avutil-56");
    System.loadLibrary("avresample-4");
    System.loadLibrary("swresample-3");
    System.loadLibrary("swscale-5");
    System.loadLibrary("native-lib");
  }

导入到项目中配到的问题

问题:编译的时候报

More than one file was found with OS independent path 'lib/arm64-v8a/libavformat-58.so'

解决方法:在build.gradle下添加

android{
    ....
    packagingOptions {
    pickFirst 'lib/arm64-v8a/libavcodec-58.so'
    pickFirst 'lib/arm64-v8a/libavdevice-58.so'
    pickFirst 'lib/arm64-v8a/libavfilter-7.so'
    pickFirst 'lib/arm64-v8a/libavformat-58.so'
    pickFirst 'lib/arm64-v8a/libavresample-4.so'
    pickFirst 'lib/arm64-v8a/libavutil-56.so'
    pickFirst 'lib/arm64-v8a/libswresample-3.so'
    pickFirst 'lib/arm64-v8a/libswscale-5.so'
  }
}

结语

以上就是编译FFmpeg的32位和64位动态库,以及导入android项目的使用的内容。关于FFmpeg的编译真的很麻烦,如果需要编译某个版本,以及对应需要的库包:尽量确认下,ndk的版本,编译的选项的内容。以上是个人的一些FFmpeg的使用经验和大家分享,有问题欢迎指出。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • FFmpeg4.0.2 编译成Android动态库

    近期需要用到FFmpeg的库,来做视频流的处理,今天尝试实现了一下,手动编译FFmpeg,然后引入到Android项目去使用。

    包子388321
  • 浅谈Lifecycle的原理,以及liveData在Lifecycle的扮演者

    我们知道jetpack出现给android开发带来很大的便利,尤其是Lifecycle带来的方便,作为一个有志向的码农,就应该了解一下Lifecycle的原理

    包子388321
  • Assets和res目录的区别

    立一个Android项目后会产生assets与res的两个文件夹,理论上他们都是存放资源的文件夹,那么他们到底有什么区别呢?

    包子388321
  • Django model转字典的几种方法

    这种方法的好处是方便控制最终返回字典value的格式,例如对于User表,我想返回最终的数据是id、创建时间、中文名、上级中文名、所属组名列表的话可以用下边的代...

    37丫37
  • python sorted 和 lamb

    dict = [ {'id':'4','name':'b'}, {'id':'6','name':'c'}, {'id':'3','name':'a'}, {'...

    py3study
  • Launchpad中图标的删除

    从App Store中下载的软件,可以通过按住Option按键然后图标右上角出现❌号进行删除。但是,如果右上角没有❌号怎么办呢? macOS中的Launch...

    卡尔曼和玻尔兹曼谁曼
  • 自然数到底可以表示到多大?

      小朋友都对巨大的数有一种天然的憧憬,以至于很多人都会想过这么一个问题,我们可以表示出多大的数?

    窗户
  • dubbo provider是如何启动的

    Netty支持多种服务端的server实例,包括mina、netty等,如下所示:

    luoxn28
  • 零基础使用Django2.0.1打造在线教育网站(十六):列表分页功能

    努力与运动兼备~~~有任何问题可以加我好友或者关注微信公众号,欢迎交流,我们一起进步!

    编程思录
  • python小代码之阶乘求和

    阶乘:也是数学里的一种术语;阶乘指从1乘以2乘以3乘以4一直乘到所要求的数;在表达阶乘时,就使用“!”来表示。如h阶乘,就表示为h!;阶乘一般很难计算,因为积都...

    py3study

扫码关注云+社区

领取腾讯云代金券