草庐IT

Android 音视频FFmpeg5.1.1编译

莫翊痕 2023-11-20 原文

学习音视频开发,记录FFmpeg编译过程.
编译环境: Ubuntu 20.04.2 LTS NDK:android-ndk-r22b

1.下载NDK https://developer.android.google.cn/ndk/downloads?hl=zh_cn
2.下载FFmpeg源码http://ffmpeg.org/download.html

这边是下载当前的最新版本 FFmpeg5.1.1

3.配置脚本
3.1修改 configure 脚本
  • 新增 cross_prefix_clang 参数
    解压下载好的源码,进入根目录找到configure 文件,搜索CMDLINE_SET找到下方代码块,新增 cross_prefix_clang参数.
CMDLINE_SET="
    $PATHS_LIST
    ar
    arch
    as
    assert_level
    build_suffix
    cc
    objcc
    cpu
    cross_prefix
    #新增命令
    cross_prefix_clang
    custom_allocator
    cxx
    dep_cc
    doxygen
    ...
  • 修改编译工具路径
    搜索 **ar_default=“${cross_prefix} ${ar_default}”**找到下方代码块
ar_default="${cross_prefix}${ar_default}"
cc_default="${cross_prefix}${cc_default}"
cxx_default="${cross_prefix}${cxx_default}"
nm_default="${cross_prefix}${nm_default}"
pkg_config_default="${cross_prefix}${pkg_config_default}"

将中间两行cc_default,cxx_default修改为

ar_default="${cross_prefix}${ar_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}"
  • 新建编译配置脚本
    FFmpeg5.1.1根目录,新建build_android_arm64-v8a_clang.sh的shell脚本.
#!/bin/bash

#配置你的NDK路径
export NDK=/home/moyihen/Desktop/android-ndk-r22b 
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64

function build_android
{

./configure \
--prefix=$PREFIX \
--enable-neon  \
--enable-hwaccels  \
--enable-gpl   \
--disable-postproc \
--disable-debug \
--enable-small \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-static \
--enable-shared \
--disable-doc \
--enable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-doc \
--disable-symver \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS"

make clean
make -j8
make install

echo "============================ build android arm64-v8a success =========================="

}

#arm64-v8a
ARCH=arm64
CPU=armv8-a
API=21
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"

build_android

4.开始编译

打开命令终端,切换到FFmpeg,输入./build_android_clang.sh,等待编译完成,将会在 ffmpeg-5.1.1/android/armv7-a目录下得到 include 和 lib 两个目录,分别是 头文件 和 so库文件(静态库.a看需求自取).



编译armv7a和arm64v8a ,修改对应shell脚本参数.

#arm64-v8a
ARCH=arm64
CPU=armv8-a
API=21
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"

#armv7-a
ARCH=arm
CPU=armv7-a
API=21
CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
5.集成FFmpeg验证编译状态

Android 支持C++的ndk项目,有2中创建方式:
1.新建支持C++项目
2.在原有不支持C++的Android项目,新增C++项目需要的配置.

5.1创建支持c++的项目

File => New => NewProject,选择Native C++类型创建项目.

5.2 配置ffmpeg动态库

把第4步编译的头文件和库文件复制到项目cpp和jniLibs目录.

5.3 配置CMakeLists.txt
cmake_minimum_required(VERSION 3.18.1)

# Declares and names the project.

project("ffmpegtest")

#设置库文件 头文件变量.
set(ffmpeg_lib_dir ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
set(ffmpeg_head_dir ${CMAKE_SOURCE_DIR}/ffmpeg)

#设置头文件目录
include_directories(${ffmpeg_head_dir}/include)

add_library( # Sets the name of the library.
        ffmpegtest
        # Sets the library as a shared library.
        SHARED
        # Provides a relative path to your source file(s).
        native-lib.cpp)

#ffmpeg----------------------------------------
#avcodec
add_library(avcodec
        SHARED
        IMPORTED)
set_target_properties(avcodec
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavcodec.so)
#avfilter
add_library(avfilter
        SHARED
        IMPORTED)
set_target_properties(avfilter
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavfilter.so)
#avformat
add_library(avformat
        SHARED
        IMPORTED)
set_target_properties(avformat
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavformat.so)
#avutil
add_library(avutil
        SHARED
        IMPORTED)
set_target_properties(avutil
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libavutil.so)
#swresample
add_library(swresample
        SHARED
        IMPORTED)
set_target_properties(swresample
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libswresample.so)
#swscale
add_library(swscale
        SHARED
        IMPORTED)
set_target_properties(swscale
        PROPERTIES IMPORTED_LOCATION
        ${ffmpeg_lib_dir}/libswscale.so)


find_library( # Sets the name of the path variable.
        log-lib
        log)

#指定编译目标库cmake链接的库
target_link_libraries( # Specifies the target library.
        ffmpegtest

        avcodec
        avfilter
        avformat
        avutil
        swresample
        swscale
        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})
5.4 编写测试代码

在默认创建native接口的MainActivity类新建ffmpegInfo()方法,按alt+enter选择Create JNI function for ffmpegInfo,快速生成ffmpegInfo()在native-lib.cpp的方法实现.

这边简单调用ffmpeg库的方法,测试编译库文件是否正常.注意include头文件要放在extern “C” {}里面,不然会报
error: undefined reference to ‘av_codec_iterate(void**)’
error: undefined reference to ‘av_codec_is_decoder(AVCodec const*)’

native-lib.cpp

extern "C" {
#include "ffmpeg/include/libavcodec/avcodec.h"
JNIEXPORT jstring JNICALL
Java_com_moyihen_ffmpegtest_MainActivity_ffmpegInfo(JNIEnv *env, jobject thiz) {

    char info[40000] = {0};
    //列举所有的编解码器
    void *p = nullptr;
    const AVCodec *c_temp;
    while ((c_temp = av_codec_iterate(&p))) {
        if (av_codec_is_decoder(c_temp)) {
            sprintf(info, "%sdecode => %s\n", info, c_temp->name);
        } else {
            sprintf(info, "%sencode => %s\n", info, c_temp->name);
        }
    }
    return env->NewStringUTF(info);
 }
}
  • 测试正常 能正常打印编解码器列表

end

有关Android 音视频FFmpeg5.1.1编译的更多相关文章

  1. ruby - Sinatra set cache_control to static files in public folder编译错误 - 2

    我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.

  2. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

  3. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  4. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  5. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  6. ruby - 无法在 Ruby 中将 ffmpeg 作为子进程运行 - 2

    我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope

  7. .net - 是否有 Ruby .NET 编译器? - 2

    是否有适用于Ruby语言的.NETFramework编译器?我听说过DLR(动态语言运行时),这是否将使Ruby能够用于.NET开发? 最佳答案 IronRuby是Microsoft支持的项目,建立在动态语言运行时之上。 关于.net-是否有Ruby.NET编译器?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/199638/

  8. ruby - 如何更改此正则表达式以从未指定 v 参数的 Youtube URL 获取 Youtube 视频 ID? - 2

    目前我正在使用这个正则表达式从YoutubeURL中提取视频ID:url.match(/v=([^&]*)/)[1]我怎样才能改变它,以便它也可以从这个没有v参数的YoutubeURL获取视频ID:http://www.youtube.com/user/SHAYTARDS#p/u/9/Xc81AajGUMU感谢阅读。编辑:我正在使用ruby​​1.8.7 最佳答案 对于Ruby1.8.7,这就可以了。url_1='http://www.youtube.com/watch?v=8WVTOUh53QY&feature=feedf'url

  9. python - 使用 Python、Ruby 和 Perl 重新编译 MacPort 版本的 MacVim - 2

    关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭10年前。ImprovethisquestionLinux专家正在转向Mac(10.8)。因为我懒...我使用MacPorts安装MacVim。它似乎安装没有错误。我只需要mvim中的python、ruby和perl支持。$/opt/local/bin/mvim--version|egrep'patches|python|ruby|perl'Includedpatches:1-244,246-646+multi_lang-mzscheme+

  10. ruby - 为什么 `middleman serve` 有效,但是 `middleman build` 编译这个 Sass 失败? - 2

    当我刚刚运行middleman时服务,all.css编译得很好,只包含对+box-shadow(none)的调用:/*line1,/home/yang/asdf/source/stylesheets/content.css.sass*/div{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;}但是当我构建网站时,我得到了这个Sass/Compass错误:$middlemanbuildSlim::EmbeddedEngineisdeprecated,itiscalledSlim::EmbeddedinSlim2.0

随机推荐