基于Node/Canvas/WebSocket直播
TL;DR
- PC端浏览器将视频流直播到服务器;移动端H5接收实时数据观看视频直播;
- 学习基于websocket技术的socket.io模块的使用
- 通过浏览器获取用户音、视频流;
- 将捕获的视频流绘制到Canvas画布;
- 基于Canvas与base64编码实现数据传输与渲染
- ffmpeg输出视频帧到图像
基本实现
- 主播和观众直播与观看直播的入口均为
/live
; - 已登录的主播进入
/live
后立即开始直播,未登录的观众进入/live
后观看直播; - 若当前无直播画面,则为进入
/live
的观众循环播放录播画面; - 主播进入
/live
后,自动将所有正在观看录播画面的观众切换到直播画面; - 主播退出直播界面后,自动将所有观众切换到录播画面
- 目前仅实现无声画面直播。
笔记
-
Node服务器端与客户端均使用socket.io提供的全双工通信协议模块
# Node服务端安装Socket.io npm i socket.io # 客户端使用Socket.io-client npm i socket.io-client
-
LIVE角色分为主播端、观众端,通过共享session识别登录状态分配直播或观看权限。
# 支持session安装下方模块 npm i express-session # 与socket.io分享session还需同时安装下方模块 npm i express-socket.io-session
-
Chrome浏览器处于安全考虑,除本机IP外禁止非HTTPs协议传输的页面调用获取用户媒介权限,Firefox则无限制。
// 处理各浏览器兼容问题 navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia; // 请求获取用户媒介 navigator.getUserMedia({ audio: false, video: { width: videoWidth, height: vidoeHeight }}, onsuccess, onerror )
-
将视频帧编码为base64图像通过websocket协议传输至服务器。
// 第一个参数可以是 'image/png' 'image/jpeg' 'image/webm',后两者可设置图像质量 const quality = .5 canvas.toDataURL('image/webp', quality)
-
关于base64编码与解码
// 编码base64数据 btoa('shuaihua') // c2h1YWlodWE= // 解码base64数据。 atob('c2h1YWlodWE=') // shuaihua
-
ffmpeg每隔一段时间提取视频帧并输出为图像文件
# 每0.2秒输出一帧300*250大小的图像,以序号命名图像,图像格式为jpg ffmpeg -i ./movie/videoplayback.mp4 -f image2 -vf fps=fps=1/.2 -s 300x250 %d.jpg
待办
- 实时弹幕发言功能
- 有声直播与基于WebAudio API 的音频流播放方案
- 最大程度发挥FFmpeg模块作用
- 在现有性能限制之下,寻找画质与延迟间的平衡