FFmpeg 引入Android Studio,2024年您应该知道的技术之一

后续也会通过最新的NDK版本、Clang来编译FFmpeg

那既然源码已经下下来了,接下来我们还差一个编译工具——NDK

NDK环境配置

===================================================================

因为在NDK源文件里面会有很多关于C的编译工具,我们必须用NDK的编译工具而不能用Linux的编译工具,我们把这种编译就称为交叉编译。

再回到云服务器,我们需要下载一个NDK,大家下载的时候可以选择NDKr20,我们将用这个版本去编译

然后我们还要对NDK进行环境配置

mkdir ndk 创建一个NDK目录

这里推荐大家买服务器最好是选择香港的服务器,因为香港的服器下载这些国外的软件是非常快的,比如我这台服务器的,实际上它就是一个香港服务器

然后我们使用wget命令,就可以把NDK下载下来了。NDK相对来说还是比较大的,但因为香港服务器的缘故,下载还是非常快的

下载完后,使用zip命令将下载的文件解压

unzip,解压的时间可能会有点长,根据每个服务器的配置不一样,解压的时间长短也会不一样

解压完成后我们再去配置NDK环境,这个配置环境和Windows还是有些不一样的,在Windows中我们直接在我的电脑中就可以配置到,但是在Linux里面,它是不一样的,我们需要去编辑etc/profile

在最底部加上我们的环境,我们设定一个NDK ROOT,把它加到PATH路径里面去

然后再退出,让环境生效

到目前,我们NDK的环境就已经配好了,这个时候我们需要编译FFmpeg就需要用到shell脚本

shell脚本

===================================================================

shell脚本它专门是针对于Linux里面,进行编译的语法,类似于Java语法

说到这里,shell语法我们要不要学呢?

学肯定是需要的,但我们只需要大概去了解这个shell脚本怎么去写,就已经可以满足我们这个系列文章里面所要掌握的内容

我们来看这个编写脚本里面内容,脚本的作用是将FFmpeg源码打包成我们在Android里面想要用到的.so文件,或者说.a静态库文件,供我们在Android项目里面去调用

在FFmpeg源文件夹下去建立一个android_build.sh

直接copy下面代码进去

#!/bin/bash

export NDK=/root/ndk/android-ndk-r20

当前系统

export HOST_TAG=linux-x86_64

支持的 Android CUP 架构

export ARCH=aarch64

export CPU=armv8-a

export ARCH=armv7a

export CPU=armv7-a

支持的 Android 最低系统版本

export MIN=21

export ANDROID_NDK_PLATFORM=android-21

export PREFIX= ( p w d ) / a n d r o i d / (pwd)/android/ (pwd)/android/CPU

export MIN_PLATFORM= N D K / p l a t f o r m s / a n d r o i d − NDK/platforms/android- NDK/platforms/androidMIN

export SYSROOT=$NDK/sysroot

export TOOLCHAIN= N D K / t o o l c h a i n s / l l v m / p r e b u i l t / NDK/toolchains/llvm/prebuilt/ NDK/toolchains/llvm/prebuilt/HOST_TAG

export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar

export AS=$TOOLCHAIN/bin/arm-linux-androideabi-as

export CC= T O O L C H A I N / b i n / TOOLCHAIN/bin/ TOOLCHAIN/bin/ARCH-linux-androideabi$MIN-clang

echo “-----------------------------”

echo $CC

export CXX= T O O L C H A I N / b i n / TOOLCHAIN/bin/ TOOLCHAIN/bin/ARCH-linux-androideabi$MIN-clang++

export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld

export NM=$TOOLCHAIN/bin/arm-linux-androideabi-nm

export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib

export STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip

OPTIMIZE_CFLAGS=“-DANDROID -I$NDK/sysroot/usr/include/arm-linux-androideabi/”

ADDI_LDFLAGS=“-Wl,-rpath-link= M I N P L A T F O R M / a r c h − a r m / u s r / l i b − L MIN_PLATFORM/arch-arm/usr/lib -L MINPLATFORM/archarm/usr/libLMIN_PLATFORM/arch-arm/usr/lib -nostdlib”

sed -i “” “s/SLIBNAME_WITH_MAJOR=‘$(SLIBNAME).$(LIBMAJOR)’/SLIBNAME_WITH_MAJOR=‘$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)’/” configure

sed -i “” “s/LIB_INSTALL_EXTRA_CMD=‘$$(RANLIB) “$(LIBDIR)\/$(LIBNAME)”’/LIB_INSTALL_EXTRA_CMD=‘$$(RANLIB) “$(LIBDIR)\/$(LIBNAME)”’/” configure

sed -i “” “s/SLIB_INSTALL_NAME=‘$(SLIBNAME_WITH_VERSION)’/SLIB_INSTALL_NAME=‘$(SLIBNAME_WITH_MAJOR)’/” configure

sed -i “” “s/SLIB_INSTALL_LINKS=‘$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)’/SLIB_INSTALL_LINKS=‘$(SLIBNAME)’/” configure

sed -i -e ‘s/#define getenv(x) NULL//*#define getenv(x) NULL*//g’ config.h

sed -i “” “s/SHFLAGS=‘-shared -Wl,-soname,$(SLIBNAME)’/SHFLAGS=‘-shared -soname $(SLIBNAME)’/” configure

sed -i “” “s/-Wl//g” configure

./configure \

–prefix=$PREFIX \

–ar=$AR \

–as=$AS \

–cc=$CC \

–cxx=$CXX \

–nm=$NM \

–ranlib=$RANLIB \

–strip=$STRIP \

–arch=$ARCH \

–target-os=android \

–enable-cross-compile \

–disable-asm \

–enable-shared \

–disable-static \

–disable-ffprobe \

–disable-ffplay \

–disable-ffmpeg \

–disable-debug \

–disable-symver \

–disable-stripping \

–extra-cflags=“-Os -fpic $OPTIMIZE_CFLAGS”\

–extra-ldflags=“$ADDI_LDFLAGS”

sed -i “” “s/#define HAVE_TRUNC 0/#define HAVE_TRUNC 1/” config.h

sed -i “” “s/#define HAVE_TRUNCF 0/#define HAVE_TRUNCF 1/” config.h

sed -i “” “s/#define HAVE_RINT 0/#define HAVE_RINT 1/” config.h

sed -i “” “s/#define HAVE_LRINT 0/#define HAVE_LRINT 1/” config.h

sed -i “” “s/#define HAVE_LRINTF 0/#define HAVE_LRINTF 1/” config.h

sed -i “” “s/#define HAVE_ROUND 0/#define HAVE_ROUND 1/” config.h

sed -i “” “s/#define HAVE_ROUNDF 0/#define HAVE_ROUNDF 1/” config.h

sed -i “” “s/#define HAVE_CBRT 0/#define HAVE_CBRT 1/” config.h

sed -i “” “s/#define HAVE_CBRTF 0/#define HAVE_CBRTF 1/” config.h

sed -i “” “s/#define HAVE_COPYSIGN 0/#define HAVE_COPYSIGN 1/” config.h

sed -i “” “s/#define HAVE_ERF 0/#define HAVE_ERF 1/” config.h

sed -i “” “s/#define HAVE_HYPOT 0/#define HAVE_HYPOT 1/” config.h

sed -i “” “s/#define HAVE_ISNAN 0/#define HAVE_ISNAN 1/” config.h

sed -i “” “s/#define HAVE_ISFINITE 0/#define HAVE_ISFINITE 1/” config.h

sed -i “” “s/#define HAVE_INET_ATON 0/#define HAVE_INET_ATON 1/” config.h

sed -i “” “s/#define getenv(x) NULL/\/\/ #define getenv(x) NULL/” config.h

我们这个shell脚本内容比较多,但是这个shell脚本其实说白了只有一句话,就是调用了我们./configure这个文件

这个./configure它是在build.sh的同级目录下的configure文件

我们直接在FFmpeg源码里面去找,在FFmpeg源码同级目录下有个叫做configure的玩意,然后我们把它打开

这个./configure它也是属于shell文件,它是一个可执行的shell文件,类似我们Java里面有一个main函数

我们如何去判断它是不是shell文件呢?

它第一句话就是#!/bin/sh就代表它是一个shell文件,这个shell文件是个可执行的,就相当于main函数里面或许会有一些参数传递进来,比如我们经常会去Java里面写一些main函数,然后main函数里面有一个steing数组,我们通过在命令行执行这个Java文件可以传递一些参数进来。同样的,在shell文件它也会传递这些参数,只不过在configure里面传递的参数就比较复杂了

总之,我们执行这个shell文件只为了去调用这样的一句话 ./configure 去执行我们刚才的shell文件

参数设置

================================================================

下面的都是属于参数的传递

而上面的是为了去给它定义一些参数的变量,类似于全局的变量

我们来看./configure 第一个–prefix 代表的是我们要输出在哪一个目录

我们最终编译出来的是一个动态库,那这个动态库它肯定就有文件夹,但是文件放在这个prefix这个变量里面,我们往上找,找到prefix定义变量声明的地方,声明在我们当前的目录

pwd是一个命令,shell语法它是可以直接去调用这些命令的,比如我们pwd就可以输出到当前的目录

那这个当前目录下的Android CPU,就是我们当前编译的CPU,我们编译的是armv7a,编译的过程中会产生一个Android文件,然后在Android文件下再去产生个子文件叫做armCPUv7a,最后把我们的编译成果放到这个文件夹下

–ar是Clang里面的一个链接编译器,我们可以打开NDK,我在AndroidStudio的NDK打开,然后接下来我们打开它所在的目录Android/SDK这个目录

这个目录里面有一个NDK-bundle,我们直接是打开了Windows的,Windows和Linux是比较相似的,因为他们都是一个版本,只不过后缀名一个是.exe一个是Linux里面的可执行文件

我们打开NDK bundle然后再toolchains

toolchains:代表的是工具链的意思

继续进去,我们可以发现很多的可执行文件,在Windows里面后缀名都是.exe

然后它里面有以下几个文件需要在FFmpeg里面进行传递参数传进去的

ar、as、nm、strip这几个路径我们需要进行指定,它主要是用来做一个链接编译的作用,加快我们编译so的速度

所以大家会发现在传递参数的时候,第一个是–ar,它的值就是AR这个变量,在上面我们就会定义一个叫做AR的变量

他的路径就是下图,也就是刚刚我们看到的那些路径

这些都是起了链接编译工具的作用

在以前的NDK版本里面是没有这几个文件的,以前只有gcc,现在用Clang来进行交叉编译后我们需要指定这些交叉编译工具链里面的内容

像上面这五个路径都是为了去指定我们交叉工具链里面的指定工具,就是我们把这些工具指定进去之后FFmpeg编译的时候就会用这些工具来进行编译

然后最主要的两个参数就是接下来的–cc、–cxx,在以前我们是–gcc,然后现在是cc,cc就是指的Clang

$CC是定义的这个变量

我们去找一下,在这里面我们就会发现有很多Clang的编译工具

我们主要是用Clang来进行编译,clang++是用来去编译C++,cang是用来编译C文件,我们只需要去指定这两个,就可以实现Clang的语法去进行交叉编译

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

img
img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip204888 备注Android获取(资料价值较高,非无偿)
img

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

下图是我进阶学习所积累的历年腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节

整理不易,望各位看官老爷点个关注转发,谢谢!祝大家都能得到自己心仪工作。

链图片转存中…(img-by38WNbI-1711558564362)]

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip204888 备注Android获取(资料价值较高,非无偿)
[外链图片转存中…(img-RxcVWaVF-1711558564362)]

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

下图是我进阶学习所积累的历年腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节

[外链图片转存中…(img-zq2jcu5i-1711558564363)]

整理不易,望各位看官老爷点个关注转发,谢谢!祝大家都能得到自己心仪工作。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值