什么是Flv.js
Flv.js 是一个用于播放 FLV 格式视频的 JavaScript 库(由国人开发)。
FLV 是一种流媒体格式,常用于网络视频播放。Flv.js 可以让你在不需要 Flash 插件的情况下,在浏览器中播放 FLV 视频。
Flv 在国内被广泛应用(国外没啥人用),目前最新的npm包已经转为github.com/xqq/mpegts....(作者相同,但已经离开bilibili)
Flv.js 的原理是什么?
flv.js 直播方案有两种协议http/s 和 websocket,这里以http-flv为例:
- 首先使用
fetch
去拉 flv 直播流。 - 使用 HTTP/1.1 的 chunked transfer encoding 功能,流式下载视频 chunk 片段。
- 使用
FlvDemuxer
流式解封装 flv 视频流。 - 对视频流进行修复做音视频同步。(一些音视频流可能会有问题)
- 使用
FMP4Remuxer
将视频流封装成 FMP4 格式。 - 最后将封装好的 FMP4 片段数据交给 MSE 播放。
MSE 是什么?
developer.mozilla.org/en-US/docs/...
使用MSE,有个很明显的特征, src是blob;具体可以看看MDN的介绍
flv.js 为什么要绕一圈,从服务器获取 FLV 再解码转换后再喂给 Video 标签呢?原因如下:
-
兼容目前的直播方案:目前大多数直播方案的音视频服务都是采用 FLV 容器格式传输音视频数据。(HTML5 原生仅支持播放 mp4/webm 格式,不支持 FLV)
-
FLV 容器格式相比于 MP4 格式更加简单,解析起来更快更方便。
flv.js换成mpegts.js,会有什么方面的提升吗?
-
更新了项目的构建工具;用 webpack 替换了 gulp 打包,并支持 typescript
-
新增了对 MPEG2-TS 流的支持
-
修复了部分空指针错误
-
调整了stashSize以支持低延迟
-
新增了如
liveBufferLatencyChasing
,liveBufferLatencyMaxLatency
,liveBufferLatencyMinRemain
的配置以支持直播追帧 -
修复了
fetchStreamLoader
中断 fetch 请求问题 -
更新了音画同步算法;采用了新的音频填充算法
Flv.js 优化延迟
因为video 标签本身的缓冲区设定,在播放端会有1.5s的延迟;如何配置,衡量播放体验和延迟,成为了问题的关键。
这里直接上代码:【倍速方案与跳帧方案结合,具体参数可以自行微调】
Flv.js 首帧播放监听
Flv.js 画面卡顿监听
【踩坑】video标签会自动暂停(窗口失去焦点),这个时候STATISTICS_INFO 依旧会触发,要加上video.paused 来判断
Flv.js 错误监听
【踩坑】多路视频同时直播
由于浏览器对 http 1.0 的限制,以Chrome为例,同一个浏览器下,最多只能播6路同源地址下的视频(包括多个标签页也会被合算在内)
目前的解决方案有:
-
使用http 2.0,由于http 2.0的多路复用,可以同屏播放多个视频流
-
使用 websocket
-
通过为流分配不同的服务端地址
【踩坑】enableWorker: true
虽然作者说开启worker 多线程转码视频,能降低延迟
但是如果你的video有经常销毁&创建的场景,worker的生命周期跟随销毁创建,对内存&性能都有一定的影响(源码中使用的worker-loader把js 转为blob注入的)
奇怪的问题
我还遇到一个奇怪的问题,开启了worker和webpack 的optimization-minimize,则出现无法执行的问题。https://github.com/xqq/mpegts.js/issues/149
关闭minimize或者关闭worker则没问题
(可能是二次混淆压缩的问题)