概述
目录
- 参考
- 理论
- iceServer
- WebRTC共分成三个API,分别对应上面三个作用。
- getUserMedia
- 调用流程
- 开发步骤
- leave、peer-leave信令实现
- offer、answer、candidate信令实现
- 开发
- 获取浏览器的流
- 常规设置
- 设置限制条件
- 创建RTCPeerConnection
- RTCDataChannel
- WebRTC Security
- 外部函数库
- 多对多聊天
、
参考
什么是WebRTC|WebRTC入门到精通必看|快速学会音视频通话原理|WebRTC超全资料分享FFmpeg/rtmp/hls/rtsp/SRS
WebRTC
**WebRTC详细指南**
http://www.vue5.com/webrtc/webrtc.html
WEBRTC三种类型(Mesh、MCU 和 SFU)的多方通信架构
理论
WebRTC API包括媒体捕获,音频和视频编码和解码,传输层和会话管理
。
假设我们是一个视频会议的发起人,我们当然先要知道,我们想跟谁进行视频通话,对方需要把相关的环境数据,比如我用的是什么视频编码啊,我们通信的协议是什么?我们把这些数据信息取了个名字叫 sdp。互相交换了环境数据后,被叫端需要把数据的地址准备好,这些数据协议我们成为 ice,当数据准备完成以后,被叫端把ice发给发起端,发起端通过这个ice就能够连上被叫端了。
简单的总结,互换两种信息,环境描述数据和数据地址。这两种叫为 sdp和ice。
iceServer
webrtc建立点对点的对等连接需要用到iceServers参数,可以使用公开免费的一些ice服务器资源,也可以使用开源程序自己搭建ice server,找了一些资源供参考:
1、IceBox https://doc.zeroc.com/ice/latest/icebox
https://blog.csdn.net/u011784767/article/category/7006667 这里有三篇介绍IceBox的文章
2、coturn https://github.com/coturn/coturn
https://www.cnblogs.com/wunaozai/p/5520084.html 这篇文章里有介绍coturn及安装使用
3、免费直接可用的iceserver列表 https://gist.github.com/yetithefoot/7592580
对于目前我的应用需求来说只需要用到getUserMedia和canvas 就够了,这里没有讲到的关于webrtc的知识还有很多,后续就不做补充了,最好的学习资源都在 https://webrtc.org/start/
4、demo https://www.qcloudtrtc.com/webrtc-samples/choosedevice/index.html
WebRTC共分成三个API,分别对应上面三个作用。
- MediaStream (又称getUserMedia)
- RTCPeerConnection
- RTCDataChannel
getUserMedia
navigator.getUserMedia方法目前主要用于,在浏览器中获取音频(通过麦克风)和视频(通过摄像头),将来可以用于获取任意数据流,比如光盘和传感器。
下面的代码用于检查浏览器是否支持getUserMedia方法。
navigator.getUserMedia = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
if (navigator.getUserMedia) {
// 支持
} else {
// 不支持
}
Chrome 21, Opera 18和Firefox 17,支持该方法。目前,IE还不支持,上面代码中的msGetUserMedia,只是为了确保将来的兼容。
getUserMedia方法接受三个参数。
navigator.getUserMedia({
video: true,
audio: true
}, onSuccess, onError);
getUserMedia的第一个参数是一个对象,表示要获取哪些多媒体设备,上面的代码表示获取摄像头和麦克风;onSuccess是一个回调函数,在获取多媒体设备成功时调用;onError也是一个回调函数,在取多媒体设备失败时调用。
调用流程
开发步骤
- 客户端显示界面
- 打开摄像头并显示在页面
- websocke连接
- join、new-peer、resp-join信令实现
- leave、peer-leave信令实现
- offer、answer、candidate信令实现
leave、peer-leave信令实现
- 点击离开按钮
- 响应离开按钮事件
- 将leave发送给服务器
- 服务器处理leave。将发送者删除并通知房间(peer-leave)其他人
- 房间其他人在客户端响应peer-leave事件
offer、answer、candidate信令实现
- 收到new-peer(handleRemoteNewPeer处理) ,作为发起者创建RTCPeerConnection,绑定事件响应函数,加入本地流
- 创建offer sdp,设置本地sdp,并将offer sdp发送给服务器
- 服务器收到offer sdp转发给指定的remoteClient
- 接受者收到offer,也创建RTCPeerConnection,绑定事件响应函数,加入本地流
- 接受者设置远程sdp,并创建answer sdp,然后设置本地sdp并将answer发送给服务器
- 服务端收到answer sdp转发给指定的remoteClient
- 发起者收到answer sdp,则设置远程sdp
- 发起者和接受者都收到ontrack回调事件,获取到对方码流的对象句柄
- 发起者和接受者都开始请求打洞,通过onIceCandidate获取到打洞信息(candidate)并发送给对方
- 如果P2P能成功则进行P2P通话,如果P2P不成功,则进行中继转发通话
开发
获取浏览器的流
常规设置
var constraints = {video: true, audio: true};
function onSuccess(stream) {
var video = document.querySelector("video");
video.src = window.URL.createObjectURL(stream);
}
function onError(error) {
console.log("navigator.getUserMedia error: ", error);
}
navigator.getUserMedia(constraints, onSuccess, onError);
如果网页使用了getUserMedia方法,浏览器就会询问用户,是否同意浏览器调用麦克风或摄像头。如果用户同意,就调用回调函数onSuccess;如果用户拒绝,就调用回调函数onError。
onSuccess回调函数的参数是一个数据流对象stream。stream.getAudioTracks方法和stream.getVideoTracks方法,分别返回一个数组,其成员是数据流包含的音轨和视轨(track)。使用的声音源和摄影头的数量,决定音轨和视轨的数量。比如,如果只使用一个摄像头获取视频,且不获取音频,那么视轨的数量为1,音轨的数量为0。每个音轨和视轨,有一个kind属性,表示种类(video或者audio),和一个label属性(比如FaceTime HD Camera (Built-in))。
onError回调函数接受一个Error对象作为参数。Error对象的code属性有如下取值,说明错误的类型。
PERMISSION_DENIED:用户拒绝提供信息。
NOT_SUPPORTED_ERROR:浏览器不支持硬件设备。
MANDATORY_UNSATISFIED_ERROR:无法发现指定的硬件设备。
设置限制条件
getUserMedia方法的第一个参数,除了指定捕获对象之外,还可以指定一些限制条件,比如限定只能录制高清(或者VGA标准)的视频。
var hdConstraints = {
video: {
mandatory: {
minWidth: 1280,
minHeight: 720
}
}
};
navigator.getUserMedia(hdConstraints, onSuccess, onError);
创建RTCPeerConnection
RTCPeerConnection
的作用是在浏览器之间建立数据的“点对点”(peer to peer)通信,也就是将浏览器获取的麦克风或摄像头数据,传播给另一个浏览器。这里面包含了很多复杂的工作,比如信号处理、多媒体编码/解码、点对点通信、数据安全、带宽管理等等。
不同客户端之间的音频/视频传递,是不用通过服务器的。但是,两个客户端之间建立联系,需要通过服务器。服务器主要转递两种数据。
通信内容的元数据:打开/关闭对话(session)的命令、媒体文件的元数据(编码格式、媒体类型和带宽)等。
网络通信的元数据:IP地址、NAT网络地址翻译和防火墙等。
WebRTC协议没有规定与服务器的通信方式,因此可以采用各种方式,比如 WebSocket
。通过服务器,两个客户端按照 Session Description Protocol(SDP协议)
交换双方的元数据。
RTCPeerConnection带有浏览器前缀,Chrome浏览器中为webkitRTCPeerConnection,Firefox浏览器中为mozRTCPeerConnection。Google维护一个函数库
adapter.js
,用来抽象掉浏览器之间的差异。
RTCDataChannel
RTCDataChannel的作用是在点对点之间,传播任意数据。它的API与WebSockets的API相同。
下面是一个示例。
var pc = new webkitRTCPeerConnection(servers,
{optional: [{RtpDataChannels: true}]});
pc.ondatachannel = function(event) {
receiveChannel = event.channel;
receiveChannel.onmessage = function(event){
document.querySelector("div#receive").innerHTML = event.data;
};
};
sendChannel = pc.createDataChannel("sendDataChannel", {reliable: false});
document.querySelector("button#send").onclick = function (){
var data = document.querySelector("textarea#send").value;
sendChannel.send(data);
};
Chrome 25、Opera 18和Firefox 22支持RTCDataChannel。
WebRTC Security
我们将在“WebRTC信令”一章中为我们创建的信令服务器添加安全功能。会有两个增强功能 -
- 使用Redis数据库进行用户认证
- 启用安全套接字连接(https)
外部函数库
RTCPeerConnectionl,RTCDataChannel由于这两个API比较复杂,一般采用外部函数库进行操作。目前,视频聊天的函数库有SimpleWebRTC、easyRTC、webRTC.io,点对点通信的函数库有PeerJS、Sharefest。
下面是SimpleWebRTC的示例。
var webrtc = new WebRTC({
localVideoEl: 'localVideo',
remoteVideosEl: 'remoteVideos',
autoRequestMedia: true
});
webrtc.on('readyToCall', function () {
webrtc.joinRoom('My room name');
});
下面是PeerJS的示例。
var peer = new Peer('someid', {key: 'apikey'});
peer.on('connection', function(conn) {
conn.on('data', function(data){
// Will print 'hi!'
console.log(data);
});
});
// Connecting peer
var peer = new Peer('anotherid', {key: 'apikey'});
var conn = peer.connect('someid');
conn.on('open', function(){
conn.send('hi!');
});
多对多聊天
参考:WebRTC从一对一到多对多
如果要再加入一个人,其实也是一样的流程,假设新加入的人是 C,那么,只需要 C 分别跟 A 和 B 交换 SDP 和 Candidate 即可建立新的通话链路。C 加入后,谁来主动发送 OFFER 呢 ?常用的策略有 2 种:
-
每当有新的成员加入到房间后,房间内的每个人主动给新成员发 OFFER,并等待他回复 ANSWER 建立新的 PeerConnection 连接
-
每当有新的成员加入到房间后,新成员主动给房间的每个人发 OFFER,并等待 ANSWER 建立新的 PeerConnection 连接
参考代码:https://github.com/Jhuster/RTCStartupDemo/tree/master/RTCClientDemo/Web/multiple
最后
以上就是勤劳大门为你收集整理的WebRTC实战-第二章-使用WebRTC实现音视频通话参考理论开发步骤开发外部函数库多对多聊天的全部内容,希望文章能够帮你解决WebRTC实战-第二章-使用WebRTC实现音视频通话参考理论开发步骤开发外部函数库多对多聊天所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复