主流流媒体协议归纳总结:
协议名称 | 网络传输协议 | 延时 | 编码类型 | HTML5支持情况 |
---|---|---|---|---|
RTSP | TCP/UDP/组播 | 0~3s | H264/H265 | 不支持,(RTSP over HTTP除外) |
RTMP | TCP | 0~3s | H264/H265(CodecID =12) | 不支持 |
HLS | HTTP短连接 | 1~10s | H264/H265 | video标签支持 |
HTTP-FLV | HTTP长连接 | 0~3s | H264/H265(CodecID =12) | flv → fmp4 → video标签 |
HTTP-fmp4 | HTTP长连接 | 0~3s | H264/H265 | video标签原生支持 |
WebSocket-FLV | WebSocket | 0~3s | H264/H265(CodecID =12) | flv → fmp4 → video标签 |
WebSocket-fmp4 | WebSocket | 0~3s | H264/H265 | 使用MSE,vidoe标签播放 |
在直播场景,目前主流的方案是http-flv,这个协议的优劣分析:
优点:
生态比较完善:
大多数后端流媒体服务器都支持rtmp/http-flv协议,比如srs,zlmediakit。
大多数web播放器也支持http-flv协议,比如flv.js,DPlayer,ckplayer。
很多CDN都支持http-flv分发。
视频实时性比较好,可以做到0~3s;
缺点:
flv不支持H.265;
flv数据解析过程比较复杂,web播放器需要将flv转为fmp4数据,然后用MediaSource播放;
HLS协议也是一个选择,HLS支持H.265,但是hls播放延迟较大;
由于chrome浏览器对同源http长连接的并发数限制为6个,所以http-flv最多只能播放6个画面,此时可以考虑使用websocket代替http,即
websocket-flv协议;
H.264:浏览器的video标签支持H.264编码格式,所以解码和渲染由浏览器内部完成;
H.265:主流方案是webassembly+webGL;
github地址:https://github.com/v354412101/wsPlayer
wsPlayer是一款专注于WebSocket-fmp4协议的web视频播放器,HTTP/WebSocket-fmp4协议与RTMP、HLS、HTTP-FLV相比,具有播放延时短,HTML5兼容性好等优点;
WebSocket-fmp4协议支持H.264/H.265,视频实时性比较好,协议解复用简单,并发路数没有限制。
将WebSocket收到的fmp4 Segment片段appendBuffer
到MediaSource
中,此时video.buffered
会记录当前已经appendBuffer
的视频时间段,然后将video.buffered
的起始时间设置给video.currentTime
,然后浏览器就会从video.buffered
缓存的视频开始播放
推荐使用ZLMediaKit作为WebSocket-fmp4协议的后端流媒体服务器
1)部署后端流媒体服务器
docker pull panjjo/zlmediakit
docker run -id -p 8080:80 -p 554:554 panjjo/zlmediakit
2)使用ffmpeg命令,向ZLMediaKit添加一路RTSP推流
ffmpeg -re -stream_loop -1 -i test.mp4 -an -vcodec copy -f rtsp -rtsp_transport tcp rtsp://192.168.1.3/live/test
3)根据ZLMediaKit的播放url规则得知,WebSocket-fmp4协议的URL格式为:
ws://192.168.1.3:8080/live/test.live.mp4
4)然后调用播放器代码:
<html><head></head>
<body>
<script type="text/javascript" src="mp4box.all.min.js"></script>
<script type="text/javascript" src="wsPlayer.js"></script>
<video muted autoplay id="video"></video>
<script>
document.addEventListener('DOMContentLoaded', function () {
var player = new wsPlayer("video", "ws://192.168.1.3:8080/live/test.live.mp4");
player.open();
});
</script>
</body>
</html>
依赖库:https://github.com/gpac/mp4box.js
v1.0 实现用video标签,调用MSE播放WebSocket-fmp4(H.264)直播流,并把播放器封装为标准的npm组件;
v2.0 实现用WebAssembly FFmpeg解码H.265,然后用canvas标签WebGL渲染YUV,从而实现播放WebSocket-fmp4(H.265)直播流,并实现动态切换H.264、H.265这两种播放机制;
v3.0 实现视频流SEI信息的callback回调