WebRTC实战-第二章-使用WebRTC实现音视频通话

news2024/11/15 17:40:28

目录

  • 参考
  • 理论
    • 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

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

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

相关文章

【经验】Word 2021|如何在Word里做出和Markdown中一样漂亮的引用样式

文章目录写在最前方法以及参数1 打开样式窗口2 设置一些基本操作3 打开格式窗口4 修改样式最后一步!保持间隔成品自取写在最前 Word 版本:2021 灵感来自 知乎奶茶叔的回答,以及我自己平时打代码用的代码块样式。但是我将分享我精心调配的参数…

HTML5期末大作业:HTM+CSS+JS仿安徽开放大学官网(web前端网页制作课作业)

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

[附源码]计算机毕业设计养生药膳推荐系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

Tsinghua:Finding Skill Neurons in Pre-trained Transformer-based Language Models

这篇文章我觉得研究的挺有意思的。 找到神经网络中最有帮助的神经元的一个过程。这个过程的价值是减少PLM参数的前提下,还能提高模型的效果。 在本文中,我们发现在对特定任务进行快速调整后,预训练的 Transformers1 中某些神经元的激活可以高…

Keras计算机视觉(二)

第一部分 认识CNN 一、quickly start 所见即所得,先看一下CNN在MNIST上的运行Demo from keras import layers from keras import modelsmodel models.Sequential() # 定义一个卷积输入层,卷积核是3*3,共32个,输入是(28, 28, 1…

后端开发怎么做得更优秀?记住这15个好习惯

目录 一. 注释尽可能全面,要写有意义的注释 二. 项目拆分合理的目录结构 三. 尽量不在循环里远程调用或者数据库操作,优先考虑批量进行 四. 封装方法形参 五. 封装通用模板 六. 封装复杂的逻辑判断条件 七. 保持优化性能的嗅觉 八. 可变参数的配…

图的初识·遍历

文章目录深度优先搜索[DFS]实现代码广度优先搜索【BFS】思路图解代码实现广度优先遍历【BFS】图的结构深度优先搜索[DFS] 并不唯一,只是一种情况A−>IA->IA−>I 实现代码 使用邻接表表示图。遍历的时间复杂度O(VE)O(VE)O(VE);邻接矩阵的时间…

使用 Python 和 OpenCV 制作反应游戏

在本文中,将向你展示如何使用 OpenCV 在 Python 中制作一个反应游戏,你可以动手来玩。你可能已经熟悉 OpenCV,OpenCV 基本上允许进行各种图像处理。你可以在下面的视频中看到最终结果,并且可以在此处获取文件:https://…

jsp4S店管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 4S店管理系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开 发,数据库为Mysql,使用ja…

海带软件分享——日常办公学习软件下载安装(百度网盘 | 收藏)

>>>深度学习Tricks&#xff0c;第一时间送达<<< &#x1f680; 写在前面 &#x1f431;‍&#x1f3cd; 本期开始&#xff0c;小海带会定期推荐一些日常办公学习软件及趣味网址&#xff08;内含安装教程&#xff09;&#xff0c;供大家学习交流参考 ~ 小伙…

三层交换技术

数据来源 一、三层交换技术出现背景&#xff1a; 解决之前给网段划分VLAN控制端口&#xff0c;然后使用路由器设置单臂路由的让不同VLAN可以通信的缺点&#xff0c; 单臂路由缺点&#xff1a; 1&#xff09;容易出现网络瓶颈 2&#xff09;容易发生单点物理故障 3&a…

[附源码]Python计算机毕业设计Django海南与东北的美食文化差异及做法的研究展示平台

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;我…

设计一个互联网交换设备的SNMP MIB库“X-MIB”

设计一个互联网交换设备的SNMP MIB库“X-MIB”&#xff1a; 问题描述 设备型号&#xff1a;字符串类型 设备生产厂商&#xff1a;字符串类型 设备名称&#xff1a;字符串类型 设备位置&#xff1a;字符串类型 设备运行时间&#xff1a;Timeticks 类型 设备队列数&#xff…

Find My资讯|苹果Find My帮助美警察逮捕连环盗车嫌犯

报道称&#xff0c;美国Shelby County Sheriff警方于11月13日搜查了Shady Ridge的5300街区的一处住宅&#xff0c;成功逮捕了现年20岁的嫌疑人Michael Walker。根据警方通告&#xff0c;该地区近期发生了多起盗车案件。而案件的突破口是发生在Pleasantwood 6800街区的一件盗车事…

【JUC】循环屏障 CyclicBarrier 详解

前言 jdk 中提供了许多的并发工具类&#xff0c;大家可能比较熟悉的有CountDownLatch&#xff0c;主要用来阻塞一个线程运行&#xff0c;直到其他线程运行完毕。而 jdk 还有一个功能类似并发工具类CyclicBarrier&#xff0c;你知道它的作用吗&#xff1f;和CountDownLatch有什…

MySQL学习记录(6)索引02

2.6、索引的使用 2.6.1、最左前缀法则 如果索引了多列&#xff08;联合索引&#xff09;&#xff0c;要遵循最左前缀法则。最左前缀法则指的是查询从索引的最左列开始&#xff0c;并且不跳过索引的列&#xff0c;如果跳跃某一列&#xff0c;索引将会部分失效&#xff08;后面…

大二Web课程设计:HTML+CSS学校静态网页设计——南京师范大学泰州学院(11页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

[附源码]Python计算机毕业设计SSM开心鲜花系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Java外卖小程序管理系统源码带小程序前端+后端搭建教程

这套系统已经完成了线下配送的大部分功能 技术架构 技术框架&#xff1a;springboot ssm mysql redis 运行环境&#xff1a;IntelliJ IDEA 2022 jdk1.8 Mysql5.7.4 maven nginx 宝塔面板 后端搭建教程 1.下载源码后打开小皮面板&#xff0c;安装mysql5.7数据库&#x…

LIO-SAM源码解析(二):代码结构

1. 代码整体框架 首先看看工程目录结构&#xff0c;主要有五个文件&#xff0c;分别是utility.h&#xff0c;featureExtraction.cpp&#xff0c; imageProjection.cpp&#xff0c;imuPreintegration.cpp&#xff0c;mapOptmization.cpp LIO-SAM/config/params.yaml …