libass + ffmpeg 的编译(FreeType2 与 HarfBuzz 的编译问题以及 ffmpeg 使用问题) 时间: 2021-02-27 15:07 分类: Linux ####前言 上一篇文章讲到`libass`问题的修复,但在修改源码后编译进`ffmpeg`却又出了新的问题。 我是在`Ubuntu`系统上编译的`ffmpeg`,教程可参看官方文档:[https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu](https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu "https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu") 注意`apt install`安装相关依赖时去掉`libass-dev`以及`libfreetype6-dev`的安装,因为我们需要手动编译。 ####问题 在手动编译`libass`的时候,我们需要先编译安装其依赖`FreeType2`和`HarfBuzz`,编译方法可从此进去参考: [http://www.linuxfromscratch.org/blfs/view/svn/general/freetype2.html](http://www.linuxfromscratch.org/blfs/view/svn/general/freetype2.html "http://www.linuxfromscratch.org/blfs/view/svn/general/freetype2.html") 如果你不注意看的话,你会发现,无论你是先编译`FreeType2`还是`HarfBuzz`,都会报错,报错的大概意思就是编译`FreeType2`时依赖`HarfBuzz`,而`HarfBuzz`没有安装;同样的先编译`HarfBuzz`,报`FreeType2`没有安装,也就是相互依赖的问题。 如果仔细一点看它的说明,你就会知道它的编译顺序是: `FreeType2` -> `HarfBuzz` -> `FreeType2` -> `HarfBuzz` 也就是每个都需要编译两次,关键是第一次编译`FreeType2`的时候`configure`命令为: > ./configure --without-harfbuzz 即先不依赖`HarfBuzz`,编译安装完`FreeType2`之后,我们就可以开始编译`HarfBuzz`。 顺利安装`HarfBuzz`后,我们需要的是依赖`HarfBuzz`的`FreeType2`,所以我们进入`FreeType2`编译目录,执行`make distclean`然后不加`--without-harfbuzz`参数重新编译安装。 最后同理重新编译`HarfBuzz`,这样一来它们相互依赖都成功编译安装,是不是有点耍流氓的感觉这种解决循环依赖的方法。关键是绕起来有点头晕。 解决完这个问题后,我们可以开始编译`libass`了,进入`libass`命令,为了与官方安装`ffmpeg`时其他依赖一致,我们执行以下`configure`命令: ``` ./configure --prefix="$HOME/ffmpeg_build" --disable-shared && \ make && \ make install ``` 安装完`libass`,我们进入其测试目录`test`,将`libass.a`拷贝进子目录`.lib`,然后`make`编译`test`程序,之后进行测试,发现一切正常。 这里说一下,本来我是想编译出完全不依赖任何`.so`动态库的`ffmpeg`的,但是最后发现不知道为什么`FreeType2`无法静态编译进`ffmpeg`,并且`HarfBuzz`也有问题,最后其实也并没有彻底解决这个问题,只是选择了折中的办法。 好了,我们最后编译`ffmpeg`,发现`ffmpeg`也有`--enable-libfreetype`参数,,不管它,加上就是,感觉没有什么影响。 编译完`ffmpeg`,由于我在之前编译`FreeType2`的时候,将其编译到`$HOME/ffmpeg_build`位置,所以测试`ffmpeg`的时候报错说`libfreetype.so.6`没找到。 这就是依赖动态库的坑,我本来想静态编译的,但发现`FreeType2`加上`--disable-shared`只编译静态库,编译能成功,但还是会报`libfreetype.so.6`没找到,最后只能去掉`--disable-shared`重新编译生成`libfreetype.so.6`在`$HOME/ffmpeg_build/lib`目录下,然后手动拷贝一份到`/usr/lib`目录。 这就完了吗?没有,最后的问题也是最坑的问题,测试`ffmpeg`时发现一直报错,意思就是有个函数未定义,这种错误都是依赖库的问题,但是明明我的依赖库都安装了的,单独测试`libass`的时候也是完全没有问题的。 最后发现测试`ffmpeg`时打印出来的日志`harfbuzz`版本为`1.0.1`,而我手动编译的明明是`2.7.4`,并且这段日志是`libass`库打印出来的,因为格式与单独测试`libass`一摸一样,只是单独测试`libass`时,打印的是正确的`2.7.4`,而报错的函数应该是`1.0.1`版本之后才有的,为什么编译进`ffmpeg`就发现了这么神奇的问题。 真他娘的操蛋,后面重新编译安装了几次`FreeType`、`HarfBuzz`、`libass`都是这样,因为最开始我是用的`apt install`安装的`freetype`,因为它自动安装的`HarfBuzz`是低版本的,我猜可能是没卸载干净。 但是单独测试`libass`为啥没问题,编译进`ffmpeg`就... 最后各种尝试都未能解决,无意间将`-vf ass=sub.ass`压制字幕的滤镜参数改为`-vf subtitles=sub.ass`竟然成功了!它两者的区别好像就是`ass=sub.ass`无需依赖`libavc*`相关的库,实际上改了之后`HarfBuzz`版本依旧是`1.0.1`,我也不知道为什么没报错了,可能`subtitles`滤镜没有使用报错的函数了吧。 ####总结 最后勉强解决了这些问题,可能是系统不够干净,以前安装过相关的库导致的这个问题。 以后在干净系统上编译安装`ffmpeg`应该不会有什么大问题。 就这样吧,本来只是想修复`libass`的渲染 bug,没想到其过程出现了这么多新的问题。 ####更新 上面原因找到了,就是以前`apt install`安装过`libfreetype6-dev`导致的,使用`apt purge --autoremove libfreetype6-dev`卸载即可,注意一定要加`--autoremove`因为`HarfBuzz`就是`libfreetype6-dev`依赖自动安装的。 之后再重新编译`FreeType`以及`libass`与`ffmpeg`即可。 最后还是换回`ass=sub.ass`滤镜,因为测试`subtitles`滤镜发现字幕颜色较亮并且锯齿比较明显。 标签: 无