在浏览器中使用ffmpeg在MP4中使用HLS

你好!超过两个月的时间了,在空闲时间里,我看到了一个使用emscripten和ffmpeg将HLS和DASH转换为MP4的Web应用程序,这使我想分享如何做到这一点。

在本文中,我不会引用ffmpeg编辑和补丁的源代码,因为 其中大多数都是在我的膝盖上完成的,而我对C的掌握也不是很好。但是现在有足够的文章可以为您提供帮助。

介绍


两年前,我的目标是将音频和视频轨道合并到一个mp4文件中。然后,我只是沉迷于emscripten,并为基础知识找到了ffmpeg.js存储库,从中学到了很多东西。然后,尽管我非常有条件地使用C语言,但我几乎可以实现该目标。
了解源代码后,ffmpeg制作了一个用于处理文件系统的补丁,其中从js中称为异步函数的文件中读取,我从中读取文件的blob并传递了缓冲区,并且在编写时,我调用了将缓冲区数据发送到存储库的js函数。

但是异步函数存在一个问题,我无法正确解决,它们通过asyncify(fastcomp)工作,在某些情况下无法正常工作,即wasm中的代码执行没有停止,而没有等待js函数的结果,仅此而已抛锚。该问题已通过EMTERPRETIFY_WHITELIST标志修复,该标志显然将代码同时从wasm移至asm并减慢了速度,并且有必要调试调用堆栈并为每个异常向列表添加损坏的函数。

通常,由于存在此类问题,因此不能将其称为有效解决方案,而在此解决方案上,所有这些仍然只是一个小演示。



一年半后


看完Google Dev Summit上有关WebAssambly中新功能的报告后,我去看看emscripten的工作情况并看到一条消息:
从1.39.0版(2019年10月)开始,Emscripten使用上游LLVM wasm后端发出WebAssembly,并且不推荐使用旧的fastcomp后端

我想尝试重建我的打包程序格式。大约一个星期,我用谷歌搜索了如何解决新的编译问题,并最终将它们放在一起。所做的更改不是很多,但是由于新的库链接程序而没有用,并且已经迫切希望收集至少一些东西,我只是找出了问题库(事实证明,库本身已连接在一起,您不再需要用手指出它们)。

而现在,这一时刻已经来临,收获了!异步代码的问题消失了,不需要调试任何东西,它从一开始就可以正常工作。

在这里,我似乎已经达到了目标,但是...出现了一个新的目标。

重写HTTP协议


这种想法在我心中已经存在了很长时间。这可以让您下载HLS或DASH,不仅可以下载现成的播放列表,还可以下载实时流。而且我从未在互联网上看到过类似的东西。

我花了大约三个星期的时间,至少短暂地与我合作。我知道C(虽然经验为零),但指针存在很多问题(即使在别人的代码中,也很难追踪到哪里去了),但最终编译出的东西没有错误。在最初的成功之后,这给了完成这个想法的更大的热情。

仅仅几个星期,最后我设法完成了工作中的http协议的第一次迭代,这似乎就是全部吗?

当最艰难的时刻结束时


至此,我已经准备好一个框架,一个带有url输入字段和一个开始按钮的小型html表单,基本上就可以了。但是仍然有必要编写一个扩展程序来绕过CORS并加载数据,创建一个可以分块写入数据的存储,建立一个带有进度显示的界面,对它们进行调试以解决不同浏览器中的问题。总的来说,现在终于可以使用它了。

基本上,创建了用户脚本,它是从ffmpeg提取请求以下载数据的代理。

几天后,Chrome和Firefox的扩展程序已准备就绪,该扩展程序使用webRequest收集了浏览器在观看视频时加载的所有hls链接。

事实证明,在Firefox中,扩展API不允许您管理电源,因此无法阻止计算机进入睡眠状态。

扩展程序如下所示:



只是改进了该网站上的页面,该页面有点用螺丝钉固定,最终确定了所有被鞭打的地方。



在测试了不同的数据存储方式之后,我发现了许多问题:

Blob -Chrome将它们写入RAM,并在溢出时掉到磁盘上,但是只有在OSX中,当内存溢出时,OS才离开帐户并关闭所有打开的应用程序。 Firefox通常总是将数据保留在内存中。

缓存存储-它的工作方式类似于IndexedDb,但是在写入数据后,它们在Chrome blob中仍保留在RAM中(无论是bug还是fitcha),但事实证明数据已写入高速缓存存储区(到磁盘),并且在内存已满时也会删除数据卷到磁盘作为blob。

IndexedDb-像时钟一样工作,知道如何存储blob,写数据时没有多余的装饰,但是Firefox严格限制了2gb的数量。

我已经完成了一点,我设法实现了通过指针中断ffmpeg进程的功能,弄清楚了如何选择格式(ffprobe)和处理网络错误。





现在,您可以在这里自己尝试结果

对我来说,当您需要在推特上录制流或下载VOD时,这是必不可少的。它也可以与笔记本电脑,调音台以及任何其他以HLS或DASH广播内容的站点配合使用(ala,ffmpeg中的DASH实现非常有条件,并且实时下载可能无法正确下载,因为它没有考虑片段请求间隔)。

感谢您的阅读!

如果您对ffmpeg和emscripten有疑问-请写信,我将尽力回答。

All Articles