如果基于ffmpeg库来做音视频开发,常常需要自己编译ffmpeg,本文整理了下编译动态库模式的,官方参考文档:https://trac.ffmpeg.org/wiki/CompilationGuide/Centos,不过官方默认是静态编译模式。

环境准备

yum安装依赖

yum install autoconf automake bzip2 cmake freetype-devel gcc gcc-c++ libstdc++-devel git libtool make mercurial nasm pkgconfig zlib-devel

目录约定

编译

编译yasm

yasm是ffmpeg依赖的汇编器。

cd ~/ffmpeg_sources
git clone --depth 1 git://github.com/yasm/yasm.git
cd yasm
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make
make install

注意:

如果出现提示autoconf版本太低,需要2.6.0以上

可以自行覆盖安装下autoconf

wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
tar -xzf autoconf-2.69.tar.gz 
./configure --prefix=/usr
make
make install

如果出现 autoreconf -fiv 报错,内容如下

Makefile.am: C objects in subdir but `AM_PROG_CC_C_O' not in `configure.ac'
autoreconf: automake failed with exit status: 1 

可以将目录下的所有(包括子目录的) configure.ac 都在最后一行加上 AM_PROG_CC_C_O 就能解决

编译libx264

x264是H.264视频编码器

需要ffmpeg在configure时,加上 --enable-gpl --enable-libx264 选项

cd ~/ffmpeg_sources
git clone --depth 1 git://git.videolan.org/x264
cd x264
PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-shared
make
make install

编译x265

x265是H.265视频编码器,需要加选项 --enable-libx265

cd ~/ffmpeg_sources
hg clone https://bitbucket.org/multicoreware/x265
cd ~/ffmpeg_sources/x265/build/linux
cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$HOME/ffmpeg_build" ../../source
make
make install

注意:

如果cmake的版本低于2.8.8,x265将无法编译

参考:https://bitbucket.org/multicoreware/x265/wiki/Home

这时需要自行安装cmake2.8.10:

wget http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz
tar -xzf cmake-2.8.10.2.tar.gz 
./configure --prefix=/usr
make
make install

关于openssl支持

当处理https的资源时,如果报错:”https protocol not found, recompile FFmpeg with openssl, gnutls or securetransport enabled. “

则需要支持openssl来编译,添加选项 --enable-openssl

不过这还和系统的openssl版本还有关系,比如:Red Hat Enterprise Linux 5 使用的openssl是”OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008”就不支持,需要升级才行,最终编译报错内容如下:

...
ffmpeg_opt.c:1947: warning: ‘avcodec_copy_context’ is deprecated (declared at libavcodec/avcodec.h:4241)
ffmpeg_opt.c:1947: warning: ‘codec’ is deprecated (declared at libavformat/avformat.h:893)
ffmpeg_opt.c: In function ‘open_output_file’:
ffmpeg_opt.c:2329: warning: ‘codec’ is deprecated (declared at libavformat/avformat.h:893)
CC	ffmpeg_filter.o
LD	ffmpeg_g
libavformat/libavformat.so: undefined reference to `SSL_set_tlsext_host_name'
collect2: ld returned 1 exit status
make: *** [ffmpeg_g] Error 1

这时需要打个patch:

--- a/deps/ffmpeg-3.2.2/libavformat/tls_openssl.c
+++ b/deps/ffmpeg-3.2.2/libavformat/tls_openssl.c
@@ -36,6 +36,10 @@
 #include <openssl/ssl.h>
 #include <openssl/err.h>

+#if OPENSSL_VERSION_NUMBER >= 0x0090806fL && !defined(OPENSSL_NO_TLSEXT)
+#define HAVE_OPENSSL_TLSEXT
+#endif
+
 static int openssl_init;

 typedef struct TLSContext {
@@ -280,8 +284,13 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op
     bio->ptr = c->tcp;
 #endif
     SSL_set_bio(p->ssl, bio, bio);
-    if (!c->listen && !c->numerichost)
+    if (!c->listen && !c->numerichost) {
+#if defined(HAVE_OPENSSL_TLSEXT)
         SSL_set_tlsext_host_name(p->ssl, c->host);
+#else
+        av_log(h, AV_LOG_WARNING, "tlsext SNI unusable with this OpenSSL library version\n");
+#endif
+    }
     ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl);
     if (ret == 0) {
         av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n");

编译ffmpeg

cd ~/ffmpeg_sources
curl -O http://ffmpeg.org/releases/ffmpeg-3.2.2.tar.bz2
tar xjvf ffmpeg-3.2.2.tar.bz2
cd ffmpeg
PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --extra-cflags="-fPIC -m64 -I$HOME/ffmpeg_build/include" --extra-ldflags="-L$HOME/ffmpeg_build/lib -ldl" --bindir="$HOME/bin" --pkg-config-flags="--static" --enable-gpl --enable-libx264 --enable-nonfree --enable-pic --enable-libfreetype --enable-libfontconfig --enable-openssl --extra-ldexeflags=-pie --enable-shared
make
make install

关于其他扩展能力,如libfdk_aac等

参考官网上的编译方式,注意在./configure后加上--enable-shared即可,然后再编译ffmpeg