This page looks best with JavaScript enabled

Compile And Run FFmpeg Examples

 ·  ☕ 3 min read

FFmpeg 的源码仓库在 doc/examples 目录中提供了一些基本的 FFmpeg Api 使用方法。但是在我想运行这些例子时,却尝试了很久才编译出来可运行的例子。因为 FFmpeg 的 readme 中只大概提到了如何编译 examples,但是还是要花一些时间才能成功。
所以在此记录以下如何编译并成功运行那些 exampples。

FFmpeg Relase 4.3 版本的源码目录结构应该是如下的:

➜  FFmpeg-release-4.3 tree -L 1
.
├── Makefile
├── README.md
├── doc
├── ffbuild
├── ffmpeg
├── ffplay
├── ffprobe
├── fftools
├── libavcodec
├── libavdevice
├── libavfilter
├── libavformat
├── libavresample
├── libavutil
├── libpostproc
├── libswresample
├── libswscale

FFmpeg 的编译会依赖一个叫 pkg-config 的工具去定位各个依赖库的位置,所以在编译前需要先在你的编译环境上安装 pkg-config。doc/examples 中就是 FFmpeg 内部 Api 的使用例子。
要运行 examples,需要先将 FFmpeg 各个组件编译为对应你目标平台的库。

编译 FFmpeg

编译本身没啥可说的,利用 make 工具根据 FFmpeg 项目中的 MakeFile 进行编译。执行 make 前需要先使用源码根目录的 .configure 脚本配置要把哪些组件加入编译中。

下面是我在 osx 上编译的一个配置, prefix 配置了编译后结果的存放目录:

./configure  --prefix=./mac_build \
--enable-gpl \
--disable-everything \
--enable-nonfree \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libtheora \
--enable-libvorbis \
--enable-libvpx \
--enable-libopus \
--enable-libxvid \
--samples=fate-suite --enable-debug=3 \
--enable-demuxer=mov,wav,wavpack \
--enable-muxer=image2 \
--enable-encoder=png \
--enable-decoder=h264 \
--enable-protocol=file \
--enable-filter=scale,trim

make clean
make -j 6
make -j 6 install

编译完成后的目录结构应该如下:

mac_build
├── bin
│   ├── ffmpeg
│   ├── ffplay
│   └── ffprobe
├── include
│   ├── libavcodec
│   ├── libavdevice
│   ├── libavfilter
│   ├── libavformat
│   ├── libavutil
│   ├── libpostproc
│   ├── libswresample
│   └── libswscale
├── lib
│   ├── libavcodec.a
│   ├── libavdevice.a
│   ├── libavfilter.a
│   ├── libavformat.a
│   ├── libavutil.a
│   ├── libpostproc.a
│   ├── libswresample.a
│   ├── libswscale.a
│   └── pkgconfig
│       ├── libavcodec.pc
│       ├── libavdevice.pc
│       ├── libavfilter.pc
│       ├── libavformat.pc
│       ├── libavutil.pc
│       ├── libpostproc.pc
│       ├── libswresample.pc
│       └── libswscale.pc
└── share
    ├── doc
    │   └── ffmpeg
    ├── ffmpeg
    │   ├── examples
        │   │   ├── Makefile

编译出来的可执行文件在 bin 目录中;如果你要基于 FFmpeg 的 Api 进行开发,那么 include 和 lib 目录就是你需要的了。而原来 doc/examples 中的例子们都被拷贝到了这里的 share/ffmpeg/examples 中,这个目录中会生成一个新的 Makefile,这个 Makefile 才是用来编译例子们的。

编译可运行的 examples

到此,我们已经得到了用来编译 examples 的 Makefile,但是还有个东西需要注意,那就是上面提到的 pkg-config。如果这个时候你直接在 share/ffmpeg/examples 目录中执行 make,一定会出现如下的日志:

Package libavdevice was not found in the pkg-config search path.
Perhaps you should add the directory containing `libavdevice.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libavdevice' found
Package libavformat was not found in the pkg-config search path.
Perhaps you should add the directory containing `libavformat.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libavformat' found
.....
cc  -Wall -g   -c -o avio_list_dir.o avio_list_dir.c
avio_list_dir.c:23:10: fatal error: 'libavcodec/avcodec.h' file not found
#include <libavcodec/avcodec.h>
         ^~~~~~~~~~~~~~~~~~~~~~
1 error generated.
make: *** [avio_list_dir.o] Error 1

pck-config 这个工具是需要根据配置文件来配置的,编译 examples 的 Makefile 又会依赖 pkg-config 去找例子们依赖的库和这些库的头文件放在了哪里,从而让预处理器和链接器能够成功执行预处理和链接任务。

那我们需要自己写 pkg-config 的配置文件吗?可以自己写,但是很痛苦,所以 FFmpeg 已经配置好了,mac_build/lib/pkgconfig 目录中就存放了每个库对应的 pkg-config配置文件。
随便打开一个看看:

prefix=./mac_build
exec_prefix=${prefix}
libdir=./mac_build/lib
includedir=./mac_build/include

Name: libavcodec
Description: FFmpeg codec library
Version: 58.91.100
Requires: libswresample >= 3.7.100, libavutil >= 56.51.100
Requires.private: 
Conflicts:
Libs: -L${libdir}  -lavcodec -liconv -lm -llzma -lz -framework AudioToolbox -pthread -framework VideoToolbox -framework CoreFoundation -framework CoreMedia -framework CoreVideo -framework CoreServices
Libs.private: 
Cflags: -I${includedir}

上面的配置其实很可读了,声明了 libavcodec 的库目录和头文件目录,以及它所依赖的库。所以我们只要让 $PKG_CONFIG_PATH 指向 mac_build/lib/pkgconfig 目录即可,同时要注意上面的 libdir 的值是 ./mac_build/lib,表示在当前目录下的 mac_build/lib 目录中查找库,所以还需要进行一个比较丑的操作解决当前目录的问题:

cd mac_build
mkdir mac_build
cp -r include mac_build
cp -r lib mac_build
cp share/ffmpeg/examples/* .

最终脚本

所以最终我写了如下的编译脚本,在编译 FFmpeg 时同时为 doc/examples 目录下的例子们编译出对应的可执行文件:

#! /usr/bin/env bash

./configure  --prefix=./mac_build \
--enable-gpl \
--disable-everything \
--enable-nonfree \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libtheora \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-libopus \
--enable-libxvid \
--samples=fate-suite --enable-debug=3 \
--enable-demuxer=mov,wav,wavpack \
--enable-muxer=image2 \
--enable-encoder=png \
--enable-decoder=h264 \
--enable-protocol=file \
--enable-filter=scale,trim

make clean
make -j 6
make -j 6 install

export PKG_CONFIG_PATH=~/code/FFmpeg-release-4.3/mac_build/lib/pkgconfig

echo "========Start make examples========"
cd mac_build
mkdir mac_build
cp -r include mac_build
cp -r lib mac_build
cp share/ffmpeg/examples/* .
make
echo "========Finish========

执行完上面的脚本后,就能在 mac_build 目录中找到每个 example 对应的可执行文件,然后执行例子学习了。


Yang
WRITTEN BY
Yang
Developer