关于FreeSWITCH与ffmpeg的恩怨可以讲很多,不过,让我们长话短说。
ffmpeg是比较流行的多媒体库,可以处理语音视频之类的,在开源领域内得到了大量应用,包括Android和Chrome。如果我没记错的话当年QQ也用过它,但因没有遵循开源协议开放源码而被钉在了耻辱柱上。
几年前(具体时间懒得查了)。由于开发团队的分歧,ffmpeg分裂了。部分开发者另起一摊,fork了一下,起名叫libav。但问题是,虽然项目名称改了,但为了跟大多数现在应用兼容,库名称依然叫libavcodec、libavformat之类的。这是所有恶梦的开始。
其实我在更早的时间就开始在FreeSWITCH里基于ffmpeg写一个模块,最初叫mod_ffmpeg。第一个可以运行的版本是在从Cluecon回来的飞机上调试成功的。
后来,由于CentOS的诡异问题,FreeSWITCH开发团队将开发平台迁移到了Debian,而Debian使用libav,所以,我们趁机将mod_ffmpeg改为两个模块,叫 mod_avcodec和mod_avformat。
libavcodec 是做编解码处理的,libavformat是处理多媒体文件的。相对的,mod_avcodec就实现了H264、H263之类的编码,而libavformat就支持mp4文件等。
后来,这两个模块合并成了一个模块,叫mod_av。就是大家在FreeSWITCH 1.6里看到的。不过,这个模块默认是不编译的,所以,如果需要的话要手工编译。原因很简单,libav/ffmpeg里有一些依赖库使用的是GPL的(如libx264)。
在Debian上编译很简单,要知道,为了能在Debian上顺利编译,开发团队也是费了很大劲的。大家也都希望能支持CentOS,但CentOS上是ffmpeg,需要做兼容,FreeSWITCH团队的开发力量不够,因此这个依赖于社区支持。但遗憾的是,没有任何一个人贡献一行代码。我们中文社区的群里也有很多人遇到这个问题。不厌其烦地问,也没有任何一个人说出点钱资助一下解决这个问题。
所有人都告诉我CentOS是刚需,但对于我来讲,没有人愿意贡献代码或出资来做这件事就不是刚需。关于刚需这个话题,我改天再专门写文章来讲。今天就不多说了。
我们小樱桃团队刚刚成立,作为一个有情怀的团队,我们投入了一些力量,把这个任务完成了。虽然过程很曲折,但其实最后改的代码也没有几行。不敢独享,跟大家分享一下相关的技术要点。
首先,ffmpeg本身就有很多版本,分裂后版本就更多了。我最初开发是基于0.8.x的,后来就直接基于了ffmpeg的master版,后来,就试了libav 11.3、11.4、11.6上个月刚刚发布。最近试了ffmpeg 2.6.x、2.8.x、3.0,基本都能顺利编译过。
为了同时测多个版本,我们需要一些技巧。
首先,卸载所有随系统安装的版本。重新执行FreeSWITCH的configure,让FreeSWITCH找不到libav和ffmpeg。
然后,编译安装各个版本的libav和ffmpeg。
编译步骤满大街都是,主要的几个参数是:
--prefix=/opt/av
我安装到了 /opt/av ,当然你也可以装到 /opt/av-11.3 /opt/av-11.6之类的,ffmpeg也是一样
在开发过程中我们还遇到libx264新版本导致的问题,所以还测试了很多版本的libx264:
./configure --prefix=/opt/x264
为了让libav能找到我们自己编译的x264,指定 PKG_CONFIG_PATH
PKG_CONFIG_PATH=/opt/x264/lib/pkgconfig ./configure --prefix=/opt/av
其它的参数就看你的需求选了, 下面的例子是我们Mac上编译libv的例子
./configure --prefix=/opt/av --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libmp3lame --enable-libvo-aacenc --enable-libxvid --enable-libvorbis --enable-libvpx --enable-libfaac --enable-libspeex --enable-libx265 --enable-nonfree --enable-vda
ffmpeg的命令行也类似。实际上,最重要的是 --enable-libx264
当然,configure完了后需要make && make install,这是UNIX在软件编译安装的标准步骤,不多说。
好了,有了多个 libav和ffmpeg, 怎么让FreeSWITCH找到它呢?
到FreeSWITCH源代码目录下
cd src/mod/applications/mod_av
创建如下Makefile(如果已经有了就替换掉)
#AV=/opt/av/
AV=/usr/local/Cellar/ffmpeg/2.8.6
LOCAL_CFLAGS=-I$(AV)/include
LOCAL_LDFLAGS=-L$(AV)/lib -lavcodec -lavformat -lavutil -lavresample -lswscale
LOCAL_OBJS=avcodec.o avformat.o
include ../../../../build/modmake.rules
很简单吧,只要把AV的路径换成你libav或ffmpeg的安装路径就好了。
然后在mod_av下面执行 make install (你的FreeSWITCH必须正常编译过一遍啊,别说我没告诉你)
一切顺利的话,你就可以在FreeSWITCH里面load mod_av了。
什么?还是不行?
在Linux上,还需要设置动态库的加载路径。最简单的办法是启动FreeSWITCH的时候加到环境变量里,如,可以用以下命令启动FreeSWITCH:
LD_LIBRARY_PATH=/opt/av/lib /usr/local/freeswitch
另一种就是放到 /etc/ld.so.conf 或 /etc/ld.so.conf.d 里,并执行 ldconfig。如果你需要经常切换多个版本,还是用环境变量来得快些。关于ldconfig,也是UNIX开发者的必备修养,不知道的自己Google吧。
好了,正常 load mod_av 后,你就可以尝试使用它提供的H264编码,录音、录像、播放视频等功能了。
当然,如果你使用Git master代码,可能直接就什么也不用动,yum install ffmpeg-devel 然后 make mod_v-install 就行了,我没有试过。大家可以测一下如果使用CentOS自己带的库有没有问题,也可以告诉我各种版本的CentOS都带了ffmpeg的哪个版本。