前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >FFmpeg4.0.2编译32位和64位动态库,并且引入到Android项目中

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

原创
作者头像
包子388321
修改2020-07-15 09:58:44
2.5K0
修改2020-07-15 09:58:44
举报
文章被收录于专栏:包子的书架

前言

近期刚好用到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

代码语言:txt
复制
#!/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

代码语言:txt
复制
#!/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
image.png

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

  • 问题二:
image.png
image.png

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

  • 问题三
image.png
image.png

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

32位和64位编译后

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

image.png
image.png

导入到Android项目中

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

2.配置CMakeLists.txt,引入FFmpeg的库

代码语言:txt
复制
# 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位的,所以需要配置):

代码语言:txt
复制
 externalNativeBuild {
      cmake {
        cppFlags "-frtti -fexceptions"
        abiFilters "arm64-v8a"//, "armeabi-v7a" //, "arm64-v8a", "x86", "x86_64"
      }
    }

    ndk{
      abiFilters "arm64-v8a"
    }

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

代码语言:txt
复制
  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");
  }

导入到项目中配到的问题

问题:编译的时候报

代码语言:txt
复制
More than one file was found with OS independent path 'lib/arm64-v8a/libavformat-58.so'

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

代码语言:txt
复制
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的使用经验和大家分享,有问题欢迎指出。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 资料
  • 回顾32位库的编译
  • 瞅瞅64位的编译脚本
  • 编译过程出现的问题
  • 32位和64位编译后
  • 导入到Android项目中
  • 导入到项目中配到的问题
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档