请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

WebRTC 如何编译 //third_party/FFMpeg

还是之前那个问题,我希望在项目中用 FFMpeg 的函数,例如 avformat_open_input, avformat_find_stream_info 等等;但之前那个问题我提的解决方案感觉很有问题,编译能通过,但后期会遇到各种奇奇怪怪的问题,包括 avformat_open_input 的时候出现 Error opening file: Protocol not found,返回值为 -1330794744 等等,因此我新开一个问题来问一下。

我感觉还是应该编译 //third_party/FFMpeg 的源码,按照老师上一次的回答应该是 gn gen 的时候加上参数 “is_component_ffmpeg=true”;包括我也查了各种资料,加上了 “proprietary_codecs=true”, “rtc_use_h264=true” 和 “ffmpeg_branding=“Chrome”” 等,都没什么用,虽然在编译时已经能够加载到 //third_party/ffmpeg 里面的文件了(我看了 ffmpeg_generated.gni,确实没有swscale 部分内容,但这只是小问题,手动加上就行了),但编译出来的静态库和共享库(.a 和 .so 文件)仍然不能放到当前的 sysroot 里面去,在我的系统环境中就是:
/home/ubuntu/Desktop/WebRTC/src/build/linux/debian_bullseye_amd64-sysroot/usr/lib/x86_64-linux-gnu
这个环境下;甚至我感觉它都没编译出来静态库 / 共享库,这导致运行的时候用的是上面路径默认的陈年库文件。

根据我对版本的观察,似乎 gclient sync 的时候会下载最新版本的 FFMpeg,具体版本为 n6.1.x,但 sysroot 路径下的 .so 文件却是 n5.9.3 版本的,以下是我用 nm 判断的结果:

sysroot 下:

ubuntu@ubuntu-virtual-machine:~/Desktop/WebRTC/src/build/linux/debian_bullseye_amd64-sysroot/usr/lib/x86_64-linux-gnu$ nm -D libavformat.so.59.27.100 | grep avformat_open_input
00000000000928d0 T avformat_open_input@@LIBAVFORMAT_59

//third_party/ffmpeg 手动编译(直接在 third_party/ffmpeg 里面 Make)得到的库文件

ubuntu@ubuntu-virtual-machine:~/Desktop/ffmpeg/out/lib$ nm -D libavformat.so.61.6.100 | grep avformat_open_input
0000000000086ce0 T avformat_open_input@@LIBAVFORMAT_61

很明显,它们的大版本是不同的,我认为这是它运行 avformat_open_input 出错并返回 -1330794744 的核心问题。

我想问一下超哥,之前有没有遇到在 WebRTC 中使用 FFmpeg 的情况,具体编译方法是怎么样的(需要在 gn gen 时候加哪些参数,我加的是否正确)?以及以超哥的经验来判断,avformat_open_input 出错并返回 -1330794744 的原因是否是 #include 的头文件和 动态库文件(.so)的版本不同导致的?

正在回答 回答被采纳积分+3

1回答

提问者 奕帝传说_梦 2024-11-21 15:18:52

算了珍惜生命,别用 WebRTC 提供的 FFMpeg,连带着也别用 WebRTC 提供那个库环境了,直接用当前操作系统的环境就行了... 那个 //build/linux/debian_bullseye_amd64-sysroot/usr/lib/x86_64-linux-gnu 里面的库太难改了...


我其实大概摸索出来了,WebRTC 里面那个 //third_party/ffmpeg 里面相当于一个 in-tree ffmpeg,而 Google 提供了一个默认生成 in-tree ffmpeg 的方法,且在 //third_party/ffmpeg/ffmpeg_generated.gni 文件中也提了一嘴:this file is autogenerated by media/ffmpeg/scripts/generate_gn.py


然而我发现,在 WebRTC  里面的 media 压根没有 ffmpeg 这个文件夹,经过一大轮搜索才发现,以前它是有的,但后面 Google 想做 WebRTC 和 Chromium 的解耦,就把很多本来 Chromium 的内容给砍了。最后看了 Piasy 大神的博客(我很崇拜他,真的好厉害,对 WebRTC 的理解非常深入)Hack WebRTC 32599,知道了大致应该怎么做:


  • 首先使用 chromium/scripts/build_ffmpeg.py 对 ffmpeg 进行模块化编译,选自己需要用到的模块,形成的其实就是 in-tree ffmpeg 的库文件。

python chromium/scripts/build_ffmpeg.py linux x64 --branding \
   Chrome -- --enable-parser=hevc --enable-demuxer=mpegts \
   --enable-protocol=file --enable-muxer=matroska
  • 然后,使用 copy_config.sh 把生成的库文件弄到相应的运行环境中:

./chromium/scripts/copy_config.sh

(这就是我之前说的,为什么会一个那么新的代码用那么陈年的 .so 库,它是可以把新编译的 .so 文件弄进去的)

  • 最后,使用 generate_gn.py 生成我们的 BUILD.gn 和 ffmpeg_generated.gni:

python ./chromium/scripts/generate_gn.py


然而它是在 Chromium 那个源码上处理的,弄完上面三步之后,就可以把生成的环境挪到 WebRTC 环境去了,整体结构其实很像的,也是在 build 目录下。这样再编译就不会出现版本不匹配的问题了。但... 这 Chromium 源码 20G,而且每次这样搞也太抽象了...


然后我问了我实习公司里做 RTC 的大佬,他说公司里都用自己的 RTC,编译工具都是自研的(tencent),还给我吐槽 Google 的 BUILD.gn 也太难用了... 还让我用公司的那个工具;我说我是学生,我就想做个实验,这样乱搞我啥时候才能把实验做完,我还写不写论文了...


最终我发现,既然我 g++ 编译能搞定,我还不如直接用操作系统的库,不用它提供的那个 build/linux 环境了,完全没必要啊,我也不指望我写的代码能有什么迁移性... 所以我就直接在 gn gen 的时候加上参数 use_sysroot=false,直接用操作系统的路径。然后同时记得去掉 BUILD.gn 里面 DEPS 中对 //third_party/ffmpeg 的依赖,这样就会完全使用操作系统的库了!当然在操作系统上要装很多环境,例如 gtk3.0 等等。


虽然解决方法并不优雅,但这次算是解决了这个问题吧,至少 FFMpeg 在 WebRTC 里面能用了...


0 回复 有任何疑惑可以回复我~
  • 李超 #1
    赞,先把问题解决掉。webrtc 对ffmpeg 的使用并不是它的重点,基本上本着能用就行的原则,没有过多的考虑升级的简易性。要想解决这个问题,一种办法是自研,像腾讯,声望都是这么干的。就是成本太高;另一种是按照webrtc 自己的思路从chrome 下手,自己整理出一套方法,写个处理脚本,但这种也不容易,需要花大量的时间研究和编写脚本。总是都是不太容易的事儿
    回复 有任何疑惑可以回复我~ 2024-11-22 07:23:44
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信