现在在直播中用的最多的软件可能就是OBS了。这个免费开源(https://github.com/jp9000/obs-studio)的直播软件功能很强大,也没有烦人的小广告,不要注册不要登录,所有基于RTMP的直播平台都能用。
这个直播软件在编码直播音频流的过程中,支持使用很多种不同的AAC编码器。它大概会按照 Core-audio(苹果iTunes里的那个)、FDK-AAC、Windows Media Foundation、FFMpeg这样的顺序一个个找下去找到能用的。虽然是这个顺序,但是实际上在正常安装的OBS里面,是找不到 obs-libfdk.dll 这样一个文件的。安装的时候就不带这个文件。其实我之前也比较纳闷,这个如果效果这么好,那么为什么网上比较少见到哪里直接下载这个编码器的EXE文件呢。下午在一个群里提了这样的疑问,结果收到的回答大概是FDK-AAC发布源代码可以,但是因为其中涉及到一些什么专利许可证的问题,发布EXE、DLL这样的二进制文件好像是不行的。但是这些编码器里面,FDK-AAC在低码率HE-AAC v2模式下是公认的效果比较好。有的时候如果想拿来玩玩看用用看试试效果的话,就要自己从源代码编译了。
对于从源代码编译这种事,有的开源软件搞起来连程序员都会感到头疼,更不要说一般主播了。值得庆幸的是搞这个OBS的FDK-AAC插件并不麻烦,OBS那边也只要编译这个插件就行了,不用编译整个项目,甚至它用的CMake软件都可以不装。
代码主要涉及到要下载的源代码也就obs-studio和fdk-aac这两套。obs-studio到obs的github版本发布页面(https://github.com/jp9000/obs-studio/releases)找到我安装的那个版本的源代码包,下载下来就行。对于fdk-aac,也是到github上的版本发布页面(https://github.com/mstorsjo/fdk-aac/releases)下载。我下载下来是obs-studio-21.0.1.zip和fdk-aac-0.1.5.tar.gz两个文件。代码有了以后然后就是编译器。我考虑到很多主播又不是程序员,也没必要装特别硕大的Visual Studio这样的东西,于是选了相对较小的TDM-GCC编译器:它下载来的安装包才几十兆。
接下来遇到的问题是编译FDK-AAC。它的代码解压出来以后发现,没有给MinGW用的Makefile……虽然有configure那一套脚本,但是那还要装unix的sh环境,麻烦。我选择的方法是把它做给VC用的那个Makefile.vc拿来改改,改成Makefile.tdm。然后要对它进行修改,首先我们用的编译器不是VC,所以可执行文件的名字也就不是 cl 和 link、lib这种。因为这边只要编译成静态库、在链接obs插件的时候用就行了,所以link可以丢那边不管,直接把 AR = lib 改成 AR = ar 即可。然后是下面那个 CFLAGS,用的完全是VC的那一套参数。改成gcc用的就好了,我是这么改的:
改之前: CFLAGS = /nologo /W3 /Ox /MT /EHsc /Dinline=__inline $(TARGET_FLAGS) $(AM_CPPFLAGS) $(XCFLAGS) 改之后: CFLAGS = -O2 -Dinline=__inline $(TARGET_FLAGS) $(AM_CPPFLAGS) $(XCFLAGS)
总之就是往简单了去。然后还有生成静态库时候的命令,找到 $(STATIC_LIB): $(FDK_OBJS) 这边,下面的命令我直接改成
$(AR) $(ARFLAGS) qf $@ $(FDK_OBJS) $(AR) $(ARFLAGS) s $@
这样了。
还不算完成,因为nmake用的默认编译规则的语法和mingw32-make的不一样,所以还有一个地方要改。找到 .cpp.obj: 这个规则,改成 %.obj : %.cpp。这样就可以了。
然后拿到这样的Makefile.tdm之后,在TDM-GCC环境里面,用命令行 mingw32-make -f Makefile.tdm fdk-aac.lib,它能给你出个静态库出来。这一步就算完成了。
下一步是编译OBS的插件了。这个OBS插件用的FDK-AAC的头文件是把FDK里面那些所有include文件夹里的头文件全部放在一起的。所以在编译之前有个步骤要做,就是把头文件都放一起。方法是先新建一个文件夹比如叫 fdkinc,然后在里面创建 fdk-aac 文件夹,用一个for命令把头文件搞过来:
for /f %%a in ('dir include /s /b /ad') do copy /y "%%~a\*" ..\fdkinc\fdk-aac
于是现在环境够了,可以开始编译插件那个DLL文件了。
编译插件的时候也有个地方其实是缺的,那就是连接到 obs.dll 用的导入库。这个导入库正常来说,是编译obs的过程中生成的。现在我们没有,要手工做一个。TDM-GCC里有给你做这个的工具,大体上来说就是把插件中要用到的 obs.dll 里面的函数都列出来,写成一个 def 文件,比如这次用的是这样的:
LIBRARY obs.dll EXPORTS obs_data_set_default_int blog bfree obs_properties_create obs_properties_add_int obs_properties_add_bool obs_data_get_int obs_data_get_bool obs_encoder_audio bmalloc audio_output_get_channels audio_output_get_sample_rate obs_register_encoder_s text_lookup_getstr text_lookup_destroy obs_module_load_locale obs_data_set_default_bool
保存成 obs.def,用dlltool命令:
dlltool --input-def=obs.def --output-lib=obs.lib
就出来lib了。现在可以编译链接插件了,进到obs-studio-21.0.1\plugins\obs-libfdk文件夹,一行命令:
gcc -shared -oobs-libfdk.dll -O2 -I"../../libobs" -I"../../../fdkinc" obs-libfdk.c "../../../fdk-aac-0.1.5/fdk-aac.lib" "../../../obs.lib"
这样就可以获得一个 obs-libfdk.dll 了。这个文件丢到 obs 的 plugins 文件夹对应的地方(32bit就放32bit,64bit就放64bit,看用的是什么版本的TDM-GCC编译器)。
这整个过程我写了个bat文件来完成。源代码文件放进来,然后tdm-gcc装到 tdm64 文件夹,运行bat就能生成DLL。但是我没做clean,所以32编完之后想要64的话要删掉全部文件重新来一次,64编完想要32的也是一样。
附:在 obs-libfdk.c 文件里,找到 //MPEG-4 AAC-LC 注释,前面有个数字是2,改成29就可以用 HE-AAC v2了。用5是没有v2的HE。
下载build-obs-libfdk后还需要做之前的步骤吗,如何使用呢
啊,这个文章好久以前的了。我现在构建这个直接用的是cmake,不过cmake脚本没传上去。
如果这里面的构建脚本还能用,那就简单地生成dll以后放到和 obs-x264.dll 同一个文件夹里就好了。
注意debug/release配置和x86/x64配置要一致