WebRTC → RTP媒体管理

1,025 阅读15分钟

前置知识

  • 轨道
    • MediaStreamTrack是WebRTC中的基本媒体单元,此轨道代表一种设备或录制内容(源)可返回的单一类型媒体
    • 每个轨道都有一个源与之对应关联,但通过WebRTC不能直接访问或控制源,对源的一切控制都通过轨道实施
      • 源只是理论上的一个实体,浏览器可基于可用的设备以任意方式提供源
      • 源于轨道的关系
        • 每个轨道各自与一个特定的源关联,但同一个源可以有多个关联的轨道
      • 有两种方式可以暂停轨道的媒体:静音和禁用
      • 可以检查轨道的muted属性值获取是否禁音
      • 通过轨道对象的enabled属性设置为false,可以单独逐一禁用每个轨道,上述两个属性均独立于轨道的readyState属性
      • readyState属性表示轨道的状态
        • new:表示轨道尚未连接至媒体
        • live:表示轨道连接至媒体,可以生成媒体
        • ended:表示轨道的源无法提供媒体数据
    • 轨道不仅可以是来自源的原始媒体,还可能是浏览器提供的经过转换的版本
    • 轨道对媒体的约束方式
      • 通过Track.getCapabilities()返回的对象可以得知该媒体可约束的属性以及可以对其赋予的值范围或列表
      • 通过Track.getSettings()将返回所有可约束的属性及其当前值
      • 通过Track.applyConstraints({options},successCB,failureCB)的调用来设置可以配置的属性值 image.png
    • WebRTC提供了createObjectURL来基于Mediastream创建URL,此创建的URL可以赋予媒体元素新定义的srcObject属性,实现媒体流的播放,任何Mediastream对象都可以直接赋予到该srcObject属性上
  • Web服务器
    • Web服务器为WebRTC应用程序提供了两种实用的功能
      • 服务于Web应用程序本身
      • 充当两个或多个浏览器之间的中继(提供信令服务)
        • 用于协商在浏览器之间传输的媒体的目标、类型和格式
    • 广义区分Web服务器的类型
      • 多线程服务器
        • 为每个请求提供单独的进程,这样可以简化文件搜索,但请求之间的同步十分复杂
        • 例如ApacheWeb服务器
      • 单线程服务器
        • 简化请求之间的同步,但文件检索的输入输出十分复杂
        • 如Node服务器
  • 流(Mediastream)
    • Mediastream是MediastreamTrack对象的集合,创建方式有两种
      • 通过现有的Mediastream中复制轨道来请求对本地媒体的访问
        • 通过getUserMedia()获取媒体流
        • 可以通过clone()的方式来复制流(及其所有轨道)
      • 使用对等连接来接收新的流
    • Mediastream对象中的所有轨道都将会在呈现时进行同步,每个轨道都没有排序,任何添加重复轨道的尝试都会被忽略
    • Mediastream中也有类似于轨道的ended属性,其ended属性用来表示Mediastream是否已完成,当Mediastream中所有轨道的状态都为ended,则视为该Mediastream已完成
  • 实时音视频应用环节浅析
    • 采集 → 编码 → 前后处理 → 传输 → 解码 → 前后处理 → 缓冲 → 渲染等
    • 前后处理包括:美颜、滤镜、回声消除、噪声抑制等
    • 采集有:麦克风阵列等
    • 编解码有:VP8、VP9、H.264、H.265等 image.png
  • 主流的视频编码器分为三个系列
    • VPx系列:VP8、VP9
      • 相同质量的前提下:VP9比VP8码率减少约50%;
    • H.26x系列:H.264、H.265
      • H.26x系列在硬件支持上比较广泛,H.265的编码效率可以比上一代提高30~50%,但复杂度上比上一代大很多
    • AVS系列:AVS1.0、AVS2.0
  • RTP、RTCP与RTSP浅析
    • RTP(Real-time Transport Protocol)
      • 是一种网络协议,一般负责音视频数据的封装和传输;
      • 播放器上的图像视频数据就是靠RTP进行传输的
    • RTCP(Real-time Transport Control Protocol:实时传输控制协议)
      • 是一种网络协议,是RTP的姊妹协议,是为了进行服务质量的监视和反馈、媒体间的同步、多播组中成员的标识,目前WebRTC用这个协议进行流量和拥塞控制
      • RTP大多数情况下是不可靠的协议,只管传输音视频数据,并不保证这些数据丢失,传快了该怎么处理此时就需要用到RTCP协议来保障了
    • RTSP(Real-time Streaming Protocol:实时流协议)
      • 是一种会话管理和媒体控制的协议,用的最多的地方就是视频监控,视频监控中摄像机、NVR、前后端之间都是用这个协议和RTP协议配合进行流媒体传输
      • 像播放器中的控制条上的功能就需要RTSP来支持
  • 参考文献

发布与接收媒体流简介

image.png 发送端

新媒体的加入会导致重新协商,发起协商的内容包括新加入的媒体消息,当协商完成,发送端开始对媒体流进行编码压缩,并将编码后的媒体流传输给对等端 接收端 当有新的媒体流传入时就会触发track事件,在该事件中获取对应的媒体流,媒体流在之前的协商中已经确定了编码格式,接收端在接受到媒体流后进行解码,随后将媒体流播放出来

webRTC编解码器

webRTC对音视频编码有强制要求,对于视频,要求所有兼容webRTC的浏览器必须支持VP8和AVC/H.264视频编码;对于音频要求必须支持Opus和G.711 PCM编码格式

image.png

AV1专门为web设计的,拥有比VP9更高的压缩率,但是AV1技术尚未成熟

视频编码

VP8/VP9
  • VP8(Video Processor 8)
    • 由On2公司研发,谷歌收购,从压缩率和视频质量方面来说,VP8和H264很接近;
  • VP9(Video Processor 9)
    • 由谷歌在VP8基础上优化版,拥有比VP8更高的性能和视频质量,与H.265(由版权问题)很接近;
  • 通常将视频格式WebM与VP8/VP9结合使用,WebM不支持Safari,需要单独提供其他编码方案
H.264

H.264yo又名为AVC(Advanced Video Coding),使用非常方便,通过更改配置可以胜任不同场景,如配置Constrained Baseline Profile(CBP)使用了较低的带宽,适合用于视频会议和移动网络;Main Profile适用于标准的视频内容;而High Profile则适用于高清蓝光DVD视频。

H.264和H.265支持硬件加速,在使用过程中比VP8、VP9更省电、设备也不容易发热,目前大多数webRTC应用选择了H.264作为默认的编码格式

音频编码

Opus/G.711

Opus是webRTC主要使用的音频编码格式,具备很好的灵活性和可拓展性,用于语音、音乐播放等音频场景;
Opus支持码率范围是6~510kbps,支持最多255个音频通道,最大采样率48KHz,延时范围5~66.5ms,可用于MP4/WebM/MPEG-TS封装格式;
G.711 PCM是一种实现简单,兼容性高的音频编码格式,支持码率64Kbps,采样率8KHz,通常用于向下兼容

媒体服务器

尽管P2P可以实现多点用户保持视频通话,但随着人数增多,该方案将不再实际,需要一个用户将数据流进行不断的转发与多位接收,此时媒体服务器就可以派上用场了,可以减少客户端需要发送的流的数量,同时也减少接收的流的数量,可以理解成一个中间人的角色,其主要作用可以是SFU(单一转发单元 Single Forwarding Unit):主要目的是在客户端之间转发媒体流、MCU(多点会议单元Multipoint Conferencing Unit):不仅仅可以转发媒体流,还可以对通过它的媒体流进行处理(如将多路流合成一路,对音视频底层进行处理,如在视频上运行计算机视觉模型或将音频流转发到语音识别引擎,进而将WebRTC提升到另一个层次);

WebRTC是一组协议、机制和API、通过对等连接为浏览器和移动端应用程序提供实时通信(RTC)功能,可以理解为是一种允许浏览器直接通信而不需要任何基础设施的中介技术,但是要实现复杂点的功能时就需要通过中间媒体服务器来实现了,如组通信,媒体广播和转码等功能;
WebRTC媒体服务器只是一个多媒体中间件,当从源到目的地移动时,媒体流就会通过该中间件,媒体服务器可以处理传入的媒体流并提供不同的结果

  • 媒体服务器提供的功能点
    • 组通信:在多个接收器之间分发一个对等方生成的媒体流,即充当多会议单元(MCU)
    • 混合:将多个传入流转化为一个单一的复合流
    • 转码:动态调整编解码器和格式以兼容多种客户端
    • 记录:以一种持久的方式存储对等方之间交换的媒体
  • 可以作为MCU使用的媒体服务器有:Licode、OWT、Kurento、Medooze
  • 可以作为SFU使用的媒体服务器有:Licode、OWT、Kurento、Jitsi、Janus、Mediasoup
  • Licode架构图
    • Licode既可以用作SFU类型的媒体服务器又可以用作MCU类型的,通常用于SFU类型,它不仅仅是一个流媒体通信服务器,而且还包括了媒体通信层、业务层、用户管理等功能完整的系统,还支持分布式部署
    • 源码地址 image.png

OWT

OWT(Open WebRTC Toolkit)是Intel在2014年推出的针对WebRTC的开发套件,于2018年开源,该套件包含了优化Intel硬件的服务器和客户端SDK;
OWT既可以充当多点控制单元(MCU),又可以作为选择性转发单元(SFU)使用,还提供了对媒体进行解码、处理和重新编码后再将其发送回客户端的能力

主要功能
  • 多方视频会议
    • 同时支持MCU和SFU两种模式
  • 转码
    • 支持对音视频进行转码,以适应不同场景
  • 将WebRTC转化成其他视频格式
    • OWT支持将WebRTC的RTP流转化成RTSP、RTMP、HLS等格式,以便非WebRTC接入的客户端也可以观看实时流
  • 录制
    • OWT支持将音频及视频存储到磁盘
  • SIP网关
    • 可以作为SIP网关使用
  • 视频分析
    • OWT支持使用机器学习对视频内容进行分析
内部解析

OWT应用层使用了Node.js开发,媒体处理层使用了C++语言,数据库使用了MongoDB,消息通信使用了RabbitMQ,其他还包括全平台的客户端SDK

Kurento

Kurento开源项目包含一个WebRTC媒体服务器(KMS)和一组与之通信的客户端API,使用Kurento可以简化Web以及移动端音视频应用程序的开发过程;Kurento的主要组件是Kurento媒体服务器(KMS),Kurento提供的功能包括媒体的处理与传输、音视频实时通信、实时转码、服务器端录制、合流、广播等,它允许WebRTC将非常有趣的功能进行集成,如计算机视觉(识别QR码、面部检测)、实时媒体修正和与RTP(VolP)服务的交互,还可以在单个实例中配置成SFU或MCU

主要功能
  • 动态WebRTC媒体管道
    • Kurento允许使用自定义媒体管道连接到WebRTC对等设备,如Web浏览器和移动应用程序,这些媒体管道包括播放器、记录器、混音器等,可以在任意时间点对这些媒体管道进行组合、激活或停用等
  • 第三方模块
    • Kurento媒体服务器具有基于插件的可拓展结构,该结构支持允许第三方自定义模块,通过该模块可以将任何媒体处理算法集成到WebRTC应用中,例如计算机视觉、增强现实,视频索引和语音分析等

Janus

image.png

  • Janus由Janus CORE、Janus Plugin和信令接口三部分组成
    • Janus CORE:是Janus的核心,其作用是处理流的转发,各种协议的接入;
      • 以浏览器为例,要想让浏览器接入到WebRTC媒体流服务器上,那流媒体服务器必须支持STUN、DTLS、SRTP、ICE等协议,而Janus CORE就是专门做这些事的
    • Janus Plugin:Janus的业务管理是按照Plugin的方式管理的,因此可以在Janus中根据需要实现自己的业务插件,常用插件如下拓展
    • 信令接口:Janus支持的信令协议较多,如HTTP、WebSocket、RabbitMQ等,这些信令协议协议使得Janus具有非常好的接入性,因此Janus在信令接入方面有较大的优势 image.png

采用C语言实现的Janus是一个Linux风格编写的WebRTC媒体服务器开源项目,支持在Linux/MacOS下编译、部署,但不支持Windows环境;整体的架构采用了插件的方案,用户可以按需引用编写程序;
Janus分为两层,插件层和传输层,插件的设计类似于Nginx,用户可以根据自己的需要动态加载或卸载插件,也可以编写自己的插件;传输层用于处理Janus的各种信令(Janus中的信令都采用JSON的格式),支持的信令有HTTP/HTTPS、WebSocket/WebSockets、NanoMsg、MQTT、PfUnix和RabbitMQ

支持的插件
  • SIP协议,使得WebRTC协议与SIP协议可以互相通信
  • TextRoom:该插件使用DataChannel实现了一个文字聊天室应用
  • Streaming:允许WebRTC终端预先观看其他工具预先录制生成的文件或媒体
  • videoRoom:是一个音视频路由器,实现了视频会议的SFU服务
  • videoCall:是一个简单的视频呼叫应用,但这个插件需要服务器进行音视频流的中转
  • RecordPlay:将发送给WebRTC的数据录制下来、通过WebRTC进行回放的两个功能

Mediasoup

Mediasoup架构图.png

  • Node.JS层:负责Mediasoup的信令接收与业务管理,如创建/销毁房间、创建/关闭生产者、创建/关闭消费者等
  • Mediasoup(C++)层:是一个单独的程序,无法直接启动,原因是内部会判断是否是NodeJS将其启动起来了,只有在NodeJS的Mediasoup管理模块加载之后,再将Mediasoup(C++)启动起来,这样才能正常工作;
    • Mediasoup是单进程的,是使用单进程的方式将服务器上CPU的某个充分利用好,然后在业务层控制进程的数量
  • NodeJS和Mediasoup之间通过管道进行通信; image.png

Mediasoup是一个较新的WebRTC媒体服务器,底层采用C++实现,外层使用Node进行封装,Mediasoup服务器端以Node模块的方式进行提供,使用libuv作为异步IO事件处理库,保证数据传输的高效性,只关心底层数据的传输,并做到极致;
与Janus相比,Mediasoup更关注数据传输的实时性、高效性和简洁性,而Janus相对来讲更加复杂一些。
在Node模块内部,Mediasoup可以分为两个独立的组件,一个是JS层,提供了使用于Node的现代ES API;另一个是处理媒体层(ICE、DTLS、RTP等)的C/C++子进程(Worker);这两个组件通过进程相互通信;

Medooze架构浅析

image.png

Medooze架构与Mediasoup类似,不过其信令处理、业务管理与媒体数据的转发功能都是在NodeJS下统一管理;
Medooze的业务功能要比Mediasoup强大,像服务端录制、推流这些Mediasoup没有的功能它都支持,但性能没有Mediasoup做的极致,Medooze的底层是用poll来处理异步I/O事件,poll与epoll性能相差甚大

浅析Mediasoup

源码地址

Mediasoup把每个实例称为一个子进程Worker,可以理解成一个节点,通常在每个CPU上启动一个子进程。在子进程内部有多个Router(应用层角度可以理解成一个房间,数据流转角度可以理解成一个路由器,数据通过路由器转发给目标用户),每个Router相当于一个房间。在每个房间里可以有多个参与者,每个参与者在Mediasoup中由一个Transport代理。换句话说,对于Router,一个Transport就相当于一个用户;
pipeTransport用于实现Router之间的连接,即一个房间的音视频流通过pipeTransport传输到另一个房间;

媒体服务器的选择

  • 当需要采用MCU方案时,推荐使用OWT
  • 当需要在服务器端对媒体流进行处理如增加人脸识别功能时推荐使用Kurento
  • 当构建通用的WebRTC平台时,Janus基于插件开发的模式更为合适
    • 当业务种类较多,变化较快时建议使用Janus作为流媒体服务器,将具体的业务做成一个插件放到Janus上很快就实现了业务需求
  • 当需要开发单一的视频通话应用,推荐使用Mediasoup;
    • 当团队较强,可以做底层开发,建议使用Mediasoup,因为Mediasoup不关心应用层,只关注底层数据如何高效的流转、代码整洁、高效、性能极佳;
  • 当业务变化不大,除追求性能外,还需要录制、推流等功能时,可以选择Medooze,但是常用的录制都需要单独实现,如是录制成多路混屏的,还是每路流单独录制,再后期处理

推荐文献

18个实时音视频开发中会用到开源项目