Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目

这篇具有很好参考价值的文章主要介绍了Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

最近在学习android NDK开发相关内容,借ffmpeg练练手。ffmpeg是做音视频方面功能的基础,后面会随着个人的学习更新一系列ffmpeg博客,防止自己遗忘。
这个系列博客主要目的是基于ffmpeg通过NDK开发的方式完成一个基本的视频播放器。

本篇博客主要实现了 ffmpeg编译 以及 引入 android 项目成功调用 静态库方法显示版本号。

必备基础

  1. c、c++基础语法;Cmake基础(常用配置、常量);
  2. NDK JNI基础(熟悉java/kotlin 、c++ 互调);
  3. kotlin基础(android 项目全部使用kotlin编写);
  4. linux常用命令、shell脚本基础语法;

准备工作

编译ffmpeg时使用Linux或者Mac都可以;如果是Mac需要安装gcc,使用gcc -v输出版本号即为成功。

ffmpeg(4.0.2)
ffmpeg全版本下载地址:
http://www.ffmpeg.org/releases/

NDK(android-ndk-r17c)
NDK历史版本下载地址:
https://developer.android.google.cn/ndk/downloads/older_releases

ffmpeg下载完成后解压缩;进入ffmpeg解压后到目录

cd ./ffmpeg-4.0.2

ffmpeg编译时有很多命令参数,查看命令参数命令:

./configure --help

编写ffmpeg编译脚本

为了方便直接在 ffmpeg-4.0.2 目录里新建shell脚本

vim ./ffmpeg-4.0.2/build_ffmpeg_4.0.2.sh

输入以下内容;
注意:每一行脚本都有对应的注释,需要仔细查看,直接复制可能会编译失败,NDK工具包的相关路径要改成自己的。
NDK_SRC 和 NDK_GCC 的目录可能不同!!!
NDK_GCC 的 arm-linux-androideabi-4.9 目录根据不同的平台路径不同 本次实现仅实现了armeabi-v7a平台!!!

#!/bin/bash

# NDK工具包目录
NDK_SRC=/Users/tttell/tools/android-ndk-r17c

# 此变量执行ndk中的交叉编译gcc所在目录
NDK_GCC=$NDK_SRC/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64

# 传递给gcc的参数 [从Android Project的 externalNativeBuild/xxx/build.ninja 中复制到参数 可以减少警告信息]
FLAGS="-isystem $NDK_SRC/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security  -O0 -fPIC"

# 导入必需的头文件 [NDK 工具包的目录]
INCLUDES=" -isystem $NDK_SRC/sources/android/support/include"

# 编译后输出的目录 [根据自己情况自定义目录]
PREFIX=./bulid_ffmpeg_lib

./configure \
--prefix=$PREFIX \
--enable-static \
--enable-small \
--enable-cross-compile \
--disable-programs \
--disable-avdevice \
--disable-encoders \
--disable-muxers \
--disable-filters \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--extra-cflags="$FLAGS $INCLUDES" \
--extra-cflags="-isysroot $NDK_SRC/sysroot/" \
--sysroot=$NDK_SRC/platforms/android-21/arch-arm \
--arch=arm \
--target-os=android

make clean

make install

# 参数注释
# --enable-static 				# 编译静态库
# --enable-small 				# 体积优化
# --enable-cross-compile 		# 开启交叉编译
# --disable-programs 			# 不编译ffmpeg命令行工具 [如果需要可以编译]
# --disable-avdevice 			# 不编译avdevice模块 [--help 提示中表示该模块不支持Android平台]
# --disable-encoders 			# 不编译编码器 [本系列仅实现播放功能 所以不需要编码]
# --disable-muxers  			# 不编译封装器 [本系列仅实现播放功能 所以不需要封装]
# --disable-filters 			# 不编译所有滤镜
# --cross-prefix 				# 指定使用NDK工具包中的gcc相关编译器
# --extra-cflags 				# gcc的参数
# --sysroot 					# 平台标准库 [具体根据android项目的平台、最低支持版本而定 本次实现仅编译了armeabi-v7a 最低支持sdk21	]
# --arch           				# 平台
# --target-os 					# 平台

开始执行脚本

sh ./ffmpeg-4.0.2/build_ffmpeg_4.0.2.sh

脚本运行时,要关注日志输出,如果出现error日志就及时停止吧 肯定会失败的 不用等到之行结束;编译过程可能会出现各种错误,具体错误可能跟环境也有关系,根据提示信息去搜索对应解决办法修改即可。

如果编译失败,输出目录中应该是空的,需要查看下终端的输出日志排查错误;
编译成功则会在你指定的输出目录下出现以下文件:
Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目
include 目录是待会需要导入到Android Project中的头文件;
lib 目录中就是成功编译出的静态库文件;
share 目录中的examples是一些例子 都是c语言的例子;

Android 项目集成

新建项目

Android Studio 版本 我这应该是最新的
Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目
新建一个支持Native的项目
Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目
Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目
然后一直下一步就可以了。

打开项目后需要在SDKManager中下载NDK和Cmake:
Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目
NDK 不用全部下载,我是为了调试不同版本全部下载了 下载21左右的就可以。
Cmake 下载的是最新版本的。

接着修改 app 目录的 build.gradle 文件:

android {

...

	defaultConfig {
		externalNativeBuild {
    		cmake {
        		abiFilters "armeabi-v7a"
    		}
		}
		ndk {
    		abiFilters("armeabi-v7a")
		}
	}
	
	# 为了开发方便不写findviewbyId 我开启了 databinding
	dataBinding {
        enabled = true
    }
...

}

下载完成后同步一下项目,运行下测试下 如果页面成功显示了 Hello from C++ 即为成功;

导入ffmpeg

将编译好的 ffmpeg 头文件目录 include 复制到 android project 的 cpp 目录下:
Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目
接着开始导入静态库,在 cpp 目录下新建 libs 目录;因为上一步骤中编译的是 armeabi-v7a 的 ffmpeg 所以在libs下新建 armeabi-v7a 目录(实际开发中会打多个平台的库文件,如:x86_64需要新建x86_64的目录)。将静态库文件复制到 armeabi-v7a 目录中:
Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目
导入工作完成后 开始编写 CMakeLists.txt :

cmake_minimum_required(VERSION 3.18.1)

project("studyffmepg")

# 导入 include目录的 库文件
# CMAKE_SOURCE_DIR 是常量 代表CMake文件所在目录
include_directories(${CMAKE_SOURCE_DIR}/include)

# 批量导入源文件 定义一个 SOURCE 变量
# 这样写在cpp目录下新建c++文件时不用再一个个写导入了
file(GLOB SOURCE *.cpp *.c)

# 添加动态库
add_library(
        studyffmepg # 生成库的名字
        SHARED      # SHARED 动态库 STATIC 静态库
        ${SOURCE}   # 源文件 上面定义的变量 表示全部打包进去
)

# 在NDK工具包中寻找 log 库
find_library(
        log-lib
        log
)

# 导入FFmpeg的库文件
# CMAKE_CXX_FLAGS 类似于 windows 环境变量中的 path;设置目录后会去目录下自动寻找库文件
# -L 代表追加目录
# CMAKE_ANDROID_ARCH_ABI 表示运行的平台(如:armeabi-v7a) 因为在 app:build.gradle中指定了平台所以这里可以读取到运行的平台
# 注意我这里的 -L 后的路径 /libs 对应上一步骤新建的目录 如果你的目录不同切记修改 否则会找不到依赖库
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}")

target_link_libraries(
        studyffmepg
        ${log-lib}
        # ffmpeg的静态库有依赖关系 使用 -Wl,--start-group -Wl,--end-group 方式写 可以忽略顺序 否则容易出错
        -Wl,--start-group
        libavcodec.a libavfilter.a libavformat.a libavutil.a libswresample.a libswscale.a
        -Wl,--end-group
)

完成之后同步一下。

集成测试

修改 native-lib.cpp 文件,输出一下 ffmpeg 的版本号

#include <jni.h>
#include <string>

using namespace std;

extern "C" {
#include <libavutil/avutil.h>
}

extern "C" JNIEXPORT jstring JNICALL
Java_top_sunhy_studyffmepg_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject jobj
) {
    //std::string hello = "Hello from C++";
    string s = "集成成功!FFmpeg Version:";
    s.append(av_version_info());

    return env->NewStringUTF(s.c_str());
}

完成后运行一下,出现版本号即为成功:
Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目文章来源地址https://www.toymoban.com/news/detail-402317.html

到了这里,关于Android ffmpeg入门(1)—— 使用NDK交叉编译ffmpeg集成到Android项目的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库

    ​ 《FFmpeg开发实战:从零基础到短视频上线》一书的“12.1.2  交叉编译Android需要的so库”介绍了如何在Windows环境交叉编译Android所需FFmpeg的so库,接下来介绍如何在Linux环境交叉编译Android所需FFmpeg的so库。 登录Linux服务器(比如华为云的欧拉系统),依次执行下面的命令。 重

    2024年03月24日
    浏览(50)
  • FFmpeg开发笔记(十六)Linux交叉编译Android的OpenSSL库

    ​ 《FFmpeg开发实战:从零基础到短视频上线》一书的例程主要测试本地的音视频文件,当然为了安全起见,很多网络视频都采用了https地址。FFmpeg若要访问https视频,就必须集成第三方的openssl库,但编译FFmpeg时却默认关闭了openssl。为了让App能够播放采用https的在线视频,需要

    2024年04月22日
    浏览(39)
  • FFmpeg开发笔记(九)Linux交叉编译Android的x265库

    ​ 《FFmpeg开发实战:从零基础到短视频上线》一书的“12.1.2  交叉编译Android需要的so库”介绍了如何在Windows环境交叉编译Android所需FFmpeg的so库,前文又介绍了如何在Linux环境交叉编译Android所需FFmpeg的so库,接下来介绍如何在Linux环境交叉编译Android所需x265的so库。 执行以下命

    2024年04月08日
    浏览(72)
  • FFMPEG使用DrawText滤镜添加字幕,包含ndk编译freetype

            ffmpeg使用drawtext滤镜需要在编译的时候使能drawtext,要想成功使能必须要先集成编译freetype库,并通知到ffmpeg(交叉编译没有安装到系统库路径)。         也有看到有的文章说需要集成fribidi,笔者也交叉编译了,但是最终没有用到,可能是ffmpeg版本的原因。 freety

    2024年01月17日
    浏览(72)
  • (NDK编译)详解使用Android.mk编译的C/C++程序过程

    想要在 Android设备 上运行 C/C++程序 可执行文件,可采用一个方法就是使用 NDK编译 ,很多时候要比 gcc编译 更适合,这里我采用的是 imx6q开发板 上面装载了自己编写的Android6.0.1镜像,在 Ubuntu64位 系统上采用NDK编译。 目录 1.准备文件 2.编写Android.mk 注意 完整Android.mk代码 3.NDK编

    2024年02月05日
    浏览(44)
  • NDK编译ffmpeg包含硬件加速vulkan和mediacodec

    NDK编译ffmpeg包含硬件加速vulkan和mediacodec flyfish ffmpeg:ffmpeg-6.0 NDK:android-ndk-r25c 硬件加速:vulkan 和 mediacodec target CPU:armv8-a host:Ubuntu 22.04 因为这里要编译硬件加速版本的ffmpeg-6.0,所以需要把vulkan中include下的两个文件夹 vk_video 和 vulkan 拷贝到 android-ndk-r25c/toolchains/llvm/prebuil

    2024年02月12日
    浏览(35)
  • Android-音视频学习系列-(二)-交叉编译动态库、静态库的入门学习

    gcc -S test.i -o test.s//-S 的作用是编译结束生成汇编文件。 汇编阶段 汇编阶段把 .S 文件翻译成二进制机器指令文件 .o ,这个阶段接收.c ,.i ,.s 的文件都没有问题。 下面我们通过以下命令生成二进制机器指令文件 .o 文件: gcc -c test.s -o test.o 链接阶段 链接阶段,链接的是函数库。

    2024年04月09日
    浏览(103)
  • Android中集成FFmpeg及NDK基础知识

    在日常App开发中,难免有些功能是需要借助NDK来完成的,比如现在常见的音视频处理等,今天就以ffmpeg入手,来学习下Android NDK开发的套路. 很多人并不清除JNI和NDK的概念,经常搞混这两样东西,先来看看它们各自的定义吧. 很多人并不清除JNI和NDK的概念,经常搞混这两样东西,先来看看

    2024年01月17日
    浏览(39)
  • Android集成OpenCV(NDK)

    1.下载OpenCv的动态库(.so) OpenCv官网,这边下载的是4.6.0 2.解压opencv-4.6.0-android-sdk.zip 复制目录 opencv-4.6.0-android-sdkOpenCV-android-sdksdknativejni 的 include 文件夹,和 opencv-4.6.0-android-sdkOpenCV-android-sdksdknativelibsarmeabi-v7a 目录对应的cpu架构类型.项目没有对应目录,手动创建一下. 3.配置

    2024年02月06日
    浏览(35)
  • Cmake学习记录(九)--使用Cmake交叉编译Android .so库

    注意:本教程没有关于JNI接口的写法,只是把C代码编译成适合android平台的so库,想查看完整代码可以参考文末的第9条参考链接 目前Android编译.so的话使用Android Studio比较简单,但是有时候时候Android Studio的话还需要创建一个Android的项目,这里记录下脱离Android Studio单纯使用Cma

    2024年02月12日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包