技术实践 | 场景导向的音视频通话体验优化
在现代生活中,音视频通话是我们最常使用的沟通方式之一。比如,社交中的一对一音视频,医疗中的远程问诊咨询,房产交易中的线上看房,以及远程工作场景下随时随地可能发生的一对一和群组音视频沟通。*本文转自公众号【融云全球互联网通信云】,回复 抽奖 获福利。
而我们在使用中也多少感受过产品逻辑的“卡壳”,比如音视频无法自由切换、1V1 不能升级群聊、退出群视频无法随时加入等等。
6 月 16 日,融云 RTC · 进阶实战高手课聚焦音视频通话,从音视频通话实现、多场景体验痛点和融云 New CallLib 的最佳实践等方面,拆解音视频通话在多种使用场景下面临的体验挑战,分享优化方案。后台回复【通话】获取完整课件
音视频通话实现
我们通常说的音视频通话,指类似微信等必须含有呼叫流程的应用场景。有一个主叫和一个或多个被叫,主叫发起通话,被叫可以选择接听或者挂断。
音视频通话的使用场景非常多,特别是当我们正在经历一场大型数字化转型时。
比如,远程问诊,医生可以通过音视频通话对患者进行沟通从而方便诊断;VR 看房,房产中介通过音视频通话和租客进行沟通,结合 VR 实现远程看房;线上相亲,红娘可以通过群聊让相亲对象交流,这是一个群组的音视频通话使用场景。
(音视频通话使用场景)
音视频通话出现在我们线上生活的方方面面,也是各类应用的必要能力。那么,如何实现一个音视频通话呢?
从需要掌握的基本知识方面来看,大体分三个部分,音视频、网络传输和服务器。
这是一个非常复杂的系统,这里只做大概描述。
(RTC 基本知识)
音视频
音视频的基础知识:音视频的采集,不同的平台采集方法有所不同。开发者需要掌握元数据的基本知识,也就是我们通过采集直接得到的数据格式。
音视频数据的处理:要掌握音频降噪、音频的回音消除、图像的裁剪等。
音视频的编解码:至少要掌握一种音频编码和一种视频编码。
编码格式有对应的解码器,比较通用的编码格式还可以使用硬件解码,可根据解决方案的不同选择软解还是硬解。软解的兼容性高,但会损耗 CPU 性能,硬解性能好,但可能面对一些兼容性问题。
音视频的播放和渲染也是必须掌握的,通常播放和渲染指的是对元数据的播放和渲染,音频其实就是 PCM 的播放,视频如果是客户端会用到 OpenGL,浏览器需要用到 WebGL 等。
网络传输
客户端可以选择 TCP 或 UDP,通常音视频使用 UDP 传输,这是因为音视频数据要求的是实时性,而不是完整性,音视频的数据即使不完整也可以正常播放。
TCP 和 QUIC 都是可靠性传输协议,类似业务信令数据等要求完整性的更多使用 TCP 或者 QUIC。
QUIC 协议是建立在 UDP 协议上的一种保证完整性的协议。UDP 本身是不可靠协议,如果要保证完整性就需要自己做丢包重传策略,而 QUIC 是具有丢包重传策略的一套数据协议,可以达到与 TCP 同样的效果。
服务器
通常分为信令服务器和音视频服务器。顾名思义,信令服务器负责传输业务相关数据,音视频服务器负责传输音视频数据。不同的技术方案对应实现服务器的技术也会有所不同。
利用以上基本知识,我们可以完成音视频通话场景的核心逻辑了。在考虑和呼叫场景强相关的业务处理之前,要先解决以下两个问题。
首先是业务数据的即时传输。要发起一个通话,要有主叫端、被叫端两个客户端。
被叫端如何收到主叫端发送的发起信令?可以使用 Push+长链接的形式,或者第三方提供的 IM SDK 来实现。
接下来是更关键的音视频基础能力,以及音视频数据的实时传输能力。
开发者如若自研,可以选择 WebRTC,这是 Google 提供的一套具有音视频基础能力及传输能力的完整开源方案;或者可以从头自研一套完整的 RTC 系统。
当然,不管是选择哪种自研方案,都有非常复杂的底层知识需要学习,需要有相当的研发能力和人员配备。
融云为开发者提供了另一个更加便捷的实现方案,融云 CallLib。
针对音视频呼叫场景,融云将 IM 和 RTC 能力融合封装,提供了包含完整呼叫流程的 SDK。开发者只需要关心 CallLib 提供的少量接口,即可实现呼叫需求,同时具备以下优势。
完整性,呼叫流程完整,支持单人、多人呼叫,开发者不需要关心底层实现原理。
易用性,开箱即用,快速实现,灵活定制。
稳定性,IM 消息 100% 可靠到达,RTC 音频抗丢包 80%,视频抗丢包 60%。
场景的多样性,扩展性强,可以满足多领域对音视频呼叫的需求。
基于融云 CallLib,开发者可以快速实现具有呼叫功能的 App,而针对开篇我们说到的使用场景卡壳情况,我们还对产品进行了针对性升级优化。
多场景通话体验优化需求
呼叫的升级
音视频的升降级:用户在打音频通话时可以直接切换为视频通话。
1V1 升级为群聊:从 1V1 单聊直接变为多人讨论群聊。
随时加入未结束的通话:当群组通话时,若用户当下未立即接入,只要通话还没有结束,就可以选择加入。
流控制的升级
自由的音视频流发布 API;多个通话实现预览;选择接听以及呼叫等待。
主要优化流控制的 API,让开发者便捷使用的同时可以根据自己的需求开发出一些高阶功能。
数据一致性的升级
包括通话计时的一致性、参与者状态同步一致性以及极端场景下,操作业务逻辑的一致性。
数据一致性的升级主要是为了给所有参与音视频通话的用户,特别是通过不同端接入通话的用户带来更加一致的体验,也方便后期的业务扩展。
那么,如何实现这些优化和升级呢?
融云 CallLib 基于 IMLib 和 RTCLib 实现,是一个重客户端的设计。
所有的状态和业务逻辑需要存储在客户端,增加了客户端的实现复杂度,业务逻辑要在每个端进行重复实现,也会导致极端情况下状态不一致。
比如主叫和被叫同时点击挂断。主叫挂断叫取消,被叫挂断叫拒绝,体现在通话记录上是不同的。而如果主叫和被叫同时挂断,由于这个操作都是从客户端发出和处理的,无法分辨到底是谁先做的操作,导致通话记录不准确。
这个问题其实是可以处理的,但会很复杂,因为重客户端的设计很难实现功能的扩展。
融云 New CallLib 实践
融云 New CallLib 可以优雅地解决上述问题。
升级业务处理能力:重服务端,轻客户端的设计。
原有的 CallLib 负责维护的状态,改为在服务端维护和保存;
CallLib 转变为了由 Server 驱动的状态机模型;
大大简化了客户端的实现复杂度,并可以避免多端逻辑实现不一致的问题。
因为状态变更都是由服务端发出,也就保证了状态的一致性,在处理极端场景和在线离线状态方面也游刃有余。
比如上面说到的两端同时做出挂断操作,一定有一个操作先到达服务器,然后服务器进行状态的下发,更加有序。通话记录的生成也是由服务器完成,就不会造成两端状态不一致的情况。
下面结合具体场景看一下,新的设计如何做到体验再升级。
1V1 音视频通话呼叫流程
这是我们最基本的通话功能,右侧是这个基础能力的完整时序图,由 4 个角色共同完成,Client A、Client B 分别代表主叫端和被叫端,Call Server 处理呼叫相关的业务逻辑,RTC Server 处理音视频的通话。
从图中可以看出,这个基础能力的流程实现起来其实非常复杂。
音视频的升降级
相信很多人有过这样的体验,当你在一个语音通话过程中因为一些原因需要开启摄像头,要先挂断音频通话重新发起视频。
融云对这样的场景做了优化实现,让这个场景下用户使用更加便捷,当我需要临时将音频通话升级为视频通话时可以在通话内发起一次升级请求。
被发起端可以选择接受或拒绝,如果接收了就升级为视频通话,拒绝就继续音频通话。当然发起端也可以选择取消升级。
这个场景下,也可能出现一些极端操作,比如发起端的取消操作和被发起端的接受同时点击,这时 CallServer 会起到一个决策的作用,比如我们以取消为准,只要操作了取消,即使被发起端点击接受依然会让两端都降级为音频通话。
而在此前的重客户端设计中,这个判断会变得非常复杂。
通话中来电
在我们常见的音视频通话场景中,如果被呼叫用户正在进行语音或视频通话,通常会显示对方繁忙,需等待他挂断。
类比电话场景,通话中的我们可能会收到第三个人的来电,此时运营商电话有选择接听和呼叫等待的功能,也就是说我们同时可以处理两个电话。
针对这个场景,融云的 CallServer 存储了每个电话的状态,所以即使已经在通话中了依然具备处理其他通话的能力。
群聊呼叫流程
群聊和单聊的区别在于两点,一是参与者可能为两人或以上,二是只要通话中还有一个人,通话就未结束。
所以群聊通话只要发起,发起人就第一时间进入了 RTC 房间,等待其他人加入。
另一个比较特殊点在于,过程中可以随时邀请他人加入房间,流程和发起非常类似。
在我们常用的通信软件中,群聊只能发生在某个群组里,而融云服务可以支持随时随地从不同的群组或者私人通讯录中做发起和邀请的操作。
1V1 升级群聊
这个场景发生在两人正在通话的过程中,有可能临时发现这个沟通需要其他人参与,融云支持将一个 1V1 通话直接升级为一个群通话。
升级的过程和群通话过程中邀请他人的过程类似,不同的是在升级为群聊的时候,Call Server 会明确告诉 1V1 的参与双方当前通话已经变为一个群通话了。
升级成功后的后续流程和群聊是一样的。
未结束通话的随时加入
这也是一个常见情况——收到群通话时不方便接听,或接听一段时间后临时有事需要离开一下。
群通话只要有一人在就不会结束,所以暂时未参与群聊的用户,可以选择在结束前的任意时间再次加入通话。
这是一个特别实用的优化,尤其是在我们现在越来越多的线上办公和沟通的场景中,临时有事要离开,后面又需要加入沟通继续之前的讨论。这也得益于 Call Server 对通话状态的保存,让客户端可以随时获取未加入通话的状态。
通话记录实现
此前,我们的通话记录存储在本地,想要做到多端同步其实很困难。
现在可以做到通话记录的更新删除,甚至通话记录的未读计数都可以多端同步,给使用者带来更加合理和统一的体验。
体验优化是一个长期话题,而音视频通话属于既十分常用又极其复杂的功能。融云基于多年通信行业深厚技术积累,将持续优化体验到细枝末节,消灭使用中的“卡壳”,为开发者提供更便捷和契合用户使用习惯的解决方案。
评论