搭建基于flv.js支持HTML5的直播流服务 (livego + flv.js)
方案简述
之前搭建过使用RTMP
协议推流 前端基于Flash
的直播流服务 奈何历史潮流不可挡 马上就到2020年底Adobe都要彻底停止支持 想起某位总加速师还在拼命加速倒车...
flv.js
flv.js是来自Bilibli的开源项目。它解析FLV文件喂给原生HTML5 Video标签播放音视频数据,使浏览器在不借助Flash的情况下播放FLV成为可能。( 顺带着膜谦谦大神 批判狗日的逼站 如何看待哔哩哔哩的 flv.js 作者月薪不到 5000 元?)
flv.js只做了一件事,在获取到FLV格式的音视频数据后通过原生的JS去解码FLV数据,再通过Media Source Extensions API 喂给原生HTML5 Video标签。(HTML5 原生仅支持播放 mp4/webm 格式,不支持 FLV)
flv.js 为什么要绕一圈,从服务器获取FLV再解码转换后再喂给Video标签呢?原因如下:
- 兼容目前的直播方案:目前大多数直播方案的音视频服务都是采用FLV容器格式传输音视频数据。
- FLV容器格式相比于MP4格式更加简单,解析起来更快更方便。
livego
Simple and efficient live broadcast server:
- Very simple to install and use;
- Pure Golang, high performance, and cross-platform;
- Supports commonly used transmission protocols, file formats, and encoding formats;
Supported transport protocols
RTMP、AMF、HLS、HTTP-FLV
Supported container formats
FLV、TS
Supported encoding formats
H264、AAC、MP3
大致方向就是OBS使用RTMP协议推流给livego服务器 livego从RTMP中拿出FLV格式音视频数据 flv.js通过HTTP向livego拉取FLV数据解码并喂给浏览器Video标签实现播放
OBS Studio ---> livego ---> flv.js
RTMP: 底层基于TCP,在浏览器端依赖Flash。
- HTTP-FLV: 基于HTTP流式IO传输FLV,依赖浏览器支持播放FLV。
livego部署
在这里通过容器部署 开放RTMP 1935端口、HTTP-FLV 7001端口、HTTP-API 8090端口 HLS端口暂时用不到
docker run -d -p 1935:1935 -p 7001:7001 -p 8090:8090 --name mylivego gwuhaolin/livego
容器运行起来后 通过HTTP-API获取获取频道密钥用于推流 (不得不说livego还挺适合二次开发的 )
GET http://服务器地址:8090/control/get?room=频道或房间名
OBS推流
推RTMP:rtmp://服务器地址:1935/live
flv.js前端
拉FLV:http://服务器地址:7001/live/频道或房间名.flv
<!DOCTYPE html>
<html>
<head>
<title>flv.js_demo</title>
<script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.5.0/flv.min.js"></script>
</head>
<body>
<video id="videoElement" autoplay muted></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
isLive: true,
enableWorker: true,
enableStashBuffer: false,
stashInitialSize: 128, // 减少首桢显示等待时长
url: 'http://192.168.1.9:7001/live/test.flv'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
</body>
</html>
这里flv.js引用自前端开源项目免费CDN服务
BootCDN
muted
是用来设置视频静音 不然Chrome浏览器可以会出现这个错误 (原因未知 很迷 ) :
Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first. https://goo.gl/xX8pDD
下面这三个参数为优化选项 参考https://github.com/gwuhaolin/blog/issues/3