基于WebRTC的在线视频会议
基于WebRTC的在线视频会议
跟小伙伴有很多话想说,但每次还要先安装腾讯会议再启动的麻烦行为让我感到厌倦,碰巧最近接触到了一些WebRTC的知识,就想着能否实现一个在线的视频会议让我们随时随地不受任何束缚的一起聊天、看电影,这是本项目的初衷😎
1. 相关背景
背景已经说的很明确了,就是一个爱折腾的人一拍脑袋想出的奇思妙想。
我的设想中,在线会议首先要具有以下几个功能:
- 可以视频+语音聊天
- 有文字聊天频道,方便某些不适合开视频语音的场所
- 有能一起看电影的观影厅
- 观影时可以发送弹幕互动
- 超可爱的头像😍
- 超有趣的灵魂😘
- ……
哈哈哈扯得有点远啦,其实本质上我觉得系统应该有腾讯会议的基础功能+腾讯视频的一起看功能,多余的功能就暂时不进行考虑啦,大概的系统架构如下
2. 技术栈
考虑到朋友手机使用的最为频繁,本项目面向手机等移动端,优先考虑移动端的开发工具
前端系统(NodeJS)
- Vue3
- Vant(UI框架)
- VueX(状态管理)
- Socket.io
- Vite
信令服务器(NodeJS)
- Socket.io
- Express
3. 实现效果
视频聊天
文字频道
一起看视频
4. 优化
1. 跨网络通信
简述
Nat技术的普及缓解了IPv4地址紧缺的问题,但也导致P2P网络打洞更加困难,由于多个设备共享同一IP出口,当数据包返回时,无法找到对应的设备,会导致P2P网络无法建立
方法
增加STUN服务器作为P2P网络打洞失败时的备选项,当打洞失败后,设备转而求其次与STUN服务器建立连接,并通过STUN服务与对端相连。
这种方法好处是可以保证双方必定可以建立链接
坏处是STUN服务器相当于中继,要想具有较好的通信质量,其带宽需要尽可能大
更近一步
既然通过NAT后因为无法寻址导致网络打洞成功率低,那么我们是否可以通过建立一个虚拟的局域网来规避这个问题呢?
答案是可行的,这也是本系统采用的方法(其实是没钱买国内大带宽的服务器😭),利用异地组网的思想,可以将不同区域的若干设备组成一个虚拟的局域网,然后P2P建立连接时通过该虚拟局域网即可实现正确的网络寻址,方法的话有很多种,本系统采用了Tailscale的形式,类似的还有蒲公英的异地组网等,就不展开叙述了
2. 一起看功能
简述
因为我与朋友经常一起看视频,所以有了这个功能模块
方法
一起看的功能有两种实现,一种是基于WebRTC,利用浏览器的共享屏幕功能与对方实现一起看视频,类似与腾讯会议中的共享桌面,这种方式好处很多
- 可以保证进度的统一
- 可以方便的切换控制
- 可以随时暂停、取消
但仍然存在一些问题,第一,移动端无法使用共享屏幕的接口;第二,流畅的共享屏幕需要非常大的带宽
这两个方法,暂时没办法解决(没钱😭),因此我想到了第二种方法
其实不难想象,类似的,腾讯视频中的一起看功能也肯定不是利用屏幕共享,网络视频必然有一个可访问地址,只要我们双方同时观看一个网络视频,然后同步进度这不就是一起看嘛😁
但实际中该方法需要考虑的因素也不少,首先共享屏幕方式的优点在这种方法里都是很棘手的问题,对此,本项目使用几个方案来保证一起看的运行:
- 信令服务器同步视频进度,参与方上报实时进度,但以主持人进度为准
- 主持人可更改
- 信令服务器使用缓存保存短期内的房间信息
嘿嘿,这样下来一起看的功能就完成啦