点击上方“
LiveVideoStack”关注我们
▲扫描图中二维码或点击阅读原文
了解音视频技术大会更多信息
编者按:自从新冠疫情爆发以来,大家经常需要居家工作和线上开会,因此音视频会议软件变得越来越重要。LiveVideoStack Meet青岛站邀请到了易软天创的李文睿老师,为我们介绍在喧喧这款聊天软件中,从无到有的视频会议之路。
文/李文睿
整理/LiveVideoStack
大家好!我是李文睿,来自青岛易软天创网络科技有限公司。我所在的小团队大概有3人,该团队是禅道团队中负责研发喧喧聊天软件的小组。
今天,我分享的主题是:在喧喧这款聊天软件中,从无到有的视频会议之路。
1.1 单机可运行、轻量、跨平台、私有部署
首先,介绍我们的企业聊天软件——喧喧。喧喧是一款单机可运行的、轻量的、跨平台的、私有部署的聊天软件。之所以说喧喧是单机可运行的、轻量的、私有部署的软件,是因为喧喧的整体架构足够轻,可以私有部署到用户的单台服务器上。
接下来,介绍一下喧喧的功能。由于喧喧是企业协同聊天软件,所以我们把精力更多地放在了针对企业和协同场景的功能开发上。首先,喧喧具有音视频聊天、桌面共享的功能,还支持移动客户端和万人级别的聊天。其次,卡片消息功能能够让用户处理由第三方或自身推送的流程事务。同时,右键菜单功能可将消息转为禅道需求、bug或第三方系统中的数据。此外,喧喧还有一套扩展机制,第三方开发者可以通过扩展机制为喧喧定义新的功能、嵌入web应用等。喧喧还有单点登录功能。
喧喧还有内置Web应用的功能,可使用WebHook向用户发送通知消息,并支持Office等格式的文件预览。之前提到,喧喧支持各种芯片架构,即可在ARM、MIPS、X86、X86-64架构服务器上稳定运行。喧喧还有LDAP和登录IP限制的功能,这两个功能都是企业办公场景下的刚需。此外,喧喧还有加密存储文件的功能。由于截图也是聊天软件中的重要功能之一,我们还为喧喧开发了一款炫酷的截图工具——ZenShot,该工具已在GitHub上开源。
接下来,介绍喧喧的架构。架构主要分为三大块,第一块是后端处理服务器,其使用PHP实现,这是因为我们团队中的程序员大多是使用世界上最好语言PHP的程序员,并且我们需要将喧喧集成到其他产品中,而其他产品也使用PHP实现。但PHP也有短板,喧喧作为一个聊天软件,需要维持与客户端的连接,但在维持连接的场景下,PHP的性能不高,且处理起来比较麻烦。为了解决这个问题,我们做了一个消息中转服务器,以达到维持连接和提升服务性能的目的。消息中转服务器使用Go和Go的WebSocket库gorilla实现,保证了服务器和客户端间的连接。最后是客户端,客户端是全平台的,支持Mac、Windows、Linux等平台。移动客户端也可跨平台,支持Android和iOS。另外只要有浏览器,也可以使用喧喧的网页端。
1.2 Electron
为什么喧喧能够做到全平台兼容呢?是因为我们使用了Electron。Electron的前身是GitHub旗下的编辑器Atom的GUI框架。虽然Atom编辑器已经寿终正寝,但Electron却可以说是如日中天。
大家的电脑上可能已经有好几个Electron,比如著名的编辑器VS Code,这是用Electron实现的。此外,交互设计工具Figma、Markdown编辑器Typora和Evernote的桌面端也都是用Electron实现的。
甚至还有人使用Electron运行完整的Windows 95操作系统,这个项目十分有意思,可在GitHub上找到。由此可以看出,Electron确实十分强大。
图中的是从Electron官网摘抄的一句话:Electron允许使用Web技术构建跨平台的桌面应用。这是因为Electron可以理解为一个Chrome浏览器,Chrome通常代表了最新的Web标准,所以Electron可以使用大多数的新的Web API和Web技术。此外,Electron还进行了系统API的集成,开发时仅需使用JS进行调用,对开发人员十分友好,无需操心各系统下的平台差异性。当然,Electron也有短板,Electron可以认为是一个Chrome,Chrome的内存消耗很大,使用Electron的软件的体积通常会达到至少一百兆。但是,Electron的好处也是明显的,我们可以使用Web技术开发各种桌面应用,一个前端工程师也可以用其做一个桌面应用。因此,如果大家需要开发新的桌面应用,我会推荐Electron。
1.3 “Dirty Hack”
然后,还想跟大家分享一些有点hack的有趣的细节。
后端服务器和消息中转服务器以及消息中转服务器和客户端之间的数据传递方式是有趣的,我称之为HTTP Over WebSocket,即经由WebSocket转发的HTTP协议通信。客户端通过WebSocket向消息中转服务器发送消息请求,该消息请求会原封不动地POST给后端服务器,得到回复后,再分发给需要被通知的客户端。这样就实现了基于PHP后端的高性能的WebSocket服务。
我们的数据使用JSON传输,JSON是一个较低效的文本数据交换格式。虽然JSON方便使用,但是每次传输的体积较大,比如这一串JSON里有效的数据量大概只占了三分之一。为了优化数据传输,我们研究了一套JSON的压缩机制。我们先定义了接口的数据格式和默认值,然后做了字典,用索引代替已知的长字符串。通过这种方法,我们将图中上半部分的JSON压缩成了图中下半部分的JSON,缩小了大概一半的体积,并且编解码过程的效率较高。此外,我们还集成了RoadRunner(一款使用Go的协程来调度PHP程序的、高性能PHP应用服务器),还将其集成到了同样是Go实现的消息中转服务器中。这能极大地提升性能,帮助实现单服务器在万人级别的场景下的稳定运行。
2.1 为什么要做音视频
接下来进入正题,开始走音视频之路,谈谈我们为什么要做音视频。最初,我们是一群快乐的Zoom付费用户,Zoom在2019年前是方便使用的视频工具,公司每次需要与外地同事开会时,都会首选Zoom。再后来,由于网络环境的恶化和Zoom运营的态度转变,Zoom在中国的运营没有以前直接,出现了代理商,服务体验变差。再之后,新冠疫情爆发,2020年后,我们经常需要居家办公,为了解决每次线上开会体验不佳的问题,我们寻求了很多办法。我们首先在网上找了很多其他的视频软件,包括当时刚起步的腾讯会议,但最终没有找到满意的视频软件,所以本着一定要解决工作中的痛苦的精神,我们最后选择成为在聊天软件中做音视频的“痛苦的”开发者,开始做音视频。
2.2 集成Intel OWT
我们先在GitHub上找灵感,思考集成哪款音视频服务,最终找到了Intel的OWT音视频媒体服务器,并尝试集成这款服务。
OWT服务支持MCU和SFU两种模式,由于当时我们刚入门,所以直接选用了MCU模式。所谓MCU模式,就是服务器接收所有用户推送的媒体流并进行混流,将它们合并到一条流中,再分发给用户,这样每个用户只需推送一个流和拉一个流。这种模式对服务器的配置要求比较高,但是能够节约带宽资源。
在集成OWT时,我们花费了很多力气,折腾了差不多一周后,我们初步实现了音频会议的功能,但中间的过程非常痛苦。比如,OWT本身需要编译,在编译时我们需要拉取其他的代码,例如Google的WebRTC的代码,受限于网络,我们经常遇到构建失败的情况,最后不得不购买一台国外的服务器来专门编译OWT。此外,我们还发现将其分发给用户也是一件困难的事情,因为喧喧是一款私有部署的聊天软件,但让用户亲自部署OWT是不现实的,于是我们尝试将其Docker化,但OWT的运行环境较大,我们在去年才将其精简、压缩成了161兆大小。
这是刚做喧喧音频时音频功能的截图,当时花了一周的时间在内网中做了相关的尝试。
后来,我们很快实现了视频会议功能。这得益于MCU模式的特点,不需要担心视频布局问题,可以很轻松地实现推流和拉流,并由OWT做好一切内容。
2.3 屏幕共享和移动端
然后,我们还实现了屏幕共享功能和移动端的开发。屏幕共享功能和视频会议功能是同期实现的,屏幕共享功能中使用了MediaDevice之类的Web API,可以获取屏幕的视频流,并将其推送到服务端。在开发移动端时,我们则花费了较大的力气。
这是当时喧喧桌面共享功能的截图。
移动端使用Flutter实现,使用Flutter与使用Electron的目的一样,希望只编写一次代码就可在多个平台下同时运行。Flutter对RTC的支持是足够的,有很多第三方库辅助我们实现相关功能。我们一共花了两周多的时间,实现了移动端音视频。
2.4 集成SRS
后来,我们不断收到用户反馈,用户说不使用音视频服务时,该服务也会占用资源,而使用该服务时,资源占用很高、体积大,于是我们开始思考解决办法。我们发现,OWT使用了RabbitMQ和MongoDB,这二者在闲时也会占用资源,于是我们考虑更换音视频后端。最终我们决定使用SRS,SRS是一款国产的开源的音视频项目。
在迁移时,我们发现SRS仅支持SFU模式,于是需要从MCU模式切换到SFU模式,这样的改变会带来一些变化。首先是布局的变化,在SFU模式下,我们需要亲自排布视频并在客户端上呈现,而不由服务端进行排布,对此我们只需开发一些前端的功能,而这是容易实现的。但同时也存在一些问题,以后再跟大家详细介绍。
SRS的文档非常全面,在GitHub上面,其Wiki有797条。得益于详尽的文档和之前集成OWT的经验,我们很快地完成了SRS的迁移。
这是近期喧喧音视频的界面,我们将其做成了独立的窗口。
03 万能的WebRTC
WebRTC技术在飞速地发展,近期我们使用WebRTC实现了客户端之间点对点的大文件传输功能。具体地,通过使用WebRTC的DataChannel和PeerConnection直接传输大文件。由此看出,WebRTC的应用广泛,各大浏览器对WebRTC的支持也很全面。我们期待用WebRTC做更多的事情,比如桌面共享和控制、甚至元宇宙,当然,还要做更好的会议功能。
我今天的分享到此结束,谢谢大家!

▼识别二维码或猛戳下图订阅课程
喜欢我们的内容就点个“在看”吧!
继续阅读
阅读原文