JITSI开源视频直播
徐景周
WebRTC被认为是一种点对点技术,浏览器可以直接通信而无需任何类型的基础设施。此模型足以创建基本应用程序,但难以在其之上实现诸如组通信、媒体流记录、媒体广播或媒体转码之类的功能。
2.1 Mesh架构模式
下面是WebRTC Mesh(网格P2P)模式下,1对1的视频通讯如图一所示。
2.2 Mesh事件序列
如图二所示,Mesh模式下1对1模式下的事件序列图。其中,Coturn Server为开源的NAT穿透服务器(支持STUN/TURN/ICE);Signal Server为信令服务器(可采用开源的Collider/SkyRTC/SignalMaster);
2.3 WebRTC框架
如图三、图四所示。
3.1 概述
WebRTC规范只定义了实时通信中客户端的行为,而没有规范服务端(包括哪些信令、数据如何流转)的行为。所以,你可以使用WebRTC库方便的实现1:1 实时通信,但对于多人实时互动,通常会使用WebRTC + 流媒体服务器的方案。WebRTC流媒体服务器类似“多媒体中间件”,从源到目的地时,媒体流量会通过该中间件。流媒体服务器能够处理媒体流并提供不同的类型,包括组通信(将一个对等方生成的媒体流分配给多个接收方),混合(将多个传入流转换为一个单一的复合流),转码(在不兼容的客户端之间适应编解码器和格式),录制(以持久的方式存储对等体之间交换的媒体)等。
如图五所示。WebRTC媒体服务器包括SFU(Selective Forwarding Unit,可选择转发单元),MCU(MultiPoint Control Unit,多点控制单元)或混合模式。
3.2 媒体流
如图六、图七所示。WebRTC由语音引擎,视频引擎和网络传输三大模块组成。其中,WebRTC音频处理(VoiceEngine)默认编解码是ISAC(Internet Speech Audio Codec),源码目录“/audio_coding”;视频处理(VideoEngine)默认采集与编解码是I420和VP8(源码目录“/video_coding”)。
3.3 流媒体服务器
基于WebRTC流媒体服务器有很多,如表一所示。下面针对主流的开源服务器进行介绍。
3.3.1 Janus
Janus 采用C语言实现,是一个非常有名的开源WebRTC流媒体服务器,它是以Linux风格编写的服务程序。支持Linux/MacOS下编译和部署,但不支持Windows环境。
Janus架构如图七所示。Janus分为两层:应用层和传输层。整体架构采用了插件的方案,用户可以根据自己的需要非常方便地在上面编写自己的应用程序。Janus 所有信令的格式都是采用JSON格式。
3.3.2 MediaSoup
MediaSoup使用C++和NodeJS语言实现,底层使用libuv处理I/O事件。
Janus架构如图八所示。MediaSoup流媒体服务器是由NodeJS和 MediaSoup(C++) 两部分组成。其中,NodeJS负责MediaSoup的信令接收与业务管理。MediaSoup(C++)负责媒体数据流的转发工作。
3.3.3 Medooze
Medooze使用C++和NodeJS语言实现。Medooze的整体架构与Mediasoup类似,不过它的信令处理、业务管理以及媒体数据的转发功能都是放在NodeJS下进行统一管理的。
Medooze的业务功能要比MediaSoup强大,像服务端录制、推流这些MediaSoup没有的功能它都支持。但它性能没有Mediasoup好,因为Medooze的底层使用的poll来处理I/O事件,poll与epoll性能差距大。除此之外,Medooze的业务逻辑也没有MediaSoup简洁;另外与 Janus 相比,它的业务管理不如Janus灵活,Janus的插件管理方式显然要优于Medooze和MediaSoup。
Medooze架构如图九所示。
3.3.4 Licode
Licode是由C++和NodeJS语言实现。既可以用作SFU类型的流媒体服务器,也可以用作MCU类型的流媒体服务器。Licode不仅仅是一个流媒体通信服务器,而且还是一个包括了媒体通信层、业务层、用户管理以及客户端 SDK 等功能的完整系统,并且该系统还支持分布式部署。
Licode架构如图十所示。其中,媒体通信部分由C++语言实现,而信令控制、用户管理、房间管理用NodeJS实现。Licode从功能层面来讲分成三部分,即Nuve、ErizoController和ErizoAgent三部分,它们之间通过消息队列进行通信。
- Nuve: 是一个Web服务,用于管理用户、房间、产生token以及房间的均衡负载等相关业务工作。它使用MangoDB存储房间和token信息,但不存储用户信息。
- ErizoController:用于管理控制,信令和非音视频数据都通过它接收。它通过消息队列与Nuve进行通信,也就是说Nuve可以通过消息队列对 ErizoController 进行控制。
- ErizoAgent:用于音视频流媒体数据的传输,可以分布式布署。ErizoAgent与ErizoController的通信也是通过消息队列,信令消息通过ErizoController接收到后,再通过消息队列发给ErizoAgent,从而实现对ErizoAgent进行控制。
3.3.5 Kurento
Kurento使用C++开发,有丰富的文档和示例。Kurento是真正完整的多功能媒体服务器,不仅提供媒体服务器功能,还提供其它很多工具(人脸识别,二维码接口,对象追踪等)。
Kurento架构如图十一所示。
3.3.6 Jitsi
Jitsi是使用Java构建的服务端,底层也是使用C/C++。Jitsi是比较活跃的开源视频会议平台,是一个处理XMPP(前身是Jabber)信号流的SFU,适用于SIP/XMPP视频通话、会议、聊天、桌面共享、文件传输。
Jisti核心组件如图十二所示。
- Jitsi Video-Bridge:一个XMPP服务器组件,充当媒体服务器,用来在单一的服务器下运行数千个视频流,并且该组件是完全开源的并兼容WebRTC。Jitsi Video-Bridge是Jitsi的核心,将所有人的视频和音频传递给所有参与者,而不是先将它们混合在一起,结果就是延迟更低,质量更好。Jitsi-Video-Bridge 用于处理视频传输,也就是视频流在各参与者之间的转发。如果没有这个组件,各参与者能文字聊天,但无法互相看见。
- Jitsi Meet :通过Jitsi Video-Bridge从而可以提供高质量、可伸缩的视频会议。该组件提供嵌入了WebRTC功能的JavaScript应用程序。一旦应用程序开始执行,信号处理完毕,用户就可以通过Jicofo进行通信,因为Jicofo负责信号处理和视频桥接的中继。Jitsi Meet是建立在Lib-Jitsi之上的,Lib-Jitsi提供了对许多其他API的全面访问,这些API可以让用户对视频会议有更多的控制。主要职责: 创建一个XMPP信令层、初始化与对等点的连接、接收媒体/消息和文件。
- Jibri(Jitsi BRoadcasting Infrastructure):提供一个记录和流式传输一个Jitsi Meet会议的服务。它的工作原理是启动一个在虚拟framebuffer中渲染的Chrome实例,然后用FFmpeg捕获并编码输出。它将在单独的机器上运行,一个Jibri服务只能同时录制一次视频会议,如果在其它会议室正在录制的同时再开户新录制,将返回没有可用设备或设备忙(考虑Jibri池)。可以采用客户端录制,但很消耗CPU导致卡顿。备注:使用之前需要先设置ALSA loopback设备(仅支持Linux)。
- Jicofo(Jitsi Conference Focus):Jitsi Meet中使用的服务器端焦点组件。即一种代理,负责确保一个参与者发送的媒体被分发给会议的所有其他参与者,以便每个人都能有效地听到或看到其他人。它是管理所有正在进行的会议的主要协调实体。当会议开始时,就会创建一个房间,任何知道该房间名称的人都可以进入该房间。
- Jigasi(Jitsi Gateway to SIP):一个链接的服务器端应用程序,允许常规SIP客户端加入Jitsi Video-Bridge主持的Jitsi Meet会议。
- Prosody:XMPP Server,可用做信令(Signalling)服务器。
- XMPP MUC(Multi User Chat):基于XMPP的群聊协议。
- Colibri (Conferences with Lightweight Bridging):定义了一个XMPP扩展,允许实时通信客户端发现并与提供会议混合/中继功能的会议桥进行交互。
- SIP(Session Initiation Protocol,会话初始协议):一个基于文本的应用层控制协议,用于创建、修改和释放一个或多个参与者的会话。SIP 是一种源于互联网的IP语音会话控制协议。
- IRC(Internet Relay Chat,因特网中继聊天):RC用户使用特定的用户端聊天软件连接到IRC服务器,通过服务器中继与其他连接到这一服务器上的用户交流。
- Etherpad:一个实时共享与协作的字处理软件。可以邀请一个或多个人访问文档,并在每个人进行添加和编辑时进行观察。
- Jidesha:桌面共享需要用到的插件(Firefox/Chrome),配置较复杂。或者也可以直接采用收费的插件:Jitsi Desktop Sreamer(Chrome)。
- UPnP(Universal Plug and Play,通用即插即用) ,该协议的目标是使家庭网络(数据共享、通信和娱乐)和公司网络中的各种设备能够相互无缝连接,并简化相关网络的实现。UPnP体系允许PC间的点对点连接、网际互连和无线设备。它是一种基于TCP/IP、UDP和HTTP的分布式、开放体系。
- 缺点:Jitsi用的是SIP和XMPP,编译部署过程过于复杂,依赖库较多,且文档比较少。
Jisti分布式部署示例(单Jitsi-Meet, 多Video-Bridges),如图十三所示。
Jitsi SDK
- Lib-Jitsi-Meet:JavaScript接口SDK,将Jitsi Meet模块嵌入到自己的应用程序中,用于Web客户端的开发。
https://github.com/jitsi/lib-jitsi-meet
- Lib-Jitsi:Java接口SDK。用于安全地实时地音视频交流,用于服务器端开发。
https://github.com/jitsi/libjitsi
- Android/iOS SDK:https://github.com/jitsi/jitsi-meet-sdk-samples
3.4 小结
对流媒体服务器的选择,没有最好,只有最合适。每个开源实现都有其各自的特点,需要根据自身特点以及项目特点选一个最合适的。
- Licode是一个完整的系统,支持分布式集群部署。系统相对复杂,学习周期要长一些。它可以直接布署在生产环境,但是二次开发的灵活性不够。
- Janus是一个独立的服务,支持的信令协议很丰富,而且支持插件开发,易扩展,对于Linux/C背景的开发者是很不错的选择。如果要做的业务种类比较多,变化比较快,建议选择使用Janus作为流媒体服务器。将你的业务做成一个插件放到Janus上很快就能实现你们的业务需求。架构较复杂,不太适合初学者。
- Medooze和MediaSoup都是流媒体服务器库,对于需要将流媒体服务器集成到自己产品中的开发者来说,应该选择它们。如果团队能力比较强,可以做底层开发,那么建议使用MediaSoup。因为MediaSoup不关心应用层,它关注的是底层数据如何高效的流转,代码简洁、高效,性能极佳。如果业务变化不大,除了追求性能外,还需要录制、推流之类的功能,那么可以选择使用Medooze,它可以很好的满足你们的需求。
- Kurento是一个媒体服务框架,可以构建任何类型的后端媒体处理功能:SFU、MCU、Recording、Transcoding、Gateway等。如果你的需求比较复杂,需要做很多集成,那么最好还是使用Kurento。
- 如果擅长Java,并且只是需要单纯的XMPP信号流的SFU,那么建议使用Jitsi。
四、Jitsi架构
4.1 网络拓扑
如图十四所示。分为二类用户接入:WebRTC和SIP。其中,Web Server可以理解为Nginx + Jitsi Meet。
4.2 技术架构
如图十五所示。可分为访问层、应用层和媒体层。
- 访问层(Access Layer):接入端。例如:Web浏览器。
- 应用层(Application Layer):内含Jitsi重要组件。例如:Jicofo提供基本信令服务、负载均衡等;Jirecon和Jipopro是负责录制视频相关的功能。
- 媒体层(Media Layer):Jitsi Video-Bridge负责中继视频流,是一个选择性转发单元(SFU)。
备注:FreeSwitch是一个开源的电话交换平台,类似一个背靠背的用户代理,用来帮助通信的双方进行实时的语音视频通信。FreeSwitch支持多种通讯技术标准,包括SIP、H.323、IAX2以及GoogleTalk,可以方便的与其他开源的PBX系统进行对接,可以用作交换机引擎、PBX、多媒体网关以及多媒体服务器等。
4.3 事件交互
一个简单示例,如图十六所示。
4.4 分布式方案
如图十七所示。一种示例方案,多区域分布式部署(美国东部/西部、欧洲中部/西部、亚太区域)。
五、Jitsi部署
Jitsi官方开源子项目有100多个,必备项目有5个:Prosody、Jitsi-Meet、Jicofo、Jitsi-Video-Bridge(jvb)、Turn Server。
官方文档提供三种部署方式,具体安装过程请参见官网示例。
1) 快速安装(即打包安装)。
2) 基于Docker的安装。
3) 手工安装(即依次逐个安装)。
注意事项
- 经安装测试,Windows环境下采用Docker容器方式,需要安装Hyper-V,Win10家庭版会遇到一些问题(例如:没有Hyper-V,容器启动不了等)。
- Windows环境下采用VMWare虚拟机安装Debian/Ubuntu的方式,则需要禁用Hyper-V;
- 先修改Linux默认来源地址(例如:Debian下的/etc/apt/sources.list)到国内镜像地址(例如:清华/阿里)。
- 可切换到root权限(终端输入:sudo -i),再按官网步骤安装。
- 终端输入:sudo nautilus,将以界面方式打开root文件夹。