相关技术栈
对于移动端来说,大多是视频聊天功能都是采用的Native端的代码来实现,这种方式性能好,兼容性强但是开发成本也会高一些,那么本文就来介绍一下采用纯H5的方式来实现视频聊天功能。
- WebRTC
- Socket.io
- Node.js
项目截图:
推荐使用Safari打开。
WebRTC介绍
WebRTC 主要提供了三个核心的 API:
- getUserMedia:可以获取本地的媒体流,一个流包含几个轨道,比如视频和音频轨道。
- getDisplayMedia:获取电脑屏幕的视频流,不过暂时无法获取音频媒体流,如果需要音频流,手动添加到轨道内,使之同步播放。
- RTCPeerConnection:用于建立 P2P 连接以及传输多媒体数据。
- RTCDataChannel:建立一个双向通信的数据通道,可以传递多种数据类型。
通过这几个 API,我们可以获取本地的音视频流,然后与其他浏览器建立点对点连接并将音视频流发送给对方,还可以建立一个建立一个双向的数据通道,发送文本、文件等实时数据。
本次的项目,我们主要用到的是getUserMedia
和RTCPeerConnection
相关的API。
getUserMedia音视频采集 API
可以使用浏览器提供的getUserMedia
接口,采集本地的音视频。
const localVideo = document.getElementById('local-video');
// 非安全模式(非https/localhost)下 navigator.mediaDevices 会返回 undefined
const mediaStream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
localVideo.srcObject = mediaStream;
RTCPeerConnection创建点对点连接的 API
RTCPeerConnection
作为创建点对点连接的 API,是我们实现音视频实时通信的关键,主要会用到以下方法和事件:
媒体协商方法
- createOffer
- createAnswer
- setLocalDesccription
- setRemoteDesccription
重要事件 - onicecandidate
- ontrack
对于点对点连接,就需要有发送方和接收方,对应上面的代码,分别是:
发送方:
const pc = new RTCPeerConnection(iceConfig);
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
sendToPeerViaSignalingServer(SIGNALING_OFFER, offer); // 发送方发送信令消息
接收方:
const pc = new RTCPeerConnection(iceConfig);
await pc.setRemoteDescription(offer);
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
sendToPeerViaSignalingServer(SIGNALING_ANSWER, answer); // 接收方发送信令消息
添加音视频流:
// 添加音视频流
mediaStream.getTracks().forEach(track => {
pc.addTrack(track, mediaStream);
});
接收音视频流:
remotePeer.ontrack = function(evt) {
const remoteVideo = document.getElementById('remote-video');
remoteVideo.srcObject = evt.streams[0];
}
有些会采用addstream
和onaddstream
属于老版本的API,这里不再推荐使用。
通信协商流程
在 WebRTC 中,有一个专门的协议,称为Session Description Protocol(SDP),可以用于描述上述这类信息。因此参与音视频通讯的双方想要了解对方支持的媒体格式,必须要交换 SDP 信息。而交换 SDP 的过程,通常称之为媒体协商。整个媒体协商流程如下:
-
呼叫端创建 Offer(createOffer)并将 offer 消息(内容是呼叫端的 SDP 信息)通过信令服务器传送给接收端,同时调用 setLocalDesccription 将含有本地 SDP 信息的 Offer 保存起来。
-
接收端收到对端的 Offer 信息后调用 setRemoteDesccription 方法将含有对端 SDP 信息的 Offer 保存起来,并创建 Answer(createAnswer)并将 Answer 消息(内容是接收端的 SDP 信息)通过信令服务器传送给呼叫端。
-
呼叫端收到对端的 Answer 信息后调用 setRemoteDesccription 方法将含有对端 SDP 信息的 Answer 保存起来。
更多关于WebRTC相关的文档可以参考[官网地址]webrtc.github.io/webrtc-org/architecture/
项目代码
在这里就不整体贴大段的代码来讲解了,感兴趣的童鞋可以参考源码[GitHub]github.com/lvming6816077/liveone来理解,这里笔者简单的说明一下整体的代码逻辑。
- 对于Vue端主要实现的是视频的预览功能和一些来电或者响应相关的CSS3动画。
- 对于Node.js端主要实现的是实时的信息通信(socket.io的room相关API),包括了识别对方的信令信息和用户的一些基本头像昵称信息的通信。
- 整体的WebRTC协议的逻辑都是安装上文中所讲解的代码方式来体现。
热门评论
搭建怎么收费呢