当前位置: 首页 > news >正文

如何使用 WebRTC 与 Kurento 建立视频会议 App

本文作者 WebRTC Ventures 工程师。在 RTC 2018 实时互联网大会上,WebRTC Ventures 的资深软件工程师,将围绕 WebRTC 开发带来经验分享。欢迎访问RTC 开发者社区,与更多WebRTC开发者交流经验。

了解 WebRTC 如何工作的一种简单方式是通过学习如何使用 WebRTC 和 Kurento 媒体服务器建立视频会议 App。尽管 WebRTC 初衷是建立peer-to-peer的连接,而媒体服务器对于添加诸如录制、多方通话等功能是非常有用的。我们将会使用 Kurento,这个开源媒体服务器,来为我们 App 在多于两个用户的情况下提供连接支持。接下来,让我们来回顾整体的过程,我们将通过 WebRTC 建立连接的过程分为三步:
 

1. 浏览器获取媒体设备(摄像头和麦克风)
2. 每一个 peer 通过发信过程与其它所有 peer 交换信息。
3. 交换信息过后,peers 可以通过媒体服务器连接,并开始通信。

注意,对于交换消息我们依然需要一个信令服务器,对于 NAT 穿透我们需要 STUN 或 TURN 服务器。另外,我们添加了一个媒体服务器用来将流引到各个 peers。

我们的 App 包括一个登陆界面,在此用户输入名字和他想加入和交谈的房间号,在这个房间里他可以看到视频会议的其他参与者。

此教程的代码可以在 Github 上一个公共目录下获得,你可以将它 clone 到你的本地,直接使用,也可以跟着我们这篇文章来一步步做起来。如果你选择后者,请下载 adapter.js 和 kurento-utils.min.js,之后我们将会用到。

我们使用 JavaScript 作为编程语言,使用 Node.js 作为运行引擎,因此如果你没有 node 的话需要安装它。我们还会使用 Docker 来在本地运行媒体服务器。

让我们从创建新文件夹开始,这将会是项目文件夹。

接着在里面创建一个叫做public的文件夹,现在将下载的library复制到这里。使用命令行,导航到项目文件夹,并输入如下命令来安装所需要的环境。在下载library的时候需要网络连接。

另外, 启动媒体服务器,在命令行输入以下命令。

开始时,我们需要创建一个html文件包含两个divs,一个是用来登录,另一个用来实际交流。同样,我们添加kurento-utils library,它需要adapter.js , http://socket.io客户端library和client.js文件。

使用你最喜欢的文本编辑器,建立一个新文件夹,粘贴如下代码并保存到项目文件夹下,在public文件夹里命名为index.html.

很好,现在我们来创建客户端的JS文件。我们从得到网页元素的reference和声明客户用户名和房间号的变量开始,我们同样需要声明一个变量用来储存一系列的会议参与者。接着,就像一对一版本的app一样,我们使用http://socket.io连接信令服务器,并注册一个点击事件,用来向服务器发送第一条信息,这是一个‘’加入房间‘’的信息。这次我们不直接使用socket.emit()函数,而是使用一个sendMessage()函数,它被定义在文件底部。我们还需要声明服务器信息的handlers。

使用文本编辑器创建client.js文件,并保存在项目里的public文件夹下。
 

接着,我们创建服务器。我们首先添加所需的node packages.接着声明一对变量来存储Kurento 客户端reference,一个队列来存储在Kurento断点建立之前接收的ice candidates。

接着将App和Kurento服务器的URL设置成as_uri和ws_uri。注意,运行的时候,我们尽量少的使用package来为使用命令行设置这些值提供支持。

接着我们对public文件夹建立一个static的host,并定义通过http://socket.io接收的events的handlers.最终我们建立一个函数来从媒体服务器得到Kurento客户端的reference,并将App的听众设置在端口3000.

【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~

使用你最喜欢的文本编辑器来建立server.js文件并将其保存在项目文件夹下。
 

现在继续交谈过程,在服务器端,当我们接收客户端发送的加入房间的信息之后,我们调用joinRoom函数,它使用getRoom函数来管理房间。

在getRoom函数里,当第一个客户到达时,我们创建一个新的房间,和一个新的Kurento MediaPipeline, 这个pipeline与房间和一个空的参与者的列表被分到一起。当另一个客户到达时,我们不需要创建新的pipeline,因此仅仅将客户添加到房间中。

回到joinRoom函数,在我们得到房间之后,我们创建一个Kurento WebRTC断点,它被分配到用户。接着如果队列中存在任何ice candidate,它将会被通过调用断点的addIceCandidate函数添加进去,接着我们建立onIceCandidate 事件。

通过发送两条信息,函数结束:一条信息是对于其它在房间中的用户通知他们有新的参与者,另一条信息是对当前用户通知当前存在的参与者。向server.js添加函数如下。
 

在客户端,两个函数管理服务器发送的newParticipantArrived’ 和 ‘existingParticipants事件,它们是receiveVideo和onExistingParticipants函数。

在onNewParticipants函数中我们首先要建立视频元素来展示流,创建一个用户为当前参与者。用户对象将会存储新创建的视频元素和一个rtcPeer field.

在将用户对象存入全局参与者数组之后,我们实现Kurento的API对象,并将其分配到rtcPeer filed,并准备一个请求来开始发信过程。通过调用receiveVideo函数结束函数。

每个函数都具有它们自己的对于onOffer和onIceCandidate事件的内部函数,事件由rtcPeer对象激发,当准备好的时候,它们负责向服务器发送实际请求和ice candidates,发送receiveVideoFrom和candidate信息。将如下代码添加到client.js.
 

到目前为止,我们完成了第一步,并且开始发信过程。

在服务器端,receiveVideoFrom和candidate事件由receiveVideoFrom和addIceCandidate函数处理。第三个叫做getEndpointForUser的函数同样被用来恢复与每一个用户相关的Kurento WebRTC断点。

ReceiveVideoFrom函数非常简单,当它获取到合适的断点,它处理请求,产生一个应答,将其发送到客户端并开始收集ice candidates.同样方式, addIceCandidate函数接收ICE Candidate并将其添加到相应的断点中。GetEndpointForUser获取正确的断点来接收视频。添加如下代码到server.js中。

到目前为止,我们完成了第一步,并且开始发信过程。
在服务器端,receiveVideoFrom和candidate事件由receiveVideoFrom和addIceCandidate函数处理。第三个叫做getEndpointForUser的函数同样被用来恢复与每一个用户相关的Kurento WebRTC断点。
ReceiveVideoFrom函数非常简单,当它获取到合适的断点,它处理请求,产生一个应答,将其发送到客户端并开始收集ice candidates.同样方式, addIceCandidate函数接收ICE Candidate并将其添加到相应的断点中。GetEndpointForUser获取正确的断点来接收视频。添加如下代码到server.js中。

接着在客户端我们需要处理服务器发送的receiveVideoAnswer和candidates事件,这是通过使用onReceiveVideoAnswer和addIceCandidate函数来完成的。添加它们到client.js文件中。

使用以上代码,我们完成了发信过程,步骤2完成了。

当我们在客户端使用kurento-utils library时,客户不需要再做额外的动作。因此步骤3自动完成。
现在是时候运行App了,在命令行,进入项目文件夹并输入如下命令
node server.js

接着使用Google Chrome或Mozilla Firefox,在三个或更多标签中打开http://localhost:3000,输入不同的参与者姓名和相同的房间号并点击进入。

作者:RTE开发者社区
原文链接 如何使用 WebRTC 与 Kurento 建立视频会议 App

相关文章:

  • 如何成为一个更好的沟通者?
  • 粒子群优化算法(Particle Swarm Optimization,PSO)求解基于移动边缘计算的任务卸载与资源调度优化(提供MATLAB代码)
  • navicat连接postgresql、人大金仓等数据库报错
  • 带libc源码gdb动态调试(导入glibc库使得可执行文件动态调试时可看见调用库函数源码)
  • 【Vue实用功能】Vue实现文档在线预览功能,在线预览PDF、Word等office文件
  • [MQ]常用的mq产品图形管理web界面或客户端
  • MySQL数据导入:MySQL 导入 Excel 文件.md
  • vue预览pdf文件的几种方法
  • 77.Go中interface{}判nil的正确姿势
  • Windows 10/11系统自带“录屏”功能的快捷键无效的解决之道
  • C++ 数论相关题目 扩展欧几里得算法(裴蜀定理)
  • 如何实现Win系统ssh连接Ubuntu使用vscode远程敲代码
  • 跟收费说拜拜,IDEA接口调试插件推荐
  • 【RabbitMQ】死信(延迟队列)的使用
  • mysql面试题合集-基础
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • egg(89)--egg之redis的发布和订阅
  • Java新版本的开发已正式进入轨道,版本号18.3
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • PHP 的 SAPI 是个什么东西
  • php的插入排序,通过双层for循环
  • Rancher如何对接Ceph-RBD块存储
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Vue组件定义
  • WePY 在小程序性能调优上做出的探究
  • XML已死 ?
  • 分布式任务队列Celery
  • 和 || 运算
  • 计算机在识别图像时“看到”了什么?
  • 区块链技术特点之去中心化特性
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 我看到的前端
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 硬币翻转问题,区间操作
  • 《天龙八部3D》Unity技术方案揭秘
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​LeetCode解法汇总1410. HTML 实体解析器
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #QT(智能家居界面-界面切换)
  • $NOIp2018$劝退记
  • (31)对象的克隆
  • (Matlab)遗传算法优化的BP神经网络实现回归预测
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (三)模仿学习-Action数据的模仿
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (转)Sublime Text3配置Lua运行环境
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • (转载)Google Chrome调试JS
  • ***通过什么方式***网吧