blog icon indicating copy to clipboard operation
blog copied to clipboard

一个异想天开的网页视频播放器

Open eyasliu opened this issue 4 years ago • 2 comments

本文全程无干货,不建议阅读

开头

首先,我们写 web 前端的时候,如果要播放一个视频该怎么做呢?想都不用想,肯定是 html 的 video 标签啊。多简单,给video.src 附一个值,它就可以自动播放了。

video 标签的局限性

video 标签用起来当然方便,但是呢,他也有很大的局限性。

首先我们想要给视频加滤镜怎么办?我要播放其他格式视频怎么办?那就没办法了,目前的video 标签还没那么多功能。

如果要给视频加滤镜,现在的video标签是没有办法做到的,它没有暴露任何相关滤镜处理视频的API。如果我想要在网页播放 hls, flv, mkv, rmvb. avi 这种格式的视频怎么办,光是靠 video 标签也是没办法做到的,它只支持很有限的那几种格式罢了。

当 Video 遇上 MSE

所谓 MSE (Media Source Extensions API) 就是给 video 加上了流媒体功能,传入视频流给 video 播放。这就扩展 video 的 API,能实现一些以前做不了的事。首先是流媒体功能,可以播放直播流了,其次是可以给视频做重编码后使用video标签播放。

xqq 在哔哩哔哩的时候实现了一个 flv.js 播放器,能播放flv视频。它的原理,就是通过获取 flv 的数据流,实时转换成 mp4 的数据流,然后通过 MSE 喂给 video 标签,video 标签发现这是 mp4 格式的视频流,然后就给它播放。这里有两个关键点,重编码视频数据流,和 MSE。

类似的项目还有 hls.js

但是,MSE的虽然扩展了video标签功能,但是对视频流的局限更大了,不仅需要mp4格式,还需要是 fragmented mp4 才能使用。但是我想要的是不仅于此

一些不切实际的想法

有 flv.js 这么一个例子,我就突发奇想,是不是可以给其他的视频流也给转成 mp4 的视频流,然后同理可得,实现网页播放器可播放多种数据格式的视频,比如 mkv, hls, avi, rmvb, rm 等等。一番恶补音视频知识后,发现有些阻碍,flv 和 mp4 这是两种视频容器,他们的视频编码可能是相同的,都是 H264,flv 转 mp4 其实只是转换了容器,视频编码其实不需要转的。其他的视频容器格式可不一定是 H264,而且就算是H264,那格式格式转换那还是一道跨不过去的坎。那么如果我想做一个能像本地播放器那样能播放大部分主流格式的视频,我该怎么做呢?

其实我这个想法有点天马行空了,按照我平常学到的知识来说,当然可以否决这种需求。web播放器怎么可能做到像本地播放器那么强大呢?

希望的火苗

再恶补一些知识后,其实我发现这其实是有希望能做到的,所谓的不可能做到。其实是知识面限制了我的想象力。不过这涉及到了一些比较新,也比较难的知识面了。

wasm 可以使得在浏览器高效的执行其他语言的逻辑,由于是新特性,兼容性不太好,但是也不差,各个平台的新版主流浏览器都已支持。有个项目叫 ffmpeg.js,直接把 ffmpeg 编译成 wasm 了,而且他还提供了自定义编译脚本,使得 ffmpeg.js 的最终构建包尽可能的小。这就给视频做软解带来了希望。

WebGL 是用于构建图形应用的,这个其实是挺长时间的标准API了,兼容性不错。可以用于渲染视频图像。

然后是声音,使用 AudioContext

WebWork,这也是必须的,视频软解耗费的CPU过高,如果没有 Work ,页面将会严重的卡 CPU

这下子,理论上的各种必须的条件都满足了,就看接下来的施工了

可预见的缺陷

  • 首先是兼容性,上面的特性都比较新,在老旧浏览器肯定是用不起来的。
  • 有些视频是无法流媒体播放的,比如 AVI
  • CPU 占用会很高,毕竟软解嘛,软解就是用 CPU 做视频解码
  • WebGL渲染视频,这还得看硬件是否支持,如果不支持也没辙
  • rmvb 等 Real 系视频的编解码是不公开的,不确定能否支持

大言不惭的目标

实现一个可扩展、可嵌入、兼容 html video 标准,可播放任意视频格式的 Web 视频播放器。

目前进展

正在建文件夹

eyasliu avatar Sep 21 '20 01:09 eyasliu

参考资料:

  • https://zhuanlan.zhihu.com/p/40786748 这里介绍了 wasm 的编译、使用细节,可根据该方案,定制wasm功能,将各种解码器分开,实现根据视频编码动态加载视频解码器
  • WasmVideoPlayer 一个可用的demo,方案跟这里提到的几乎类似,并且定制的wasm很小,原来已经有大佬已经做出来了
  • https://zhuanlan.zhihu.com/p/27910351 完全使用ffmpeg的命令行方法,几乎不能用来做播放器,只适用下载好完整视频文件后对视频做处理

要实现这个播放器,C 语言是必备技能,目前C语言掌握程度 1%,持续充电~~~

eyasliu avatar Nov 10 '20 03:11 eyasliu

构建ffmpeg wasm的脚本 https://gist.github.com/eyasliu/0e2284b4554c63fefcb5e75f386722df

eyasliu avatar Nov 10 '20 03:11 eyasliu