欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Windows下编译FFmpeg4.2

程序员文章站 2022-06-04 13:10:17
...

1. FFmepg简介

ffmepg是一个音视频的开发工具。
一套可以用来记录、处理数字音频、视频,并将其转换为流的开源框架。采用 LPL、GPL许可制,提供了录制、转换以及流化音视频的完整解决方案。

1.1 命令行工具概述

下面是一些FFmepg使用时的基本命令,是最基础的内容,我们不用太熟悉FFmpeg里面的代码是如何写的,如我们只需调用:

ffmpge -i input.avi -r 24 output.avi
  • 1

就可以把input.avi中的帧率变成24,输出的output.avi就是24fps的视频

  • ffmpeg
    包含FFmpeg的各种功能,如 gif、格式转换、截图、编解码等等
  • ffmpeg -all
    包含ffmpeg工具及ffmpeg组件
  • ffplay
    一个使用了FFmpeg和SDL库的、简单的、可移植的媒体播放器
  • ffplay-all
    包含fflpay工具以及ffmpeg组件
  • ffprobe
    用来查看多媒体文件的信息
  • ffprobe-all
    包含ffprobe工具及FFmpeg组件
  • ffserver
    与流媒体服务相关,负责响应客户端的流媒体请求,把流媒体数据发送给客户端
  • ffserver-all
    包含ffserver工具及FFmpeg组件

1.2 组件概述

  • Utilities
    libavutils提供的通用的features及工具
  • Video scaling and pixel format converter
    视频缩放和像素格式转换器
  • Audio resampler
    音频重新取样
  • Encoders and decoders
    编码和解码
  • Bitstream filters
    码流过滤器
  • Muxers and demuxers
    数据合成及数据分离
  • Protocols
    协议
  • Input and output devices
    输入和输出设备
  • Filters
    过滤器

1.3 类库概述

  • libavutil
    包含了一些公共的工具函数
  • libswscale
    用于视频场景比例缩放、色彩映射转换、图像颜色控件或格式转换
  • libswresample
    原始音频格式转码
  • libavcodec
    用于各种类型声音/图像转码,该库是音视频编码核心库
  • libavformat
    用于各种音视频封装格式的生成和解析。
  • libavdevice
    硬件采集、加速、显示。
  • libavfilter
    音视频滤波器开发。
  • libavresample
    音视频封装编解码格式预设等。
  • libpostproc
    用于后期效果处理,如图像的去块效应

1.4 文件概述

  • Frequently Asked Questions
    常见问题
  • Support External Libraries,Formats,Codecs or Features
    支持扩展库、格式、编解码或特性
  • Platform Specific Information
    平台具体信息
  • Developer Documentation
    开发者概述
  • Git How-To
    Git
  • FFmpeg Automated Testing Enviroment
    FFmpeg自动化测试环境。

2. 在Windows10、NDK r20下编译FFmpeg

在Windows下编译FFmpeg需要准备工具 MSYS2 和 Yasm
MSYS2集成了 Pacman、MinGW-w64的Cygwin升级版,下载地址在:MSYS2下载地址
Yasm是一个汇编器。在地址在:Yasm下载地址,下载对应的 .exe文件,下载完后放入到 Windows\System32文件夹下就行了。

关于安装完MSYS2后,需要配置一些东西,重点去看这个blog:msys2在windows10下编译安装ffmpeg+x265
至于265的可以考虑先装。

在这个地方(使用WIN10编译)我踩坑无数,花了几天的休息时间终于编译出来了。
这里先列出我所有踩过的坑:

  1. 书上、网上的编译方法过于老旧
    书上、网上所使用的的FFmpeg、ndk都是比较旧的,比如FFmpeg是3.xx,ndk是r12或者r10
    而新版本的ndk是r20,ffmpeg是4.2
    他们的区别是 旧版本使用gcc编译,新版本必须使用clang编译。
  2. 关于msys2
    它是一个命令行工具,可以使用 ./来执行文件,它的作用和linux的终端一样,功能非常强大
    我们要用其来编译ffmpeg。
  3. 使用clang时,要去改configure文件,旧版本也要,但是新旧的改法已经完全不同了。

这里就不多探究为什么要怎么怎么改。具体的可以参考这篇文章(完全ok):编译 FFmpeg 之 clang

2.1 编辑configure文件

先说下目的:ffmpeg4之后使用clang编译器进行编译,但是它并没有专门为clang声明一套方案,这导致如果我们不在其配置文件下加入clang的一些声明,会导致后期我们编译ffmpeg不成功。

首先在ffmpeg的文件下找到configure,用文本打开。
找到 --cross-prefix=PREFIX use PREFIX for compilation tools [$cross_prefix]
在其下面加一行:

--corss-prefix-clang=PREFIX use PREFIX for compilation clang tools [$cross_prefix]
  • 1

接着找到 CMDLINE_SET="..... corss_prefix
在其下面添加一行:

cross_prefix_clang
  • 1

接着找到

set_default target_os
if test "$target_os" = android; then
   cc_default="clang"
fi
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}"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

替换成:

set_default target_os
if test "$target_os" = android; then
   cc_default="clang"
   cxx_default="clang++"
fi
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}"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

保存文件,使用msys2进入到ffmpeg根目录下执行 ./configure 来跑一边配置文件

2.2 编写 build_android.sh脚本

在根目录下新建一个名为 temp的文件夹作为 编译过程中的临时文件。

在ffmpeg根目录下编写一个脚本名为build_android.sh,用来编译ffmpeg。
在里面编辑(注意看注释):

#!/bin/bash
make clean

#指定ndk路径
export NDK=C:/Users/msn/AppData/Local/Android/Sdk/ndk-bundle
#指定ffmpeg路径
export FFMPEG=C:/Users/msn/Desktop/ffmpeg-4.2.1
#指定临时文件夹
export TMPDIR=$FFMPEG/temp
#指定sysroot
export SYSROOT=$NDK/toolchains/llvm/prebuilt/windows-x86_64/sysroot
#指定平台
export PLATFORM=$NDK//toolchains/llvm/prebuilt/windows-x86_64
#指定cpu(如果用clang编译,必须指定cpu为armv7-a)
export CPU=armv7-a
#指定产出文件
export PREFIX=C:/Users/msn/Desktop/ffmpeg-4.2.1/android/$cpu

function build
{
   ./configure \
   	--prefix=$PREFIX \
   	--target-os=android \
   	--arch=$CPU \
   	--enable-shared \
   	--disable-static \
   	--disable-doc \
   	--disable-ffmpeg \
   	--disable-ffplay \
   	--disable-ffprobe \
   	--disable-avdevice \
   	--disable-symver \
   	--enable-cross-compile \
   	--sysroot=$SYSROOT \
   	--cross-prefix=$PLATFORM/bin/arm-linux-androideabi- \
   	#指定为android28编译,当然也可以把28换成16以上的其他数字
   	--cross-prefix-clang=$PLATFORM/bin/armv7a-linux-androideabi28- \
   	--extra-cflags="-I$SYSROOT/usr/include" \
   	--extra-ldflags="-L$SYSROOT/usr/lib" \
   	$ADDITIONAL_CONFIGURE_FLAG
   	make clean
   	make -j2
   	make install
}
build
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

编辑完后保存。

在根目录下运行 ./build_android
运行之后的结果,是会在目录下看到产出的文件:
Windows下编译FFmpeg4.2
里面的内容就是编译之后的结果。