实时音视频开发散记

  • 作者:JetaimeTse
  • 分类:webrtc
  • 发表日期:2020-08-30 23:16:00
  • 阅读(45)
  • 评论(0)

rtc\webrtc\aiortc

什么是rtc

rtc(Real-Time Communications):泛指各种数据,包括音频、视频、文本、图片等媒体或非媒体数据的实时传输

从功能流程上rtc包含采集、编码、前后处理、传输、解码、缓冲、渲染 等很多环节,每一个环节还有更多细分的技术模块,如视频的编解码,音频的降噪或者美颜,滤镜等一些处理环节。


rtc中导致延迟的环节


1. 采集 / 渲染:

​ 在实际的网络结构中,网络往返时的延迟都控制在 50 毫秒以内,这个环节中尤其是渲染,由于一些硬件,很难保证网络延迟会在50毫秒内,甚至可能是这个环节带来的延迟是最大的。

2. 媒体数据的编解码

​ 这个环节中有些延迟是避免不了的,不同的编解码引擎和引擎的处理粒度或多或少都会给整个传输过程带来延迟。

3. 网络分发

​ 这是大家最能体会到的,客户端所处的网络环境差,以及服务器是否选择了资源集中的最优子集,另外还有网络分发中可能出现的丢包现象,这些都可能会给接收端媒体数据的卡顿感。


如何降低延迟


a. 服务器端应该考虑的事

负载均衡: 当一个rtc系统搭建完成,服务器的每一个节点都应承担相对均匀的服务,不至于使得某个节点负载过重,不然会造成一些丢包,使网络往返时间增大,也就造成音视频延迟的增加。

就近接入:这里的“近”并不是指地域上的近,而是“网络上的近”。很简单的例子,我们在深圳做推流,香港离得很近,可以推到香港的服务器,但实际上这毕竟是一个跨域的网络,有不稳定的因素在里面,所以我们宁愿推远一点。这个近指的应该是在网络质量评估意义上的近,例如网络往返时很小、往返时很平稳、分布在延迟比较大的时刻不会还具有很大的概率,丢包率很低等。

实时动态路由:举个例子,我在北京要往厦门推送数据,通常来说我们会直接将数据发到厦门的服务器,但有可能出现直接推流这个链路并不好,反而增加链路中一些路由节点带来效果更好,例如北京先发往上海的服务器,再有上海的服务器发到厦门的服务器。

b. 网络传输与传输机制

     实时音视频传输中,实现一套可靠的传输机制相比于优化其它环节,就像高铁和火车有着本质区别,火车再怎么优化终究是跑不赢高铁的。要实现低延迟可靠的传输机制,信道服务质量(QoS)尤为关键,这里主要介绍FEC(前向纠错技术)和ARQ(丢包重传技术)

FEC — 前向纠错技术: 是指根据网络状况,调整算法,增加或减少发包冗余度,以四六编码为例, 我要发一个分组,这个分组有六个包,其中有四个包是实际媒体数据,有两个包是冗余包。那么在解码端收到六个包中任意的四个,就可以完全恢复所有携带媒体内容的包。当网络环境差的时候,就增加冗余包的占比,相反则降低。

ARQ — 丢包重传技术:是指接收端在接收到发送端发过来的包时,告诉发送端自己的收包情况,如果少接收了包,则发送端会把丢失的包重传。

​ 参考自如何优化传输机制来实现实时音视频的超低延迟

c. 媒体数据编码

​ 为了节省传输过程中的带宽和时间,提高传输效率,对媒体数据进行编码,把大量的数据压缩成比较小的网络数据,以减轻网络负担这是必要的。

​ 附:视频压缩编码和音频压缩编码的基本原理


什么是webrtc

webrtc(web real-time communication): 它最初是为了解决浏览器上视频通话而提出的,即两个浏览器之间直接进行视频和音频的通信,不经过服务器。后来发展到除了音频和视频,还可以传输文字和其他数据。开发者可以轻易开发出实时多媒体应用,而无需安装任何插件,也无需关注媒体数据的数字信号处理过程。 它主要让浏览器具备了以下三个作用:

  • 获取音频和视频 — getUserMedia
  • 进行音频和视频通信 — RTCPeerConnection
  • 进行任意数据的通信 — RTCDataChannel

webrtc支持的平台:Chrome、Firefox、Opera、Edge、Safari、Android、iOS


webrtc架构介绍及与rtc的关系


webrtc架构组件介绍

​ 上图是webrtc的技术架构图,由上图可概括webrtc的架构如下:

你的Web应用:Web开发者开发的程序 ,Web开发者可以基于集成webrtc的浏览器提供的web API开发基于视频、音频的实时通信应用。

面向第三方开发者的webrtc标准API

webrtc原生 C++ API:使浏览器厂商容易实现webrtc标准的Web API,抽象地对数字信号过程进行处理。

音频引擎: 是包含一系列音频多媒体处理的框架,包括从视频采集卡到网络传输端等整个解决方案。

视频引擎: VideoEngine是包含一系列视频处理的整体框架,从摄像头采集视频到视频信息网络传输再到视频显示整个完整过程的解决方案。

传输/会话控制层: 采用了libjingle库的部分组件实现,无须使用xmpp/jingle协议。

​ a. RTP Stack协议栈:Real Time Protocol;

​ b. STUN/ICE:可以通过STUN和ICE组件来建立不同类型网络间的呼叫连接;

​ c. Session Management:一个抽象的会话层,提供会话建立和管理功能。该层协议留给应用开发者自定义实现。


webrtc与rtc的关系

上图展现了rtc与webrtc的关系,webrtc只是rtc的一部分。webrtc实现了rtc功能流程的媒体数据采集、编码前处理、音视频的编解码以及传输控制,这里的传输控制应注意,webrtc并不提供完整的服务器方案的设计与部署


webrtc建立实时通讯的过程


基本术语

信令服务器(SIP): 是实现webrtc通信很重要的一个部件,主要负责交换2个终端的候选地址(Candidates)和媒体信息描述文件(SDP)。当2个终端都在NAT后面时,双方都不知道对方的地址也无法连接到对方,而且双方也不知道对方所支持的媒体类型以及是否支持某些特定的网络协议。因为需要一个身处公网的服务器(信令服务器)来为双方交换这些信息。信令服务器也可以起到房间管理的作用。可以在整个通信过程中与双方客户端始终保持长连接来通知双方房间状态,比如有人离开,会议结束等等。而信令服务器是必需的。

SDP: 是一个媒体信息描述文件,用于描述自身的能力,比如我的浏览器想做为一个终端与另一端进行音视频通信,我应该告诉对方我是否支持音频或视频通信,以及我所支持的编解码格式,我是否支持丢包重传,FEC校验等等。另外,也可以把candidates(候选地址)添加到SDP中,一并告诉对方可以连接到我的地址是哪几个。

候选地址(Candidates): 一个候选地址可理解为一组IP+端口号+优先级+网络类型组成的字符串。每个终端因网络环境不同可能有多个候选地址。

OFFER: 由通话发起端发出的SDP叫做OFFER

ANSWER: 由通话接受端发出的对应对方OFFER的应答SDP文件叫做ANSWER。是SDP文件在通话发起方和接受方的不同名称。

NAT: 可理解为一个防火墙或一个网关或路由器。比如我们的手机在使用wifi的情况下,我们的IP地址一般是192.168.0.1这种局域网地址,这时我们可以说我们在手机端在NAT后面,不是直接拥有公网地址。

STUN服务器: 一个位于公网的具有公网IP的服务器,我们位于NAT后面(局域网内)的终端可通过访问STUN服务器来获取我们所有的候选地址。其实就是我在局域网内,我不知道自己的IP地址,不知道自己的公网IP地址也不知道自己的网络类型,这时我可以问STUN服务器,当我向其发消息时,身处公网的STUN服务器会将其收集到的我的网络信息发送给我。STUN服务器可以在github上找到并在某个公网机器上搭建一个,也可以使用已知的公用的一些STUN服务器,网上可以搜到很多。

TURN服务器: 当两个想建立连接进行音视频通信的网络环境都很复杂,都处于NAT后面且双方始终无法建立连接时,可通过连接到TURN服务器的方式,用其帮忙转发音视频流。因TURN服务器身处公网,所以大家都可以连接上它。


过程描述


webrtc如何支持群聊

多人视频通讯常用架构Mesh/MCU/SFU

引用自原文

webrtc虽然是一项主要使用p2p(端到端)的实时通讯技术,本应该是无中心化节点的,但是在一些大型多人通讯场景,如果都使用端对端直连,端上会遇到很带宽和性能的问题,所以就有了上图的三种架构。

一、Mesh架构

​ 每个端都与其它端互连。以上图最左侧为例,5个浏览器,二二建立p2p连接,每个浏览器与其它4个建立连接,总共需要10个连接。如果每条连接占用1m带宽,则每个端上行需要4m,下行带宽也要4m,总共带宽消耗20m。而且除了带宽问题,每个浏览器上还要有音视频“编码/解码”,cpu使用率也是问题,一般这种架构只能支持4-6人左右,不过优点也很明显,没有中心节点,实现很简单。

二、MCU (MultiPoint Control Unit)

​ 这是一种传统的中心化架构(上图中间部分),每个浏览器仅与中心的MCU服务器连接,MCU服务器负责所有的视频编码、转码、解码、混合等复杂逻辑,每个浏览器只要1个连接,整个应用仅消耗5个连接,带宽占用(包括上行、下行)共10m,浏览器端的压力要小很多,可以支持更多的人同时音视频通讯,比较适合多人视频会议。但是MCU服务器的压力较大,需要较高的配置。

三、SFU(Selective Forwarding Unit)

​ 上图右侧部分,咋一看,跟MCU好象没什么区别,但是思路不同,仍然有中心节点服务器,但是中心节点只负责转发,不做太重的处理,所以服务器的压力会低很多,配置也不象MCU要求那么高。但是每个端需要建立一个连接用于上传自己的视频,同时还要有N-1个连接用于下载其它参与方的视频信息。所以总连接数为5*5,消耗的带宽也是最大的,如果每个连接1M带宽,总共需要25M带宽,它的典型场景是1对N的视频互动。随着5G技术的推广,可以预见带宽越来越不是问题,所以SFU在未来,可能会更有优势。

​ 如果规模不大(5人以下) Mesh框架就够用了,毕竟实现简单;如果50人以下,且带宽有限,选择MCU比较适合;如果规模更大,且带宽良好,SFU相对更


什么是aiortc

​ aiortc是Python中用于Web实时通信(webrtc)和对象实时通信(ortc)的库。它是基于Python的标准异步I/O框架asyncio搭建的。

RabbitMQ

什么是消息中间件

​ 9+消息中间件在互联网公司中使用越来越多,主要的作用的是用来做应用程序的解耦,以及消息的缓冲和分发。消息中间件的常规用法就是生产消息传送到队列中,消费者从队列中拿消息处理,生产者不需要关心谁来消费,消费者也不需要知道消息是谁生产的,两者是没有直接关系的,从而达到解耦的目的。

RabbitMQ介绍

什么是RabbitMQ

​ RabbitMQ是消息中间件的一种,它负责接收和转发消息,通俗理解就是可以把RabbitMQ比作是一个邮局,我们把信件放到邮箱,由邮局将信件发到我们指定的地点,而邮局不对信件内容进行处理。不同的是我们的信件并没有地址,地址是在邮箱中,邮局根据邮箱上的地址把消息发送给收件人,而收件人需要主动把地址写在邮箱上。

支持的开发语言: Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP

​ 同时RabbitMQ还支持消息和队列的持久化,即在某些情况下,服务器宕机了或其它原因导致服务器出现问题,而队列和队列中的消息不会消失。。


工作原理

​ 上图左侧代表生产者,也就是往RabbitMQ发消息的程序。 中间即是RabbitMQ,其中包括了交换机和队列。右侧C代表消费者,也就是往RabbitMQ拿消息的程序。


相关概念

Broker

简单来说就是消息队列服务器的实体。

Exchange

接收消息,转发消息到绑定的队列上,指定消息按什么规则,路由到哪个队列。

Queue

消息队列载体,用来存储消息,相同属性的 queue 可以重复定义,每个消息都会被投入到一个或多个队列。

Binding

绑定,它的作用就是把 Exchange 和 Queue 按照路由规则绑定起来。

Routing_Key

路由关键字,Exchange 根据这个关键字进行消息投递。

Producter

消息生产者,产生消息的程序。

Consumer

消息消费者,接收消息的程序。

Channel

消息通道,在客户端的每个连接里可建立多个 Channel,每个 channel 代表一个会话。


RabbitMQ的几种交换机类型

fanout

​ 不处理路由键。只需要简单的将队列绑定到交换机上。一个发送到这种类型交换机的消息都会被转发到与该交换机绑定的所有队列上。fanout 类型交换机转发消息是最快的。

direct

​ 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。如果一个队列绑定到该交换机上要求路由键 “info.1”,则只有被标记为 “info.1” 的消息才被转发,不会转发 info.2,也不会转发 info.2。

topic

​ topic其实是路由键(routing_key)的扩展,就是可以使用正则表达式,和常用的正则表达示式不同,这里的“#”表示所有、全部的意思;“*”只匹配到一个词。

  任何发送到Topic Exchange的消息都会被转发到所有关联routing_key中指定主题Queue上:

  • 这种模式较为复杂,简单来说,就是每个队列都有其关心的主题,所有的消息都带有个“标题”(routing_key),Exchange会将消息转发到所有关注主题能与routing_key模糊匹配的队列。
  • 这种模式需要routing_key,也许要提前绑定Exchange与Queue。
  • 在进行绑定时,要提供一个该队列关心的主题,如“usa.#”表示该队列关联所有涉及usa的消息队列
  • “#”表示0个或若干个关键字,“”表示一个关键字。如“log.”能与“log.warn”匹配,无法与“log.warn.timeout”匹配;但是“log.#”能与上述两者匹配。
  • 同样,如果Exchange没有发现能够与routing_key匹配的Queue,则会抛弃此消息。

webrtc与rabbitMQ是互联网两种不同的消息传递工具,webrtc提供的数据交互是建立在端与端直接相连的条件下,当需要多端参与的情况,单机的负载能力是很有限的,所以必须借助于中间服务器,搭建适合自己生产环境的架构,实现难度大。而RabbitMQ作为消息中间件,本身就是服务器,支持较大的吞吐量,每秒达到万级别。

提交评论

您尚未登录,登录之后方可评论~ 登录 or 注册

评论列表

暂无评论