WebRTC 之点对点连接——浏览器

2023-11-19

WebRTC 的精髓——点对点连接

上一篇文章中,主要讲了浏览器怎样获取用户设备上的视频流,并且显示在 HTML5 <video> 标签中。这一篇文章则是让这一切变得有用起来:把视频流发送到另一位用户的浏览器上。WebRTC 特有的点对点连接,可以让服务器不必中转大量的视频数据,让通讯的速度、私密性得到更好的保障。这是 WebRTC 相对于 WebSocket 等技术最大的优势,也就是它存在的根本。

怎样建立点对点连接

要建立一个点对点连接,并在其上传送视频内容,我们需要两个浏览器互相交换以下信息:

1.视频流的元数据,包括分辨率和编码格式等
2.各自的网络连接情况,包括用于 NAT 穿透的信息

WebRTC 用于实现了以上信息交换,提供给浏览器 JavaScript 平台的 API 就是 RTCPeerConnection

为了完成以上第 1 种信息的交换,我们用 RTCPeerConnection 的 createOffer() 方法生成一个 Offer,它是以 SDP(Session Description Protocol,会话描述协议)格式传送的。对方收到 Offer 后,应该生成一个 Answer 并发回,这个 Answer 同样是 SDP 格式的。通信的双方通过调用setLocalDescription() 方法,把自己生成的 SDP 设置成本地描述;通过调用setRemoteDescription() 方法,把对方发给自己的 SDP 设置成远程描述。以上的这个过程,被统称为JSEP(JavaScript Session Establishment Protocol,JavaScript 会话建立协议)。


JSEP 结构(via html5rocks.com)

对于以上第 2 种信息的交换,则是通过 ICE(Interactive Connectivity Establishment,交互式连接建立)完成的。对于点对点连接最简单的设想是,大家都连接在一个网络中,只要双方都知道对方的 IP 地址,我就可以直接发送数据。但现实永远不会这么简单:如今的网络世界中,绝大部分设备并不是直接连接到互联网上,具有一个公网 IP 地址,而是处在层层的路由器和防火墙的背后,这也就使得直接建立连接变得不可能。不过,如果双方都向一个公网上的服务器发送一个请求,这台服务器可以获取到双方的公网地址,这样就可以让双方知晓怎样和对方进行通讯。这就是 STUN 服务器。


信令交换与 STUN/TURN 服务器(via html5rocks.com)

当双方完成了 Offer 和 Answer 的交换后,RTCPeerConnection 便利用 STUN 服务器收集 ICE 候选,也就是双方建立连接的多个可能途径,然后在这些候选中挑选最优化的一个,用以建立点对点连接。

STUN 还有一个扩展,即 TURN 服务器。除了实现 STUN 的全部功能外,当双方由于某种原因(如防火墙)还是没法建立点对点连接时,TURN 服务器可以起到中转的作用,让双方可以绕过防火墙进行通讯(事实上绝大多数防火墙被配置为允许从内部向外主动发起的连接)。

实例代码

// 建立一个 RTCPeerConnection 实例,这里设置了 STUN 或 TURN 服务器
var servers = {
  'iceServers': [
    {
      'url': 'stun:turn.mywebrtc.com'
    },
    {
      'url': 'turn:turn.mywebrtc.com',
      'credential': 'siEFid93lsd1nF129C4o',
      'username': 'webrtcuser'
    }
  ]
};
peerConnection = new RTCPeerConnection(servers);

// 交换 ICE 候选,通过 WebSocket 发送
peerConnection.onicecandidate = function (e) {
  if (e.candidate) {
    console.log(['ICE candidate', e.candidate]);
    socket.emit('message', roomToken, {
      'candidate': e.candidate
    });
  }
};

// 接收到对方添加的视频流时,显示在本地的 <video> 标签中
peerConnection.onaddstream = function (e) {
  remoteMediaStream = e.stream;
  remoteVideo.src = URL.createObjectURL(remoteMediaStream);
};

// 在这里添加上一篇文章中获取到的本地视频流
peerConnection.addStream(localMediaStream);

// 包装一个 Offer
peerConnection.createOffer(gotLocalDescription, handleError);

// 有了 Offer,通过 WebSocket 发送给对方
function gotLocalDescription(desc) {
  peerConnection.setLocalDescription(desc);
  socket.emit('message', roomToken, {
    'sdp': desc
  });
}

// 在 WebSocket 中接收到信息时
socket.on('message', function (message, socketId) {
if (message.sdp) {
    // 接收到 Offer 时,创建 Answer 并发送
    var desc = new RTCSessionDescription(message.sdp);
    peerConnection.setRemoteDescription(desc, function () {
      peerConnection.createAnswer(gotLocalDescription, handleError);
    }, handleError);
  } else {
    // 接收到 ICE 候选时,让 RTCPeerConnection 收集它,稍后它将在这些候选方式中挑选最佳者建立连接
    // 注意:RTCPeerConnection 要在 setLocalDescription 后才能开始收集 ICE 候选
    peerConnection.addIceCandidate(new RTCIceCandidate(message.candidate));
  }
});

下期预告

本文简述了点对点连接的建立过程中,双方信息交换的流程。

事实上,在 WebRTC 的技术规范中并没有规定这些信息交换要通过什么途径进行,而是把选择的自由留给留给上层的应用程序。在开发 Web App 时,我们可能最先想到的是 WebSocket,但是也可以采用 SIP 或者 Jingle,或者 XMPP 信息服务比如 OpenFire 之类,等等。在本文中,我们使用了 WebSocket 实现信令交换。

信令服务的任务并不止于连接的建立过程。我们还需要把诸如有人加入聊天、有人挂断这样的信息通知给所有客户端。这些信息既可以用与建立连接时相同的机制进行交换,也可以用 WebRTC RTCDataChannel,这是 WebRTC 的数据传送通道,但这个通道只能在点对点连接建立好以后才能使用,也就是说它不能代替 WebSocket 等,但可以在连接建立后把信令交换的任务接管过来。

WebRTC 之服务器 将会介绍如何使用 node.js 和 socket.io 建立一个 WebSocket 服务器,以提供信令服务;以及如何搭建 STUN/TURN 服务器。


https://hyjk2000.github.io/2015/05/16/webrtc-peer-connection/


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebRTC 之点对点连接——浏览器 的相关文章

  • WebRTC - 禁用所有音频处理

    我目前正在尝试通过 webrtc 获得尽可能干净的音频通道 通过 getUserMedia mediaconstraints 对象 我设置了以下选项 constraints audio mandatory echoCancellation
  • 使用媒体流扩展 (MSE) 显示 getUserMedia Stream 实时视频

    我正在尝试使用 getUserMedia 显示从网络摄像头获取的 MediaStream 并使用任何可能播放的机制将其中继到远程对等点 作为实验 我没有直接使用 webRTC 因为我想控制原始数据 我遇到的问题是我的视频元素不显示任何内容
  • webrtc如何选择输入视频设备?

    我正在研究webRTC应用程序 我参考的是这个软件 apprtc https code google com p webrtc source browse trunk samples js apprtc https code google
  • iOS 11(Beta)中的webKit支持WebRTC吗?

    我有一个 URL 可以在 iOS11 测试版 上的 Safari 上正常工作 音频 视频也可以正常工作 但是 当我使用 WKWebView 加载此 URL 时 它会给我一个错误 不兼容的浏览器 当我在 WebKit 中检查浏览器版本时 它会
  • SignalR WebRTC WebSocket 已处于 CLOSING 或 CLOSED 状态

    我想测试运行 SignalR 和 WebRTC 的最简单实现 我将代码托管在https github com foyzulkarim WebRtc https github com foyzulkarim WebRtc 我制作了两个不同的文
  • 独立移动应用程序上的 WebRTC

    我知道WebRTC是为浏览器设计的 但是可以直接在移动应用程序上使用WebRTC库吗 Thanks 截至5月14日here https github com pchab AndroidRTC是一个android项目 使用WebRTC效果很好
  • 如何运行媒体流

    我创建了一个网络摄像头流 navigator getUserMedia video true function stream videoTag src window URL createObjectURL stream videoTag p
  • Android WebRTC 自定义捕获器

    我已经编译了 webRTC 演示应用程序 我看到捕获帧是由VideoCaptureAndroid java与本机代码紧密耦合的文件 我需要添加将我自己的帧推送到 webRTC 库以在视频通道上发送的功能 我可以用 C NDK 或 Java
  • 有没有办法使用 getUserMedia 减少延迟?

    在尝试减少视频延迟的同时WebRTC通信时 我测量了视频捕获和视频显示之间的延迟 为了防止测量 WebRTC 涉及的延迟 我只是使用getUserMedia和一个 HTMLvideo显示流 我通过每帧显示时间戳来做到这一点 使用reques
  • 如何将音频从浏览器流式传输到 WebRTC 本机 C++ 应用程序

    到目前为止 我已成功运行以下示例 WebRTC 原生 C 到浏览器视频流示例 http sourcey com webrtc native to browser video streaming example 该示例展示了如何将视频从本机
  • 结束两个对等方之间的 WebRTC 视频通话

    我已经使用以下命令在两个同伴之间建立了视频聊天WebRTC 我想让一个对等方结束聊天 并让另一个对等方知道聊天已结束 聊天结束后 需要为双方执行一些代码 这PeerConnection对象有一个removeStream 应该触发的方法onr
  • WebRTC:强制对等点使用 TURN 服务器

    我有一个 webrtc 应用程序 它工作正常 但出于测试目的 我需要测试我的 TURN 服务器是否工作 但因为两个测试设备都在同一网络内 所以我无法测试 认为下面的代码会限制候选人仅那些使用 TURN 服务器的 function onIce
  • 如何在 iOS 和 macOS 上的 Safari 中使用网络摄像头录制视频?

    我已经发布了几条路径 1 录制视频https caniuse com feat html media capture https caniuse com feat html media capture但它仅适用于 iOS 并且无法自定义 我
  • 如何在 Android webRTC 上启用 H264

    如何在 Android WebRTC 上启用 H264 PeerConnection to createOfferSDP中没有h264描述 由于某种原因 Google 默认会阻止他们自己的软件编解码器 因此 如果您的芯片组中没有硬件解码 或
  • MediaStream 未处理的承诺拒绝:[object DOMError](在 Safari 11 中)

    在下面初始化 WebRTC 的方法中 我在 Safari Tech Preview 11 中遇到了未处理的承诺拒绝 具体来说 当我分配MediaStream像这样的视频元素 video srcObject event stream 堆栈跟踪
  • webrtc - 视频出现斑点,但它仍然是黑色的

    我使用 chrome 21 运行我的 webrtc 代码 如果我在同一个 chrome 中打开两个选项卡 然后打开其中包含 webrtc 代码的页面 一个选项卡用于发送视频流 一个选项卡用于接收视频流 效果很好 但是 如果我使用两种隐身模式
  • WebRTC 不适用于 Windows

    每当我尝试为 Windows 构建 WebRTC 时 运行 gclient runhooks 时都会收到此错误 running C path to depot tools python276 bin python exe src build
  • 使用peerjs webrtc共享屏幕+共享系统音频时麦克风不工作

    我们已经尝试过共享屏幕声音的 共享屏幕时 麦克风和屏幕共享音频不能同时工作 麦克风不工作时系统音频已开启 系统音频确实不工作如果末端麦克风打开 请解释一下问题是什么 这是代码 function startScreenShare if scr
  • iOS SWIFT - WebRTC 从前置摄像头更改为后置摄像头

    WebRTC 视频默认使用前置摄像头 效果很好 但是 我需要将其切换到后置摄像头 但我无法找到任何代码来执行此操作 我需要编辑哪一部分 是 localView 或 localVideoTrack 还是捕获器 斯威夫特3 0 对等连接只能有一
  • 有没有办法使用 JSON 对象创建自己的 mediaStreamTrack?

    webRTC 上的 mediaStream 接口允许多个 MediaStreamTrack 这些不一定是来自相机 麦克风的音频和 或视频流 如何使用 JSON 对象创建 MediaStreamTrack 在最近的一次会议上主题 http l

随机推荐

  • gerrit提交出现remote rejected change closed错误

    看了这边文章 原因就像提示信息所说3203已经关闭了 change id找不到了 分析了原因 我的问题是因为之前的一次提交 3203 anandoned掉了 所以找不到这个change id 将这次提交重新恢复后 push成功
  • 区块链技术实战学习路线图

    请大家前往深入浅出区块链主站 获取最新内容 本章的文章越来越多 本文是一个索引帖 方便找到自己感兴趣的文章 你也可以使用左侧的分类 标签及搜索功能 有新文章时会更新本文 建议大家加入收藏夹中 如果你觉得本站不错 欢迎你转发给朋友 引言 给迷
  • 编写简单的linux shell脚本

    1 touch hello sh 2 vi hello sh 键入i 插入 bin sh echo hello world 键入 esc wq 3 chmod 700 hello sh 4 执行 hello sh
  • linux 上生成图片的问题 (awt)

    1 启动xwindow 执行命令 xhost local 2 参考下面资料 原因 Linux无图形支持环境配置 解决 在catalina sh 中加入 Djava awt headless true 或者在 bash profile中增加
  • Redis持久化AOF

    目录 1 AOF简介 2 AOF持久化流程 3 AOF默认不开启 4 AOF和RDB同时开启 redis听谁的 5 AOF启动 修复 恢复 6 AOF同步频率设置 7 Rewrite压缩 7 1 是什么 7 2 重写原理 如何实现重写 8
  • 微信小程序:自动生成打卡海报

    文章目录 1 前言 2 界面展示 3 部分代码展示以及原理解释 4 结语 完整项目下载 下载链接 1 前言 在当前的背单词小程序开发中 为满足用户学习完成后的展示需求 计划引入自动生成打卡海报功能 以提升用户参与度与推广效果 除了基本的海报
  • Window XP驱动开发(十三) 芯片功能驱动端 (代码实现,针对USB2.0 芯片CY7C68013A)

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家提出意见 一起讨论 需要源码的可以与我联系 针对USB2 0 芯片CY7C68013A FPGA实现的高速传输应用来写XP下的USB驱动程序 说
  • 医学图像配准工具Elastix的配置和入门

    一 Elastix介绍 Elastix是一个基于ITK开发的处理医学图像配准问题的工具 Elastix提供了很方便的命令行使用方式以供使用者进行配准应用 同时Elastix是开源的 并且采用模块式构成 可以根据源代码进行开发 或者添加新的模
  • 在LinuxBridge/OVS中使用VxLAN组网以及创建VTEP

    原文来自于 https blog lofyer org E5 9C A8linux bridge ovs E4 B8 AD E4 BD BF E7 94 A8vxlan E7 BB 84 E7 BD 91 E4 BB A5 E5 8F 8A
  • 【满分】【华为OD机试真题2023 JS】箱子之形摆放

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 箱子之形摆放 知识点数组 时间限制 1s 空间限制 128MB 限定语言 不限 题目描述 有一批箱子 形式为字符串 设为str 要求将这批箱子按从上到下以之形的顺序摆放在宽度为n
  • js的事件执行机制(Event loop)

    同步任务 执行主线程上排队执行的任务 只有前一个任务执行完毕 下一个任务才会开始执行 异步任务 不进入主线程 而进入 任务队列 task queue 的任务 只有 任务队列 通知主线程 某个异步任务可以执行了 该任务才会进入主线程执行 事件
  • docker安装nginx太多坑了,果断放弃

    以下是我本人的个人看法 如有不对可在评论区讨论交流 1 listen的端口受限于docker p的参数 一个nginx容器conf文件只能listen同一个端口 2 修改配置文件麻烦 还有docker exec进入到容器内部进行操作 当然
  • 医疗保健软件必备指南

    对许多人来说 软件可能是一种奢侈品 只会给生活在 21 世纪的人们带来一些额外好处 但有时 软件可能是救命稻草 起着生死攸关的作用 根据医疗行业的部分统计数据 我们清醒地发现 美国平均每年约有 25 万至 40 万患者死于本可预防的医疗差错
  • Qt队列的使用

    一 queue 队列 队列是一种先进先出的数据结构 是一个模板类 队列和栈是一种数据逻辑概念 即数据能进行的操作 主要区别是 队列先进先出 First In First Out 栈后进先出 链表和顺序表是一种数据存放方式 主要区别是 链表有
  • 向日葵远程连接Ubuntu出现 “连接中断“ 的解决方法

    向日葵远程连接Ubuntu出现 连接中断 的解决方法 https www cnblogs com wangling1820 p 13448397 html 方法一 参考博客1 https blog csdn net wzf20162016
  • styled-components 的用法

    用于给标签或组件添加样式 给标签或组件添加样式 import styled from styled components styled button 给button标签添加样式 const Button styled button back
  • opencv中归一化函数cv2.normalize()的原理讲解

    本篇文章参考博客 https blog csdn net kuweicai article details 78988886 功能 归一化函数 参数 Python cv2 normalize src dst alpha beta norm
  • 转:在内核里写i2c client 驱动的两种方式

    原文位置 https www cnblogs com simonshi archive 2011 02 24 1963426 html 在内核里写i2c client 驱动的两种方式 前文介 绍了利用 dev i2c 0在应用层完成对i2c
  • 局域网下ROS多机通信的网络连接配置

    1 在路由器设置中固定各机器IP地址 在浏览器中输入路由器的IP地址 例如TP LINK路由器的IP为 192 168 1 1 进入登录页面后 输入用户名和密码登录 用户名一般为admin 密码为自定义 在 基本设置 gt LAN设置 gt
  • WebRTC 之点对点连接——浏览器

    WebRTC 的精髓 点对点连接 上一篇文章中 主要讲了浏览器怎样获取用户设备上的视频流 并且显示在 HTML5