写点什么

实现 WebRTC 的几个想法

2016 年 2 月 23 日

不借助第三方应用,快速且安全地在浏览器中传输视频——这有可能实现吗?根据你的需求,有不止一种方式能够将 WebRTC 添加到你的站点之中。

WebRTC(Web 实时通信,Web Real-Time Communication)是一项开源技术,用来在 Web 浏览器中实现实时直接的多媒体通信功能。它能够在两个或更多的人之间建立端到端的连接,这对于传输媒体(音频和视频流)来说是非常合适的。这项技术已经在如下的浏览器中得到了支持:Google Chrome、Mozilla Firefox 和 Opera。对于这些浏览器,我们不需要额外的插件。只需要打开一个 Web 浏览器页面并开启一个会话就可以了。对于使用 Safari 和 IE 的用户来说,没有原生的支持,但是我们可以添加特定的插件。

理念是非常简单的。首先,浏览器发送一个信号到 WebRTC 服务器,这个服务器是用户希望初始化调用的。在获取到服务器的连接之后,用户将其发送给他的同伴。浏览器弹出的窗口会提示用户访问 Web 摄像头和麦克风的权限。如果用户使用 HTTPS 协议的话,浏览器能够记住你所选择的选项(是否授予权限)。如果你使用 HTTP 协议的话,在每次尝试连接的时候,浏览器都会向你申请权限。

如果你是用户的话,这听起来非常简单。但是,作为开发人员,又该如何呢?在 Web 站点上如何实现它呢?如果你所需要的不仅仅是视频聊天,还要使用 Web 摄像头进行记录,并将录制的结果发送到 Amazon S3 存储中,这样第三方就有可能浏览这个录制结果,那又该怎样实现呢?对于一些场景来说,这种方式是非常棒的,比如收集某些商品和服务的视频回访,当某位讨论成员不在场的时候,为其记录视频信息,为工作的求职者进行面试,Web 支持等等。

我们都知道,视频格式有很多种。它们中的大多数在某些方面都具有一定的优势。例如,我可以选择 Flash 格式(FLV、F4V)来记录视频,但是这项技术在 Web 中正在逐渐失势。多个浏览器都已经宣布将来不再支持 Flash,这也是我选择使用 WebRTC 的另外一个原因。Flash 使用 H.264 视频编码解码器,而 WebRTC 使用 VP8。WebRTC 标准中规定要支持 H.264,但是它还没有得到广泛地应用。VP8 是免费的(H.264 并非如此),视频文件的质量和大小几乎是相同的。

我开始选择使用的是免费的 JavaScript 库,名为 MediaStreamRecorder ,它用于跨浏览器的音频 / 视频记录。这个库通常会与 WebRTC 实现相关。不过令人遗憾的是,在这个过程中,我遇到了很多技术难题。例如,每次记录完成时,浏览器会停止响应,并且会很多的延迟(lag)。

然后,我尝试使用 WebRTC Experiments 库。它使用了相同的技术,但是实现不同。记录完成时,它的延迟时间和浏览器行为都是正常的。

使用这个库的结论如下所示:

优点:

  • 不需要运行服务器,所有的负载都会落到浏览器端。
  • 录制过程的控制非常容易:只需点击 pause 键,就能开始新的录制和停止录制。
  • 没有延迟,因为所有的事情都是在 Kurento 中完成的(我稍后将会对其进行介绍)。

不足:

  • Google Chrome 会分别记录视频和音频,这样最终会有两个不同的文件:音频文件以及没有音频的视频文件。
  • 如果录制时间超过五分钟的话,浏览器会停止响应,用户的命令会被忽略掉。
  • 在录制停止时,将会耗费几秒钟的时间来解码视频和接收数据。
  • 它将会耗费一些时间将视频发送到仓库中。如果在文件传输的过程中,用户关闭了浏览器的 tab 标签,数据将会出现丢失。

我需要一个服务器来接收来自客户端的视频流并对其进行记录。对我来讲,一个较为合适的方案是使用 Kurento Media Server,我在 Amazon EC2 上使用 STUN/TURN 服务器进行了搭建。我使用 Kurento 实现了前端(不需要使用中间服务器)。Kurento(英语中“stream”这个词的世界语名称)是一个开源的框架,它提供了一个媒体服务器,这个服务器基于标准提供了任意媒体的处理功能。

最终,对于我来讲,无法接受这样的结果,但是如果上述的不足对你来讲不那么重要的话,那你可以使用这种方法。因为我的想法是尽可能实现最优的结果,因此我又开始寻找其他的解决方案。

有时候,我们所需要的记录文件并不仅仅只有一个。如果我们基于某些原因,需要将流划分为多个部分,例如应用只能接收三分钟或五分钟的视频记录(以避免出现过载的情况),那该怎么做呢?我思考过如何将一个小时的记录划分为12 个五分钟的记录,每一个都保存为一个单独的文件。我尝试的做法是每次都停止录制,断开与服务器的连接并重新开始录制(再次连接到服务器)。使用Kurento 无法正常运行,这是因为我每次重新连接服务器的时候,会丢掉几秒钟的记录(连接不是瞬时完成的)。

于是,我决定采用一个连接,使用Web 摄像头进行无停止的录制。稍后,我要将记录进行分割并将其发送到Amazon S3 上,这个过程中,我决定使用 node-fluent-ffmpeg 库。为了完成该功能,我搭建了一个新的服务器,但是这里还有一个难题。Kurento 会将文件保存为 _webm_ 格式,在 Google Chrome 上无法正确地播放(Mozilla Firefox 不会有这个问题):视频流播放地比音频流更快。修正这个问题的最佳方式是讲文件重编码为 mp4,这样就能解决这个问题了。

最终,所有的事情都能正常运行了。我使用 WebRTC 技术构建了完整的流程,在当前的任务下解决了所有的问题。当然,实现并不是 100% 完美的,我们同时可以看到它的优势和不足:

优点:

  • 视频和音频位于同一个文件中,没有将其分为两个单独的文件。
  • 视频是以实时的模式录制的,不会丢失视频文件。如果在客户端一侧实现录制的话,用户在退出我们的服务之前,必须要等待文件上传到仓库之中。

不足:

  • 连接到 Kurento Media Server 需要耗费一些时间。
  • 网络传输。客户端的带宽要足够快。
  • 实现起来比较困难,这不仅涉及到资源还涉及到时间。我必须要搭建 Kurento Media Server、coturn 以及 Node.js,其中 Node.js 会用来将视频转换为另外一种格式,将其拆分为多个部分,并将其发送到 S3 中。

WebRTC 技术是很新的,所以在安全性上会有一些问题。它所使用的加密构建在 TLS 协议之上。我们会发现安全漏洞,但是这可能并不是 WebRTC 技术的问题,而是信号传输所使用的浏览器本身的问题。WebRTC 的主要问题在于它很容易和快速地暴露真实的用户 IP 地址,它并没有使用代理、VPN、Tor 或流行的插件如 Ghostery 进行保护。为了使用 WebRTC 组织视频或音频会话,两台电脑必须发送 IP 地址给对方(不仅包括公网 IP,还包括私有 IP)。我们可以在 JavaScript 中使用简单的脚本来请求地址,在个人数据保护方面,这是一个巨大的问题,这个问题只能通过禁用 WebRTC 来解决。

这里有很大的提升空间,首先就是浏览器的良好支持。

你也可以看到,这里并没有完美的答案。这项技术有好处也有坏处,有优势也有不足,但是 WebRTC 正在迅速地流行起来。使用 WebRTC 的统计数据是令人兴奋的。有47% 的商业组织计划在未来的12 个月中使用该技术,或者已经使用了该技术。90% 的受访者相信WebRTC 有潜力提升客服中心的服务水平。超过720 家公司正在以某种实行使用WebRTC。

我们可以预期WebRTC 将会影响通信市场,有多种方式来使用该项技术。例如,假设在线商店会有一个“客户支持”的链接,我们可以点击这个链接并与客服进行视频聊天、询问问题并得到建议。这都是在浏览器中实现的,不需要额外的应用或插件。这能够在很大程度上提升客户服务的质量,因而有利于增加利润。这意味着致力于成为市场领导者的公司会迅速使用这项技术,其余的公司将会随之跟进。

现实中使用传统电话呼叫的很多领域正在被快速的链接点击或Web 通信器的消息所取代。相对于打电话,通过在站点上点击链接,会更加容易地打出租车、订餐等等。这是可以使用WebRTC 技术的一个领域。它起初与通用的视频聊天(如Skype)和电话呼叫进行竞争。谁知道呢,也许在未来的几年内,WebRTC 将会改变我们的日常习惯。

关于作者

Nikolai Bezruk Qualium Systems 的 JavaScript 开发人员,这家公司致力于为创业公司和数字代理公司创建 Web 和移动应用。Nikolai 担任团队领导和软件架构师,进行全栈的 Web 编程。他同时还负责培训新员工。

查看英文原文: Ideas for WebRTC Implementation

2016 年 2 月 23 日 17:266912

评论

发布
暂无评论
发现更多内容

PIP的报错Could not fetch URL https://pypi.org/

陈磊@Criss

Docker的Image

陈磊@Criss

人人都可以掌握的正交试验设计测试用例方法

陈磊@Criss

Python的Twisted事件驱动的网络引擎框架

陈磊@Criss

Web前端性能优化,应该怎么做?

华为云开发者社区

运维 前端 HTTP js 前端性能优化

第十周.总结

刘璐

原创 | 使用JPA实现DDD持久化-R:数据的世界

编程道与术

Java hibernate DDD JDBC jpa

22种超全用户触点采集,易观方舟SDK又更新了

易观大数据

Grafana和ES打造的Nginx的仪表盘

陈磊@Criss

该了解一波了!零基础入门Nginx

程序员的时光

nginx Docker

作业一

Kiroro

jmeter 执行python脚本

陈磊@Criss

Docker 容器连接

陈磊@Criss

Nginx的容器部署

陈磊@Criss

Java的Override和Overload

陈磊@Criss

Clover:解决Java8和Cobertura的问题以及解决方法

陈磊@Criss

架构师培训第10周练习

小蚂蚁

标新立异的日志归档:用更少的内存归档大规模测试日志

陈磊@Criss

欲速也可达:Battle接口测试训练系统的1分钟快速说明

陈磊@Criss

微信小程序的自动化测试框架

陈磊@Criss

作业二

Kiroro

python判断文件和文件夹是否存在、创建文件夹

陈磊@Criss

最受欢迎的男友职业排行榜Top10

程序员生活志

程序员

弹性计算的内部概念:弹性扩张、弹性收缩、弹性自愈

陈磊@Criss

Git删除仓库中的文件和文件夹

陈磊@Criss

pipreqs:生成python项目的requirements

陈磊@Criss

企业微信群消息机器人发送开源项目

陈磊@Criss

Docker的Image

陈磊@Criss

DockerFile 详解

陈磊@Criss

快速掌握的测试用例优先级划分方法

陈磊@Criss

高中生写LOL外挂1年狂赚500万,落网前刚买下120万保时捷...

程序员生活志

编程 程序员 外挂

演讲经验交流会|ArchSummit 上海站

演讲经验交流会|ArchSummit 上海站

实现WebRTC的几个想法-InfoQ