Android开发教程

音视频学习之路--编译FFmpeg

2021-12-05  本文已影响0人  蜗牛是不是牛

前言

看了前面的一些C/C++基础以及一些编译基础,那现在是时候实战一下,这里就编译顺便看一下FFmpeg的大体结构。

正文

这里就边操作,边记录吧,来看看大名鼎鼎的FFmpeg库。

相关推荐
Android音视频开发:音视频基础知识到直播推流实战系列教程_哔哩哔哩_bilibili

FFmpeg定义

FFmpeg既是一款音视频编解码工具,同时也是一组音视频编解码开发套件,作为编解码开发套件,为开发者提供了丰富的音视频处理的调用接口。

FFmpeg提供了多种媒体格式的封装和解封装,包含多种音视频编解码、多种协议的流媒体、多种色彩格式转换、多种采样率转换、多种码率转换等等。

同时FFmpeg框架提供了多种丰富的插件模块,包含封装与解封装插件、编码与解码的插件等。

关于这里的一些具体概念,比如什么是封装和解封装,我们到后面学习音视频相关知识点就明白了,这里先大概了解。

FFmpeg模块介绍

关于下载FFmpeg代码很容易,从官网或者GitHub都可以,但是我尝试了在Linux上下载很慢,所以我直接在Windows上在GitHub下载了,拷贝到了Linux虚拟机中,下面就是完整的目录:

FFmpeg框架的目录还是蛮清晰的,其中包括了几个模块,这里先简单介绍一下:

编解码库,封装了Codec层,但是有一些codec是具备自己的License,FFmpeg不会默认添加,比如libx264、FDK-AAC、Lame等库,但是FFmpeg像是一个平台,可以降其他第三方codec以插件的方式添加进来,为开发者提供统一接口。

文件格式和协议库,封装了Protocol层和Demuxer、Muxer层,使得协议和格式对于开发者来说是透明的。

音视频滤镜库,该模块包含了音视频特效的处理,在使用FFmpeg的API进行编解码的过程中,可以使用该模块高效的为音视频数据做特殊处理。

输入输出设备库,比如需要编译出播放声音或者视频的工具ffplay,就需要确保该模块是打开的,同时也需要libsdl的预先编译,该设备模块播放声音和视频又都是使用libsdl库。

核心工具库,最基础模块之一,其他模块都会依赖该模块做一些基本的音视频处理操作。

用于音视频采样,可以对音频进行声道数、数据格式、采样率等多种基本信息的转换。

该模块用于图像格式转换,可以降YUV的数据转换为RGB的数据

该模块用于后期处理,当我们使用filter的时候,就需要打开这个模块,filter会用到这个模块的一些基础函数。

另外,库里还包含对H.264/MPEG-4 AVC视频编码的X264库,是非常常用的有损视频编码器,支持CBR、VBR模块,可以在编码的过程中直接改变码率的设置,在直播场景中非常适用,可以做码率自适应的功能。

一些最基本的介绍就是上面了,具体是啥意思,我们后面再细说。

编译FFmpeg

wget命令

在Linux中可以使用wget命令来下载文件,这个wget就相当于是一个下载器,但是呢最近发现很多网站使用wget下载特别慢,尤其是国外的一些网站,Windows挂了代理也还是不行,上网找了一些,推荐使用mwget。

mwget命令

mwget下载器是一个多线程下载应用,比wget下载更快,下面有个脚本可以直接安装:

#!/bin/bashwget http://jaist.dl.sourceforge.net/project/kmphpfm/mwget/0.1/mwget_0.1.0.orig.tar.bz2
yum install bzip2 gcc-c++ openssl-devel intltool -y
bzip2 -d mwget_0.1.0.orig.tar.bz2
tar -xvf mwget_0.1.0.orig.tar 
cd mwget_0.1.0.orig
./configure   #一般用来生成 Makefile,为下一步的编译做准备,你可以通过在 configure 后加上参数来对安装进行控制,比如代码:./configure –prefix=/usr 意思是将该软件安装在/usr下面
make       #编译,大多数的源代码包都经过这一步进行编译
make install  #开始安装echo "至此,安装完成"

这个脚本在Ubuntu上肯定运行不起来,就比如yum这个命令在Ubuntu上就不行,这里就简单介绍一下apt和yum。

apt和yun

一般来说著名的Linux系统分为2大类,

这2个系统的包管理器用的是不一样的,有区分yum、dkpg和apt,下图是区别:

所以上面yum安装bzip2的命令就需要修改一下,改成

apt install bzip2 gcc-c++ openssl-devel intltool -y

但是呢,会发现这4个软件只有一个bzip2能安装成功,其他几个都找不到,这又是什么鬼呢,下面再来细说。

Ubuntu安装mwget

这里还是单独说一下在Ubuntu下安装这个mwget,因为网上很多都是centos系统,直接看一个链接:

# Ubuntu安装mwget

会发现想跑通mwget的shell脚本需要安装3个软件,然后把压缩包bz2文件先进行解压,然后运行./configure脚本,这个脚本跑完后需要执行make和make install,注意这又是坑,首先需要sudo权限,然后会发现很多cpp文件缺少头文件,这时需要挨个去修改添加头文件。

下载FFmpeg

假设上面mwget能成功安装,这时就需要下载和解压FFmpeg了,命令如下:

mwget https://ffmpeg.org/releases/ffmpeg-4.2.2.tar.bz2
tar -jxvf ffmpeg-4.2.2.tar.bz2

下载完之后,就是上面我们简单介绍的几个目录了,这时可以直接运行configure脚本,这个脚本是用来配置FFmpeg的,里面配置项巨多,我们可以直接运行:

这里发现居然执行不过,原因很简单,是因为没有yasm汇编编译器,FFmpeg为了提高效率使用了汇编指令,所以需要安装汇编编译器:

sudo apt-get install yasm

即可,然后configure脚本就可以执行成功。

编译FFmpeg

当然上面脚本编译时是编译很多东西,我们需要针对我们自己的需求,定制一个脚本,其实就是配置FFmpeg的configure中的各种选项,下面我们来看一下:

#!/bin/bash

echo ">>>>>>>>> 注意:该编译环境目前只在 NDK17c + ffmpeg4.2.2 测试过 <<<<<<<<"
echo ">>>>>>>>> 注意:该编译环境目前只在 NDK17c + ffmpeg4.2.2 测试过 <<<<<<<<"
echo ">>>>>>>>> 注意:该编译环境目前只在 NDK17c + ffmpeg4.2.2 测试过 <<<<<<<<"

#NDK_ROOT 变量指向 ndk 目录
NDK_ROOT=$NDK_HOME
#指定android api版本
ANDROID_API=21


#开始编译 在下面调用传入参数即可
function build_ffmpeg()
{
echo "开始编译 $PREFIX_CPU"
echo "开始编译 $PREFIX"
echo "开始编译 $TOOLCHAIN"

./configure \
--prefix=$PREFIX \
--enable-small \
--disable-programs \
--disable-avdevice \
--disable-encoders \
--disable-muxers \
--disable-filters \
--enable-cross-compile \
--cross-prefix=$CROSS_PREFIX \
--disable-shared \
--enable-static \
--sysroot=$NDK_ROOT/platforms/android-$ANDROID_API/arch-$ARCH \
--extra-cflags="$CFLAGES" \
--arch=$ARCH \
--target-os=android

#上面运行脚本生成makefile之后,使用make执行脚本
make clean
make
make install

echo "$PREFIX_CPU 编译完成"
echo "$PREFIX_CPU 编译完成"
echo "$PREFIX_CPU 编译完成"
}

#armeabi-v7a
PREFIX=./result/armeabi-v7a
TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
ARCH=arm
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
CFLAGES="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=$ANDROID_API -U_FILE_OFFSET_BITS  -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"

build_ffmpeg

#arm64-v8a
PREFIX=./result/arm64-v8a
TOOLCHAIN=$NDK_ROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64
ARCH=arm64
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
CFLAGES="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=$ANDROID_API -U_FILE_OFFSET_BITS  -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security  -O0 -fPIC"

build_ffmpeg

#直接跳转到编译完成的路径
cd /result


上面就是编译的脚本,这里有几点需要说明一下,对于这种编译的脚本,还是要力求都看懂,不然出问题了根本无法查找。

configure常用参数

既然我们知道了这里的编译脚本就是配置configure中的一些配置,那常用的配置我们必须得懂,下面就罗列一些:

编译问题

首先这个编译可不是一帆风顺的,由于代码太多,我的Ubuntu虚拟机大概要编译20分钟,其中有几个主要错误,下面来说一下。

//1. 修改 configure 文件
vim configure
//2. 把 默认的 clang 修改为 gcc
if test "$target_os" = android; then
   # cc_default="clang"
         cc_default="gcc"
fi


总结

编译FFmpeg还是很复杂的,这也正常,毕竟FFmpeg有这么多功能,音视频学习之路还很长,边学边总结吧,加油。

相关推荐
Android音视频开发:音视频基础知识到直播推流实战系列教程_哔哩哔哩_bilibili

本文转自 https://juejin.cn/post/7025441094921879560,如有侵权,请联系删除。

上一篇下一篇

猜你喜欢

热点阅读