Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >WebRTC 入门指南

WebRTC 入门指南

作者头像
ihoey
发布于 2020-07-27 08:15:23
发布于 2020-07-27 08:15:23
1.5K00
代码可运行
举报
文章被收录于专栏:梦魇小栈梦魇小栈
运行总次数:0
代码可运行

WebRTC (Web Real-Time Communications) 是由谷歌开源并推进纳入 W3C 标准的一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。WebRTC 包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建点对点(Peer-to-Peer)的数据分享和电话会议成为可能。

Web 世界经典的 B/S 架构最大的不同是,WebRTC 的通信不经过服务器,而直接与客户端连接,在节省服务器资源的同时,提高通信效率。为了做到这点,一个典型的 WebRTC 通信过程,包含四个步骤:找到对方->进行协商->建立连接->开始通讯。下面将分别阐述这四个步骤。

找到对方

虽然不需要经过服务器进行通信,但是在开始通信之前,必须知道对方的存在,这个时候就需要信令服务器。

信令服务器

所谓信令(signaling)服务器,是一个帮助双方建立连接的「中间人」,WebRTC 并没有规定信令服务器的标准,意味着开发者可以用任何技术来实现,如 WebSocketAJAX

发起 WebRTC 通信的两端被称为对等端(Peer),成功建立的连接被称为 PeerConnection,一次 WebRTC 通信可包含多个 PeerConnection

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const pc2 = new RTCPeerConnection([configuration]);

在寻找对等端阶段,信令服务器的工作一般是标识与验证参与者的身份,浏览器连接信令服务器并发送会话必须的信息,如房间号、账号信息等,由信令服务器找到可以通信的对等端并开始尝试通信。

其实在整个 WebRTC 通信过程中,信令服务器都是一个非常重要的角色,除了上述作用,SDP 交换、ICE 连接等都离不开信令,后文将会提到。

进行协商

协商过程主要指 SDP 协议交换。

SDP

SDP(Session Description Protocol)指会话描述协议,是一种通用的协议,使用范围不仅限于 WebRTC。主要用来描述多媒体会话,用途包括会话声明、会话邀请、会话初始化等。

WebRTC 中,SDP 协议主要用来描述:

  • 设备支持的媒体能力,包括编解码器等
  • ICE 候选地址
  • 流媒体传输协议

SDP 协议基于文本,格式非常简单,它由多个行组成,每一行都为以下格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type=value;

其中,type 表示属性名,value 表示属性值,具体格式与 type 有关。下面是一份典型的 SDP 协议样例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
v=0
o=alice 2890844526 2890844526 IN IP4 host.anywhere.com
s=
c=IN IP4 host.anywhere.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
m=video 51372 RTP/AVP 31
a=rtpmap:31 H261/90000
m=video 53000 RTP/AVP 32
a=rtpmap:32 MPV/90000

其中:

属性名

属性说明

v

代表协议版本号

o

代表会话发起者,包括 username、sessionId 等

s

代表 session 名称,为唯一字段

c

代表连接信息,包括网络类型、地址类型、地址等

c

代表会话时间,包括开始/结束时间,均为 0 表示持久会话

m

代表媒体描述,包括媒体类型、端口、传输协议、媒体格式等

a

代表附加属性,此处用于对媒体协议进行扩展

Plan B VS Unified Plan

WebRTC 发展过程中,SDP 格式 (semantics) 也发生了多次改变,目前使用最多的是 Plan BUnified Plan 两种。两者均可在一个 PeerConnection 中表示多路媒体流,区别在于:

  • Plan B: 所有视频流和所有音频流各自放在一个 m=值 里,用 ssrc 区分
  • Unified Plan: 每路流各自用一个 m=值

目前最新发布的 WebRTC 1.0 采用的是 Unified Plan,已被主流浏览器支持并默认开启。Chrome 浏览器支持通过以下 API 获取当前使用的 semantics:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Chrome
RTCPeerConnection.getConfiguration().sdpSemantics; // 'unified-plan' or 'plan b'

协商过程

协商过程并不复杂,如下图所示:

会话发起者通过 createOffer 创建一个 offer,经过信令服务器发送到接收方,接收方调用 createAnswer 创建 answer 并返回给发送方,完成交换。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 发送方,sendOffer/onReveiveAnswer 为伪方法
const pc1 = new RTCPeerConnection();
const offer = await pc1.createOffer();

pc1.setLocalDescription(offer);

sendOffer(offer);

onReveiveAnswer((answer) => {
  pc1.setRemoteDescription(answer);
});

// 接收方,sendAnswer/onReveiveOffer 为伪方法
const pc2 = new RTCPeerConnection();

onReveiveOffer((offer) => {
  pc2.setRemoteDescription(answer);
  const answer = await pc2.createAnswer();
  pc2.setLocalDescription(answer);
  sendAnswer(answer);
});

需要注意的是,随着通信过程中双方相关信息的变化,SDP 交换可能会进行多次。

建立连接

现代互联网环境非常复杂,我们的设备通常隐藏在层层网关后面,因此,要建立直接的连接,还需要知道双方可用的连接地址,这个过程被称为 NAT 穿越,主要由 ICE 服务器完成,所以也称为 ICE 打洞。

ICE

ICE(Interactive Connectivity Establishment) 服务器是独立于通信双方外的第三方服务器,其主要作用,是获取设备的可用地址,供对等端进行连接,由 STUN(Session Traversal Utilities for NAT) 服务器来完成。每一个可用地址,都被称为一个 ICE 候选项 (ICE Candidate),浏览器将从候选项中选出最合适的使用。其中,候选项的类型及优先级如下:

  • 主机候选项: 通过设备网卡获取,通常是内网地址,优先级最高
  • 反射地址候选项: 由 ICE 服务器获取,属于设备在外网的地址,获取过程比较复杂,可以简单理解为:浏览器向服务器发送多个检测请求,根据服务器的返回情况,来综合判断并获知自身在公网中的地址
  • 中继候选项: 由 ICE 中继服务器提供,前两者都行不通之后的兜底选择,优先级最低

新建 PeerConnection 时可指定 ICE 服务器地址,每次 WebRTC 找到一个可用的候选项,都会触发一次 icecandidate 事件,此时可调用 addIceCandidate 方法来将候选项添加到通信中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const pc = new RTCPeerConnection({
  iceServers: [
    { url: "stun:stun.l.google.com:19302" },
    { url: "turn:user@turnserver.com", credential: "pass" },
  ], // 配置 ICE 服务器
});
pc.addEventListener("icecandidate", (e) => {
  pc.addIceCandidate(event.candidate);
});

通过候选项建立的 ICE 连接,可以大致分为下图两种情况:

  1. 直接 P2P 的连接,为上述 1&2 两种候选项的情况;
  2. 通过 TURN(Traversal Using Relays around NAT)中继服务器的连接,为上述第三种情况。

同样的,由于网络变动等原因,通信过程中的 ICE 打洞,同样可能发生多次。

进行通信

WebRTC 选择了 UDP 作为底层传输协议。为什么不选择可靠性更强的 TCP?原因主要有三个:

  • UDP 协议无连接,资源消耗小,速度快
  • 传输过程中少量的数据损失影响不大
  • TCP 协议的超时重连机制会造成非常明显的延迟

而在 UDP 之上,WebRTC 使用了再封装的 RTPRTCP 两个协议:

  • RTP(Realtime Transport Protocol): 实时传输协议,主要用来传输对实时性要求比较高的数据,比如音视频数据
  • RTCP(RTP Trasport Control Protocol): RTP 传输控制协议,顾名思义,主要用来监控数据传输的质量,并给予数据发送方反馈。

在实际通信过程中,两种协议的数据收发会同时进行。

关键 API

下面将以一个 demo 及其代码,来展示前端 WebRTC 的能力及其使用的 API:

Start Call

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

       const startButton = document.getElementById("startButton");     const callButton = document.getElementById("callButton");     const localVideo = document.getElementById("localVideo");     const remoteVideo = document.getElementById("remoteVideo");     callButton.disabled = true;     startButton.addEventListener("click", start);     callButton.addEventListener("click", call);     let localStream;     let pc1;     let pc2;     const offerOptions = {       offerToReceiveAudio: 1,       offerToReceiveVideo: 1     };     async function start() {       startButton.disabled = true;       const stream = await navigator.mediaDevices.getUserMedia({         audio: true,         video: true       });       localVideo.srcObject = stream;       localStream = stream;       callButton.disabled = false;     }     function gotRemoteStream(e) {       if (remoteVideo.srcObject !== e.streams[0]) {         remoteVideo.srcObject = e.streams[0];         console.log("pc2 received remote stream");         setTimeout(() => {           pc1.getStats(null).then(stats => console.log(stats));         }, 2000);       }     }     function getName(pc) {       return pc === pc1 ? "pc1" : "pc2";     }     function getOtherPc(pc) {       return pc === pc1 ? pc2 : pc1;     }     async function call() {       pc1 = new RTCPeerConnection();       //  {       //   sdpSemantics: "unified-plan", // 指定使用 unified plan       //   iceServers:       //   [       //      { url: "stun:stun.l.google.com:19302" },       //      { url: "turn:user@turnserver.com", credential: "pass" }       //   ] // 配置 ICE 服务器       // }       pc1.addEventListener("icecandidate", e => onIceCandidate(pc1, e)); // 监听 ice 候选项事件       pc2 = new RTCPeerConnection();       pc2.addEventListener("icecandidate", e => onIceCandidate(pc2, e));       pc2.addEventListener("track", gotRemoteStream);       localStream.getTracks().forEach(track => pc1.addTrack(track, localStream));       const offer = await pc1.createOffer(offerOptions); // 创建 offer       await onCreateOfferSuccess(offer);       callButton.disabled = true;     }     async function onCreateOfferSuccess(desc) {       await pc1.setLocalDescription(desc);       await pc2.setRemoteDescription(desc);       const answer = await pc2.createAnswer(); // 创建 answer       await onCreateAnswerSuccess(answer);     }     async function onCreateAnswerSuccess(desc) {       await pc2.setLocalDescription(desc);       await pc1.setRemoteDescription(desc);     }     async function onIceCandidate(pc, event) {       try {         await getOtherPc(pc).addIceCandidate(event.candidate); // 设置 ice 候选项         onAddIceCandidateSuccess(pc);       } catch (e) {         onAddIceCandidateError(pc, e);       }       console.log(         `${getName(pc)} ICE candidate:\n${           event.candidate ? event.candidate.candidate : "(null)"         }`       );     }     function onAddIceCandidateSuccess(pc) {       console.log(`${getName(pc)} addIceCandidate success`);     }     function onAddIceCandidateError(pc, error) {       console.log(         `${getName(pc)} failed to add ICE Candidate: ${error.toString()}`       );     }    

写在最后

作为「指南」,本文从比较浅的层次介绍了 WebRTC 技术,很多细节及原理性的内容,限于篇幅未作深入阐述。笔者也是刚接触几个月,如有谬误,还请告知。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-07-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
解码陪玩系统连麦技术:从音频传输到实时交互
陪玩公众号 陪玩小程序陪玩app 陪玩平台源码 陪玩平台搭建 游戏陪玩源码 线上游戏陪玩源码 线上游戏平台搭建线上游戏代练系统 下线付费搭子源码 线下家政平台 线下家政源码线下预约服务源码 陪玩陪聊系统源码 陪玩平台搭建 游戏陪玩系统,线上游戏开黑陪玩
菜鸟指南
2025/04/24
640
解码陪玩系统连麦技术:从音频传输到实时交互
WebRTC实现p2p视频通话
简介 目的 帮助自己了解webrtc 实现端对端通信 # 使用流程 git clone https://gitee.com/wjj0720/webrtc.git cd ./webRTC npm i npm run dev # 访问 127.0.0.1:3003/test-1.html 演示h5媒体流捕获 # 访问 127.0.0.1:3003/local.html 演示rtc 本地传输 # 访问 127.0.0.1:3003/p2p.html 演示局域网端对端视屏
random_wang
2019/10/22
6.8K0
WebRTC实现p2p视频通话
【WebRTC】WebRTC学习总结
WebRTC 是一项「实时通讯技术」,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。WebRTC包含的这些标准使用户在无需安装任何插件或者第三方的软件的情况下,创建点对点(Peer-to-Peer)的数据分享和电话会议成为可能。本篇文章从自身实践出发,结合相关代码,总结WebRTC实现的基本流程。
pingan8787
2020/05/14
3.8K0
【WebRTC】WebRTC学习总结
WebRTC:一个视频聊天的简单例子
在前面的章节中,已经对WebRTC相关的重要知识点进行了介绍,包括涉及的网络协议、会话描述协议、如何进行网络穿透等,剩下的就是WebRTC的API了。
猿哥
2019/08/06
3K0
【从头到脚】前端实现多人视频聊天— WebRTC 实战(多人篇)
这是 WebRTC 系列的第三篇文章,主要讲多人点对点连接。如果你对 WebRTC 还不太了解,推荐阅读我之前的文章。
陈大鱼头
2020/04/16
5.9K0
【从头到脚】前端实现多人视频聊天— WebRTC 实战(多人篇)
WebRTC学习笔记——建立连接
1.WebRTC简介 WebRTC是一个开源的项目,可以提供浏览器,手机应用之间实时通信能力。 同时,这一功能已经内置于现代浏览器中,所以它可以做到无须借助第三方软件或插件便可以在开发网络中传输高质量
IMWeb前端团队
2017/12/29
2.1K0
WebRTC学习笔记——建立连接
零基础入门:基于开源WebRTC,从0到1实现实时音视频聊天功能
本文由微医云技术团队前端工程师张宇航分享,原题“从0到1打造一个 WebRTC 应用”,有修订和改动。
JackJiang
2021/08/24
3.8K0
WebRTC中的信令和内网穿透技术 STUN / TURN
Translated from WebRTC in the real world: STUN, TURN and signaling. 最近刚接触到WebRTC,网上看到这篇介绍WebRTC的文章不错,仔细读了读还算有用,分享出来能帮到一些刚入门的人也挺好的,翻译不好的地方可以直接看原文。
全栈程序员站长
2022/09/13
6K0
WebRTC中的信令和内网穿透技术 STUN / TURN
通过WebRTC进行实时通信-通过RTCPeerConnection传输视频
RTCPeerConnection 是调用WebRTC传输音视频和交换数据的API。这个例子是在同一个页面中两个RTCPeerConnection对象之间建立连接。没有什么实际价值,但却能很好的证明RTCPeerConnection是如何工作的。
音视频_李超
2020/04/02
5.6K0
【教程】如何使用Javascript构建WebRTC视频直播?
WebRTC是一个免费的开源项目,它通过简单的API为浏览器和移动应用程序提供实时通信功能。本文将向你展示WebRTC的基本概念和功能,并指导你使用Node.js构建自己的WebRTC视频直播。
TSINGSEE青犀视频
2021/04/12
4.4K0
创建 WebRTC 会话
一WebRTC 是一套基于 Web 的实时通信解决方案,通过浏览器内置的 API 来支持音视频通道的搭建。
派大星在吗
2021/12/05
5.6K0
音视频通信加餐 —— WebRTC一肝到底
最近需要搭建一个在线课堂的直播平台,考虑到清晰度和延迟性,我们一致认为使用 WebRTC 最合适。
杨成功
2022/09/22
1.1K0
音视频通信加餐 —— WebRTC一肝到底
实践:《从头到脚撸一个多人视频聊天 — 前端 WebRTC 实战)》
请先阅读原文,链接:从头到脚撸一个多人视频聊天 — 前端 WebRTC 实战(一),本文只涉及实践过程中的问题
申君健
2019/03/21
1.6K0
【项目实战】基于 WebRTC 的音视频在线监考模块的设计与实现(下)
在上一篇博文 【复】基于 WebRTC 的音视频在线监考模块的设计与实现(上) 中,主要介绍了关于 WebRTC 的基本理论,那么这篇文章我们将进入实战阶段,通过 WebRTC 框架,去实现 P2P 通话,以及延伸到一对多的音视频通话,从而实现在线监考功能;
sidiot
2023/08/31
4710
【项目实战】基于 WebRTC 的音视频在线监考模块的设计与实现(下)
WebRTC 速成课程
WebRTC (Web Real-Time Communication)是一个免费、开源的项目,通过简单的应用程序编程接口(API)为 Web 浏览器和移动应用程序提供实时通信(RTC)。这也表明了 WebRTC 设计的目标就是“设计一种通过尽量短的、延迟尽量低的路径进行 P2P 通信的协议,提供一种简单的、能让所有人使用的 API”。一旦你把它放入浏览器,它就是标准;一旦它成为了标准,开发时会遇到的“摩擦”就会消失。
用户1324186
2022/02/18
1.4K0
WebRTC 速成课程
Web前端WebRTC攻略(一) 基础介绍
随着互联网高速发展,以及即将到来的5G时代,WebRTC作为前端互动直播和实时音视频的利器,也是将前端开发者们不可错过的学习领域。如果你现在只是听过而已,那你可能要好好学习一番。 01  什么是WebRTC? WebRTC 全称是(Web browsers with Real-Time Communications (RTC) 大概2011年,谷歌收购了 GIPS,它是一个为 RTC 开发出许多组件的公司,例如编解码和回声消除技术。Google 开源了 GIPS 开发的技术,并希望将其打造为行业标准。 收
用户1097444
2022/06/29
2.6K0
Web前端WebRTC攻略(一) 基础介绍
前端音视频WebRTC实时通讯的核心
通过上两个系列专栏的学习,我们对前端音视频及 WebRTC 有了初步的了解,是时候敲代码实现一个 Demo 来真实感受下 WebRTC 实时通讯的魅力了。还没有看过的同学请移步:
童欧巴
2020/11/02
2.7K0
前端音视频WebRTC实时通讯的核心
实时音视频入门学习:开源工程WebRTC的技术原理和使用浅析
本文由ELab技术团队分享,原题“浅谈WebRTC技术原理与应用”,有修订和改动。
JackJiang
2022/01/10
1.8K0
实时音视频入门学习:开源工程WebRTC的技术原理和使用浅析
WebRTC介绍及简单应用
WebRTC介绍及简单应用 WebRTC,即Web Real-Time Communication,web实时通信技术。简单地说就是在web浏览器里面引入实时通信,包括音视频通话等。 WebRTC
用户1141560
2017/12/25
6.2K0
html5使用webrtc例子
以上是 html5 使用 webrtc 的核心代码,其实代码并不复杂,可以运行示例例观察调用流程;但是自己需要实现一个信令服务器。
用户10777220
2024/01/17
2730
推荐阅读
相关推荐
解码陪玩系统连麦技术:从音频传输到实时交互
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验