
几天前,在上课的时候,老师的麦克风连接不上展台的电子白板,所以就无法扩音.这让我产生了一个想法,如果有一个工具,能利用手机作为麦克风,电脑1作为展示端,最好还能允许其他电脑将自己的屏幕画面推送到展示端去,是不是就能改善这个问题了呢?说干就干,我总结了这个工具的一些特点:
- 不需要安装,而且最好使用方便,操作简单,因此排除各大视频会议软件
- 传输延迟低
- 保密性,最好流传输时不经过服务器,如果一定要经过,那就经过自己的服务器
针对于以上特点,进行技术选型的时候,我做了以下选择
- 基于浏览器,只有基于浏览器,才能实现真正意义的无需安装,而且大多数电脑现在都配备了较新的浏览器,可以使用新特性
- 视频/音频传输方案使用webrtc的P2P,如果无法P2P,就通过自己的服务器进行中转
名词解释:
- stun: 用于webrtc的P2P连接中的nat打洞的协议,也就是说,如果要实现P2P连接,他是必不可少的.视频音频流量是不会通过stun服务器的,他只负责建立连接.
- turn: 用于webrtc的P2P连接中的中继的协议,如果stun的nat打洞失败(比如防火墙限制),turn可以作为公网中继,这时的rtc并不是P2P连接,而是Peer --> Server --> Peer连接,视频和音频流量需要经过此服务器
- SDP: rtc建立P2P连接的时候,双方需要交换对方的网络信息,而sdp是一种描述格式,他定义了交换过程需要发送给对方的字符串的统一格式
- ice: rtc建立连接的协议集,stun和turn是他的子集,他还包括了SDP,客户端尝试建立P2P连接时使用ice服务器列表来建立最短,最优化的连接
- Coturn: 一个开源的rtc stun + turn服务器实现
- Docker: 容器引擎,用于快速部署coturn
- docker-compose: 容器编排引擎,用于快速部署coturn
- socketio: 一种基于websocket的RPC框架,每一个peer都需要与公网上的socketio连接并在P2P连接尚未建立时交换Peers的信息.又称为信令服务器.
确定了方案以后,就开始了实施.首先部署了位于公网的coturn服务器部署,这里不展开解释,直接上docker相关配置文件.
# docker-compose.yml |
# coturn/Dockerfile |
# coturn/turnserver.conf |
WebRTC建立连接分为几个角色:
对于Peer1(发起端)而言:
- 初始化socketio连接.
let sio = io(window.location.protocol + "//" + window.location.host); |
- 初始化PeerConnection,配置ice服务器列表,我们只有1台stun+turn服务器,所以只需要配置候选列表使接收到来自服务器下发的信息(candidate)并将其通过发送到对端上.同时我们需要配置屏幕视频流,配置好后一旦连接建立,视频流就会启动传输.
let webrtcConfiguration = { |
- 发送Offer给对端
const offerOptions = { |
- 等待对端发送answer,并配置
sio.on('answer', (ans) => |
- 连接建立,webrtc会自动分析网络,如果可以,会通过stun建立P2P的连接.如果不可以,会通过中继turn服务器建立连接.
对于Peer2(接受端)而言:
- 与Peer1相同
- 除了不需要最后的“配置视频流发送”,其他与Peer1相同
- 等待接受offer,并回应answer
sio.on('offer', async (offer) => { |
- 等待接受视频流
rtc.addEventListener('track', obj => { |
对于Sockerio服务端而言:
并没有什么好说的,只需要接受客户端的offer,answer,candidate,直接广播即可.
中间遇到的坑:
- 获取不到candidate或获取到了也转发了就是怎么也连接不上.
解决方法: 检查是否开启了代理,包括各种系统级代理,浏览器代理,关闭即可.
- 获取到视频流了(即Peer2.4)中,也配置成功了,就是怎样都没声音
解决方法: https://developers.google.com/web/updates/2017/09/autoplay-policy-changes, 如果只是为了调试,可以在safari浏览器中的“此网站设置”中选择“自动播放”中的“允许全部自动播放”.
开源
这个项目时开源的,但由于时间较赶,代码质量不佳,仅供参考.
LET'S LEAVE A LITTLE NOTE
来聊聊天吧♡
你的每一句话,都会让这座小房子更温暖。
正在打开留言本…