WebRTC初试用-在线视频聊天室的基本流程

本文介绍了WebRTC技术,旨在解决在线视频传输中的服务器中继问题,通过P2P连接减少系统复杂度。主要内容包括获取流、信令传输、客户端传输的基本流程,并提供了一个简单的实例。
摘要由CSDN通过智能技术生成

WebRTC技术

在线视频传输,传统做法是做一个中继服务器,负责客户端的发现和数据的中介传输,那么就会产生一个很明显的问题,中继服务器需要
传输大量的数据,不仅如此还有复杂的流信息控制以及同步等问题。而且,随着数据量的增大,中继服务器单机无法承载,不得不做负载
均衡甚至地区分发等,大大增加系统复杂度,增加了各种成本,降低了稳定性。而且服务器作为中介,有记录用户传输数据的能力,用户
的隐私问题也值得关注。所以,如果能够让客户机P2P的连接以及传输数据,让客户机自己去处理同步以及控制问题,自己去传输流数据,
这样即可大大减小系统的复杂度。WebRTC就是致力于建立统一的浏览器标准,来完成这种P2P的传输工作。

本文声明

由于WebRTC的大量功能还处于实验阶段,即使在MDN上面,很多接口也没有详细的介绍和说明,部分没有翻译,而网上的代码大多也过时
,因为WebRTC已经duplicate一部分函数了:例如RTCPeerConnectioncreateOffer函数的successCallback参数等。所以写
此文,大略的介绍一下RTC里面的部分基础组件和常用流程。另外由于这些API处于实验阶段,仍然可能变化,本文仅限写作时的时效性。

获取流

视频,音频是以流(stream)的形式进行网络传输,为了获取一个流,可以使用HTML的getUserMedia,由于目前支持该对象的浏览器
各不相同,暂时可以用下列代码获得:

getUserMedia = (navigator.getUserMedia ||
            navigator.webkitGetUserMedia ||
            navigator.mozGetUserMedia ||
            navigator.msGetUserMedia);

getUserMedia可以用来获取用户的视频/音频流,使用如下:

getUserMedia.call(navigator, {
                "audio": true,
                "video": true
            }, function(stream) {
   
                //绑定本地媒体流到video标签用于输出
                localVideoElement.src = URL.createObjectURL(stream);
            }, function(error) {
   
                //处理错误
            });

就像代码中所描述的,处理流的第二个参数中的匿名函数,将stream使用URL.createObjectURL创建一个blob的URL,这个URL可以
绑定到HTML5的Video标签播放(记得Video标签加上autoplay属性,不然就只有一张图了)。

信令传输

要实现Client到Client的直接传输,还需要服务器协调一些数据,比如最基本的,两个客户端的IP地址是什么,好让他们互相发现。另外
由于因特网的历史原因,NAT广泛用于全世界,所以,要实现P2PNAT穿透也是一个问题,NAT穿透的问题已在上一篇讲过,这盘文章在局域
网内做一个视频传输。和服务器的传输,到了这个时代,使用websocket有很多好处,不一一列举。websocket的基本使用如下:

//没有TLS协议的话用ws://,因为chrome等浏览器要求获取用户流的网站必须是安全的,所以一般都用了TLS(HTTPS)
var socket = new WebSocket('wss://0.0.0.0/xxx'); 

socket.onopen = function() { ... }

socket.onmessage = function(event) { //event.data是具体信息 }

socket.send(....);

客户端(浏览器)传输

浏览器间流的传输使用PeerConnection,这个对象封装了底层的传输,以及流数据的编码、同步控制,使用起来相当简易。同样,获取这个
对象也要兼容不同浏览器:

PeerConnection = (window.PeerConnection ||
            window.webkitPeerConnection00 ||
            window.webkitRTCPeerConnection ||
            window.mozRTCPeerConnection);

该对象的传输涉及几个概念,candidate是ICE候选信息,包括了对端的IP地址等信息,用于互相发现,offeranswer可能是用来同步
数据等等的,每次发送数据时,发送方都要发送一个offer过去,接收方收到后,根据offer更新自己的会话,接收方也可以发送answer
信令让发送方更新会话。发送方和接收方一开始就要确定,身份在整个传输中不变(确定谁是发送谁是接收就交给协调服务器好了)。同时,answer
信令在接收到offser之前是不能发送的,而且在发送offer信令的时候,也会发送candidate过去,所以,传输流程如下:

  1. 接收方准备好PeerConnection
  2. 发送方准备好PeerConnection,并在有流数据获取到的时候发送offer信令
  3. 当接收方收到offer信令,则更新本地会话,并开始在有流数据到达时发送answer信令
  4. 当发送方收到answer信令,更新本地会话
  5. 现在P2P通道已经建立
//准备PeerConnection
pc = new PeerConnection({
  "iceServers": []});

//收到ICE候选时发送ICE候选到其他客户端
pc.onicecandidate = function(event){
   
    socket.send(JSON.stringify({
        "type": "__ice_candidate",
        "candidate": event.candidate
    }));
};

//当收到candidate信令(比如通过websocket)
pc.addIceCandidate(new RTCIceCandidate(data.candidate));

//当流数据到达时,接收方的处理(注意写法,回调函数的写法已经过时了):
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值