一文学会使用WebRTC API

WebRTC(Web Real-Time Communication)是一项开放标准和技术集合,由 W3CIETF 等组织共同推动和维护,旨在通过Web浏览器实现实时通信媒体流传输。WebRTC于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准,其提供了一组API和协议,使开发者能够在浏览器中构建实时音视频通信、数据传输和协作应用。目前WebRTC已得到包括主流的Web浏览器(如Chrome、Firefox、Safari)和移动设备平台的广泛的支持和应用。

  • WebRTC API 简介
  • WebRTC SDP状态机
  • WebRTC API 使用——媒体流传输
  • WebRTC API 使用——DataChannel

一、API 简介

WebRTC(Web Real-Time Communication)提供了一组丰富的 API 方法,用于在浏览器中实现实时通信。这些 API 方法涵盖了音视频捕获、连接建立、媒体流传输和数据传输等方面。下面是对 WebRTC 中一些核心 API 方法的详细介绍,并提供了相应的使用示例:

WebRTC API 使用

  • 呼叫端通过 navigator.mediaDevices.getUserMedia()捕捉本地媒体;
  • 呼叫端创建一个RTCPeerConnection 并调用 RTCPeerConnection.addTrack()
  • 呼叫端调用 RTCPeerConnection.createOffer()来创建一个提议 (offer);
  • 呼叫端调用 RTCPeerConnection.setLocalDescription()将提议 (Offer) 设置为本地描述 (即,连接的本地描述);
  • 呼叫端请求 STUN 服务创建 ice 候选 (ice candidates);
  • 呼叫端通过信令服务器(如 websocket)将提议 (offer) 传递至接收端
  • 接收端收到了提议 (offer) 并调用 RTCPeerConnection.setRemoteDescription() 将其记录为远程描述 (也就是连接的另一端的描述);
  • 接收端捕获本地媒体,通过RTCPeerConnection.addTrack()添加到连接中;
  • 接收端通过 RTCPeerConnection.createAnswer() 创建一个应答;
  • 接收端调用 RTCPeerConnection.setLocalDescription() 将应答 (answer) 设置为本地描述。此时,接收端已经获知连接双方的配置了。
  • 接收端通过信令服务器(如 websocket)将应答传递到呼叫端
  • 呼叫端接受到应答。
  • 呼叫端调用 RTCPeerConnection.setRemoteDescription()将应答设定为远程描述。如此,呼叫端已经获知连接双方的配置了。

二、会话描述状态机

JSEP是一种用于在WebRTC应用程序中建立和管理通信会话的机制,其由RFC8829 JSEP:规范,定义了JavaScript API和信令交换的规范,以便在浏览器之间建立点对点的实时通信。

通过JSEP规范,我们可以了解到WebRTC SDP 会话描述状态机:

RFC8829 JSEP 状态机

  • 呼叫端通过调用 createOffer API 来创建提议 (offer);
  • 呼叫端使用这个 offer 通过 setLocalDescription API 来设置其本地配置;
  • 呼叫端通过信令服务器(如 websocket)将提议 (offer) 传递至接收端

为了完成 offer/answer 交换:

  • 接收端收到了提议 (offer) 并调用 setRemoteDescription() 将其记录为远程描述;
  • 接收端使用 createAnswer API 生成应答 (answer) ,使用 setLocalDescription API 来应用answer;
  • 接收端通过信令服务器(如 websocket)将应答传递到呼叫端

呼叫端接受到应答:

  • 呼叫端调用 RTCPeerConnection.setRemoteDescription()将应答设定为远程描述,完成初始化。

三、WebRTC API 使用——媒体流传输

  1. navigator.mediaDevices.getUserMedia(constraints)

    • 描述:请求访问音视频设备并获取本地媒体。
    • 示例:
navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(function(stream) {// 处理获取到的媒体流}).catch(function(error) {// 处理错误});
  1. RTCPeerConnection(configuration)

    • 描述:创建一个 PeerConnection 对象,用于建立和管理点对点连接。
    • 示例:
var configuration = { iceServers: [{ urls: '192.168.1.1:19302' }] };
var peerConnection = new RTCPeerConnection(configuration);
  1. peerConnection.addTrack(track, stream)

    • 描述:将音视频轨道添加到 PeerConnection 中。
    • 示例:
var localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
localStream.getTracks().forEach(function(track) {peerConnection.addTrack(track, localStream);
});
  1. peerConnection.createOffer(options)

    • 描述:创建一个SDP提议 (offer),用于发起连接。
    • 示例:
peerConnection.createOffer().then(function(offer) {return peerConnection.setLocalDescription(offer);}).then(function() {// 将 SDP offer 发送给远程端}).catch(function(error) {// 处理错误});
  1. peerConnection.setLocalDescription(description)

    • 描述:将本地描述设置为提供的 SDP(Session Description Protocol)对象。
    • 示例:
var localDescription = // 从信令服务器获取的本地描述信息
peerConnection.setLocalDescription(localDescription)
  1. peerConnection.setRemoteDescription(description)

    • 描述:将远程描述设置为提供的 SDP 对象。
    • 示例:
var remoteDescription = // 从信令服务器获取的远程描述信息
peerConnection.setRemoteDescription(remoteDescription)
  1. peerConnection.addIceCandidate(candidate)

    • 描述:将 ICE(Interactive Connectivity Establishment)候选项添加到 PeerConnection 中。
    • 示例:
var iceCandidate = // 从信令服务器获取的 ICE 候选项
peerConnection.addIceCandidate(iceCandidate)
  1. peerConnection.ontrack

    • 描述:当远程端添加媒体轨道时触发的事件处理函数。
    • 示例:
peerConnection.ontrack = function(event) {var remoteVideo = document.getElementById('remoteVideo');remoteVideo.srcObject = event.streams[0];
};
  1. peerConnection.onicecandidate

    • 描述:当 ICE 候选项可用时触发的事件处理函数。
    • 示例:
peerConnection.onicecandidate = function(event) {if (event.candidate) {// 将 ICE 候选项发送给远程端}
};
  1. peerConnection.onconnectionstatechange

    • 描述:当 PeerConnection 的连接状态发生变化时触发的事件处理函数。
    • 示例:
peerConnection.onconnectionstatechange = function(event) {if (peerConnection.connectionState === 'connected') {// 连接已建立} else if (peerConnection.connectionState === 'disconnected') {// 连接已断开} else if (peerConnection.connectionState === 'failed') {// 连接失败}
};

四、DataChannel

要在两个 WebRTC 端点之间直接传输非媒体流信息,需要使用 DataChannel API。DataChannel 允许在两个对等连接之间传输任意类型的数据,包括文本、图片等数据内容。
下面是一个使用 WebRTC DataChannel 在两个端点之间发送文字内容的详细代码实现:

  1. 发送端代码(例如浏览器 A):
// 创建 PeerConnection
var peerConnection = new RTCPeerConnection();
// 创建 DataChannel
var dataChannel = peerConnection.createDataChannel('textChannel');
// 事件处理:当 DataChannel 开启时
dataChannel.onopen = function() {// 发送文字内容dataChannel.send('Hello, WebRTC DataChannel!');
};// 事件处理:当 DataChannel 收到消息时
dataChannel.onmessage = function(event) {var receivedMessage = event.data;console.log('Received message:', receivedMessage);
};// 创建 SDP offer
peerConnection.createOffer().then(function(offer) {return peerConnection.setLocalDescription(offer);}).then(function() {// 将 SDP offer 发送给远程端var offer = peerConnection.localDescription;// 发送 offer 给远程端,例如通过信令服务器}).catch(function(error) {console.error('Error creating offer:', error);});
  1. 接收端代码(例如浏览器 B):
// 创建 PeerConnection
var peerConnection = new RTCPeerConnection();// 事件处理:当收到来自远程端的 SDP offer 时
function handleOffer(offer) {// 设置远程描述为 SDP offerpeerConnection.setRemoteDescription(offer).then(function() {// 创建 SDP answerreturn peerConnection.createAnswer();}).then(function(answer) {return peerConnection.setLocalDescription(answer);}).then(function() {// 将 SDP answer 发送给远程端var answer = peerConnection.localDescription;// 发送 answer 给远程端,例如通过信令服务器}).catch(function(error) {console.error('Error creating or setting local description:', error);});
}// 事件处理:当 PeerConnection 收到来自远程端的 DataChannel 时
peerConnection.ondatachannel = function(event) {var receivedDataChannel = event.channel;// 事件处理:当 DataChannel 开启时receivedDataChannel.onopen = function() {// 发送文字内容receivedDataChannel.send('Hi, WebRTC DataChannel!');};// 事件处理:当 DataChannel 收到消息时receivedDataChannel.onmessage = function(event) {var receivedMessage = event.data;console.log('Received message:', receivedMessage);};
};// 事件处理:当收到来自信令服务器的 SDP offer 时
var receivedOffer = // 从信令服务器获取的 SDP offer
handleOffer(receivedOffer);

在上述代码中,发送端创建了一个 DataChannel,并在 DataChannel 开启后发送文字内容。
接收端在 PeerConnection 上监听 “ondatachannel” 事件,当收到来自远程端的 DataChannel 时,设置相应的事件处理函数,并在 DataChannel 开启后发送文字内容。

参考:

W3C WebRTC API:
https://www.w3.org/TR/webrtc/

RFC8829 JSEP:
https://datatracker.ietf.org/doc/html/rfc8829

WebRTC API:
https://developer.mozilla.org/zh-CN/docs/Web/API/WebRTC_API

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/110342.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVS-rules中的基础与复合变量:规则引擎的心脏

JVS-rules中的“变量”概念与编程语言中的变量类似,但它们通常在规则系统中处理条件判断、业务结果复制场景,如下所示: 条件判断:在规则引擎中,规则通常由两个部分组成:条件和分支。变量用于描述条件部分中…

Arduino驱动ICG-20660L传感器(惯性测量传感器篇)

目录 1、传感器特性 2、硬件原理图 3、控制器和传感器连线图 4、驱动程序

职场题:有一件特别紧急的事,群众要办理,且联系不上领导,你怎么办?(2)

接1所写 如果无法联系上领导且有一项特别紧急的事情需要办理,以下是进一步的建议: 11. 尝试其他沟通渠道:除了直接联系领导外,尝试通过其他沟通渠道与领导取得联系。这可能包括电子邮件、即时通讯工具或其他内部通信平台。确保详…

逐字稿 | 2 MoCo 论文逐段精读【论文精读】

bryanyzhu的个人空间-bryanyzhu个人主页-哔哩哔哩视频 评价 今天我们一起来读一下 MOCO 这篇论文。 MOCO 是 CVPR 2020 的最佳论文提名,算是视觉领域里使用对比学习的一个里程碑式的工作。而对比学习作为从 19 年开始一直到现在视觉领域乃至整个机器学习领域里最炙…

深度学习零基础教程

代码运行软件安装: anaconda:一个管理环境的软件–>https://blog.csdn.net/scorn_/article/details/106591160(可选装) pycharm:一个深度学习运行环境–>https://blog.csdn.net/scorn_/article/details/106591160&#xf…

PAM从入门到精通(七)

接前一篇文章:PAM从入门到精通(六) 本文参考: 《The Linux-PAM Application Developers Guide》 先再来重温一下PAM系统架构: 更加形象的形式: 五、主要函数详解 5. pam_strerror 概述: 描述…

在vue使用class选择器和下标更改点击列表样式

如果您正在使用Vue 3的<script setup>语法&#xff0c;可以按照以下步骤在Vue中使用class和下标来更改点击项的样式&#xff1a; 首先&#xff0c;在<script setup>部分导入所需的响应式API和定义需要使用的变量。 <script setup> import { ref } from vue…

千兆光模块和万兆光模块的区别?

在网络通信领域&#xff0c;千兆光模块和万兆光模块是最为常见且广泛应用的两种光模块。不同之处在于传输速率、封装、传输距离、功耗、发射光功率、接收光功率和应用场景等。 千兆光模块的传输速率为1 Gbps&#xff0c;万兆光模块的传输速率为10 Gbps&#xff0c;这意味着万…

vue-cli脚手架创建项目时报错Error: command failed: npm install --loglevel error

项目背景 环境&#xff1a;vue-cli 5.x 在工程文件中&#xff0c;后端模块wms已经创建完成&#xff0c;现在想新建一个名为vue-web的前端模块 执行命令vue create vue-web时&#xff0c; 报错Error: command failed: npm install --loglevel error 问题分析及解决 排查过程…

ScyllaDB获4300万美元融资,NoSQL数据库市场再掀热潮!

ScyllaDB是一家成立于2012年12月的美国公司&#xff0c;总部位于加利福尼亚州桑尼维尔。作为一家数据密集型应用程序数据库供应商&#xff0c;ScyllaDB生产的NoSQL数据库兼容Apache Cassandra和Amazon DynamoDB&#xff0c;具有可靠的低延迟和10倍的吞吐量。在2023年10月17日&a…

代码随想录算法训练营第五十八天| LeetCode 583 两个字符串的删除操作、LeetCode 72 编辑距离、编辑距离总结

1 LeetCode 583 两个字符串的删除操作 题目链接&#xff1a;LeetCode 583 两个字符串的删除操作 文章讲解&#xff1a;代码随想录(programmercarl.com) 视频讲解&#xff1a;LeetCode&#xff1a;583.两个字符串的删除操作 2 LeetCode 72 编辑距离 题目链接&#xff1a;LeetCod…

JVM第十三讲:调试排错 - JVM 调优参数

调试排错 - JVM 调优参数 本文是JVM第十三讲&#xff0c;调试排错 - JVM 调优参数。对JVM涉及的常见的调优参数和垃圾回收参数进行阐述。 文章目录 调试排错 - JVM 调优参数1、Jvm参数2、垃圾回收 问题1&#xff1a;线上ECS治理问题2&#xff1a;白龙马线上服务机JVM参数配置&a…

Qt move和setGeometry的区别

move 和 setGeometry 都是用于管理窗口或小部件的位置的方法&#xff0c;通常在使用 Qt 编程时会用到。它们之间的主要区别在于&#xff1a; move 方法&#xff1a;这个方法用于设置小部件的左上角的坐标位置&#xff0c;它需要两个参数&#xff0c;即横坐标和纵坐标。使用 mov…

idea dubge 详细

目录 一、概述 二、debug操作分析 1、打断点 2、运行debug模式 3、重新执行debug 4、让程序执行到下一次断点后暂停 5、让断点处的代码再加一行代码 6、停止debug程序 7、显示所有断点 8、添加断点运行的条件 9、屏蔽所有断点 10、把光标移到当前程序运行位置 11、单步跳过 12、…

访问 github 问题解决方法

一、macOS版 PS. Windows 版的还没试&#xff0c;不过应该也差不多 1.基本信息 硬件&#xff1a;MacBook Pro 2017 (A1707) 系统&#xff1a;macOS 13.6 (Ventura) 应用&#xff1a;SwitchHosts 4.1.2 (Releases oldj/SwitchHosts GitHub) hosts内容网站&#xff1a;ht…

迅为RK3588开发板Android12单摄方案设备树修改

打开 3588-android12/kernel-5.10/arch/arm64/boot/dts/rockchip/topeet_camera_config.dtsi 设备树&#xff0c;此设备树中对底板上的摄像头接口进行了配置&#xff0c;如下图所示&#xff1a; 如果想要使用 J1 接口打开摄像头 OV5695 或者 摄像头 OV13850&#xff0c;只需要在…

pytorch代码实现之动态蛇形卷积模块DySnakeConv

动态蛇形卷积模块DySnakeConv 血管、道路等拓扑管状结构的精确分割在各个领域都至关重要&#xff0c;确保下游任务的准确性和效率。 然而&#xff0c;许多因素使任务变得复杂&#xff0c;包括薄的局部结构和可变的全局形态。在这项工作中&#xff0c;我们注意到管状结构的特殊…

vue中动态设置source标签

项目中有个视频播放,路径通过接口返回,而且不带后缀,并不确定是什么类型的视频文件,所以要通过source标签去进行设置. 问题:当video中存在source标签的时候&#xff0c;浏览器渲染之后会自动去获取地址&#xff0c;即便地址改变&#xff0c;浏览器也不会再去获取地址。 解决方…

3、Flowable任务分配和流程变量

任务分配和流程变量 1.任务分配 1.1 固定分配 固定分配就是我们前面介绍的&#xff0c;在绘制流程图或者直接在流程文件中通过Assignee来指定的方式 1.2 表达式分配 Flowable使用UEL进行表达式解析。UEL代表Unified Expression Language&#xff0c;是EE6规范的一部分.Flo…

无蓝光的护眼灯有哪些品牌?分享五款优秀的无蓝光护眼台灯

现在儿童近视率越来越高了&#xff0c;用眼过度疲劳是导致近视的主要因素&#xff0c;学习环境的光线是否合适&#xff0c;都会直接影响用眼的疲劳程度。所以给孩子营造一个良好的学习环境非常重要&#xff01;为大家推荐五大品牌的护眼台灯。 1.书客护眼台灯L1 推荐指数&…