双人视频通话

最近更新时间:2017-12-27 14:39:16

功能体验

在微信小程序中搜索 腾讯视频云 可以加载到我们的演示用小程序,其中 双人音视频 功能可用于体验基于 <live-pusher> 和 <live-player> 所构建的双人视频通话功能。

技术指标

  • 通讯延迟:300ms - 800ms
  • 底层协议:基于 UDP 协议构建,并遵循 RTMP 标准对音视频数据进行切分和封装,支持丢包恢复和网络自适应。
  • 安全加密:每次连接都独立启用一对全新的非对称加密密钥,整个通讯过程无法监听和篡改。
  • 支持录制:如果需要可以在云端进行录制,适用于在线客服、金融开户等商用音视频解决方案,支持私有化部署。

内部原理

解读:通讯的双方 A 和 B 各自创建一个 RTC 模式的 <live-pusher> 和 <live-player> 然后置换用于播放的低延时 URL 给对方。

流程解读

  • step1:A 跟业务服务器沟通,获取 push-url-A 和低延时的 play-url-A,服务器分配 URL 的方法参考 DOC

  • step2:A 创建一个 RTC 模式的 <live-pusher> 标签,指定 url 为 step1 中获得的 push-url-A,并通过 bindstatechange 属性绑定一个 javascript 函数(比如叫 onPushEvent)。

  • step3:A 这边需要一些时间启动推流,推流开始以后,<live-pusher> 会通过 onPushEvent 的 PUSH_EVT_PUSH_BEGIN(1002)事件通知给 A, 此时 A 可以向 B 发起通话请求,请求中可以携带 play-url-A。

  • step4:B 需要等待 UI 界面上的确认,如果 B 确认接通,接下来要做的就是创建一个 RTC 模式的 <live-player>,并指定 src 为 play-url-A。

  • step5:B 此时还要跟业务服务器沟通,获取 push-url-B 和低延时的 play-url-B,并创建一个 RTC 模式的 <live-pusher> 标签,指定 url 为 push-url-B,并通过 bindstatechange 属性绑定一个 javascript 函数(比如叫 onPushEvent)。

  • step6:B 此时需要一些时间启动推流,推流开始以后,<live-pusher> 会通过 onPushEvent 的 PUSH_EVT_PUSH_BEGIN(1002)事件通知给 B,之后 B 可以向 A 响应通话请求,请求中可以携带 play-url-B。

  • step7: A 此时要做的就是创建一个 RTC 模式的 <live-player>,并指定 src 为 play-url-B。

真实场景

以上 7 个步骤虽然不难理解,但对于真正想要照此实现的您而言,显然也是个不小的工作量。在真实的场景中,我们需要面对的业务逻辑远比简单的把 A 和 B 连接起来要复杂。

  • 房间管理
    以金融开户和保险定损为例,如果 A 端使用的是小程序,那么真正的 B 端一般情况下会是企业的客服职员(通常都是一个人),所以这里就牵扯到要给用户分配客服的逻辑。同时,如果目前所有的客服都是忙碌的,那就需要有排队等待的逻辑。

    所以,真实场景下的逻辑是这样的: 客服 MM 在进入工作岗位后即创建好一个属于自己的“房间”,这个房间有三种状态:BUSY(占线)、IDLE(空闲) 以及 CLOSE(关闭)。处于 BUSY 状态的房间表示对应的客服正在跟用户进行沟通, IDLE 表示可以分配给新进来的呼叫,CLOSE 则表示客服 MM 已经下班了。

  • 消息系统
    在 A 和 B 之间搭建 IM 消息系统也是必不可少的,一方面,如果 A 和 B 中某一方网络发生异常,那么文本消息可以用极低的带宽占用维持最基本的消息通讯;另一方面,消息系统对于事件的传递要比音视频通道更加可靠。

    现代实时音视频系统一般都有数据通道和信令通道两个传输通道,这样设计的原因是音视频通道并不适合用于传输信令,比如 B 端的 <live-player> 通知音视频数据没有了,可能原因是 A 已经挂断,但也有可能是 A 的网络出现了长时间的波动。而基于消息系统的“挂断事件”则不需要考虑这种不确定性问题。

基于以上原因,我们推荐您参考 RTCRoom 方案,它是我们腾讯视频云团队基于 <live-pusher> 和 <live-player> 标签所实现的一套开源接入方案,支持它包含房间管理、消息系统 和 状态管理 等组成部分,而且支持 一键部署,非常适合用于参考和调试。