-
Notifications
You must be signed in to change notification settings - Fork 33
实时音视频
RTC(Real time communication)实时通信,是实时音视频的一个简称,它最大的特点就是低延时和无卡顿,一般都可以达到毫秒级延迟。在房间场景有大量应用,比如聊天室麦上主持聊天、游戏开黑房语音交流、直播间连麦、在线K歌等。
要实现一套实时音视频服务的搭建还是比较困难的,虽然 RTC 发展了很多年,但是音视频的技术门槛高,涉及到的传输协议多且复杂,如果采用纯自建的方式,成本会有点大,所以一般都会购买外部云商的服务来实现。
SONA 中使用的是 即构和腾讯云的TRTC ,所有对接云商的工作都集成了,只需要配置相关的云商 appid 和 秘钥、域名等,不需要额外工作。并且可以支持热切,在不同云商之间进行切换,万一某一个云商出现故障,可以瞬间切换到其他云商。 如果需要对接其他的外部云商,也可以非常简单的集成进来。
比心内部也自研了一套 WebRTC 服务,叫做 Starlink,基于 mediasoup 二次开发。使用mercury长连网关做rtc信令传输,并集成进 sona 中,提供和外部云商同等的功能,目前在一些小流量场景使用,后续功能完善后,也会考虑开源出来
在 t_product_config 和 t_room_config 配置表中有几个 音视频相关的配置字段
- stream_supplier 流供应商(TENCENT/ZEGO)
- type 流类型 AUDIO=音频 VIDEO=视频
- push_mode 推流模式
- pull_mode 拉流模式(MULTI,MIXED)
- need_replay 是否需要流录制
- bitrate 播放器码率
在 sona-service 的 apollo 上添加 即构和 TRTC 相关的配置 apollo
每个房间都可以指定外部云商, 推/拉流的方式, 播放器类型, 码率等. 也可以按照房间ID进行特殊配置, 该配置在APP调用 sona/enter
接口的时候会返回给APP端进行使用。
麦上用户(主播)使用 RTC 推拉流,即构会将所有流转推给 CDN,麦下用户(观众)通过 rtmp 从 CDN 拉流
腾讯云的 TRTC 和 即构类似
可以通过房间配置,指定观众采用拉CDN单流还是CDN混流
云商会提供相应的回调,包括 推流回调、关流回调、录制回调、混流回调等
所有流记录都存储在 t_room_stream 表中,方便后续审查做内容回溯
CREATE TABLE `t_room_stream` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`stream_id` varchar(255) NOT NULL COMMENT '流ID',
`product_code` varchar(16) NOT NULL DEFAULT '' COMMENT '产品码',
`room_id` bigint(32) NOT NULL DEFAULT '0' COMMENT '房间ID',
`biz_room_id` varchar(512) DEFAULT NULL,
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1:打开 0:关闭 -1:未开始',
`uid` bigint(32) NOT NULL DEFAULT '0' COMMENT '用户UID',
`source` int(2) NOT NULL DEFAULT '1' COMMENT '来源 1:zego 2:tecent',
`rtmp_url` varchar(1023) NOT NULL DEFAULT '' COMMENT 'rtmp_url',
`hls_url` varchar(1023) NOT NULL DEFAULT '' COMMENT 'hls_url',
`hdl_url` varchar(1023) NOT NULL DEFAULT '' COMMENT 'hdl_url',
`pic_url` varchar(255) NOT NULL DEFAULT '' COMMENT 'pic_url',
`replay_url` varchar(255) NOT NULL DEFAULT '' COMMENT 'replay_url',
`begin_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '开始时间',
`close_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '关闭时间',
`end_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '结束时间',
`close_type` int(2) NOT NULL DEFAULT '-1' COMMENT '0-正常关闭 1-后台超时关闭 2-同一主播直播关闭之前 没有关闭的流',
`err_msg` varchar(256) NOT NULL DEFAULT '' COMMENT '错误描述',
`ext` varchar(1024) NOT NULL DEFAULT '' COMMENT '扩展信息',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `unq_stream_id` (`stream_id`),
KEY `idx_room_id_status_uid` (`room_id`,`status`,`uid`),
KEY `idx_room_id_status_source` (`room_id`,`status`,`source`),
KEY `idx_uid_status` (`uid`,`status`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='sona音视频流记录表';
ZEGO 控制台配置回调地址
- 即构推流回调 https://domain/zego/create
- 即构关流回调 https://domain/zego/close
- 即构录制文件回调 https://domain/zego/replay
TRTC 控制台配置回调地址
- TRTC推流回调 https://domain/tencent/create
- TRTC关流回调 https://domain/tencent/close
- TRTC录制文件回调 https://domain/tencent/replay
云商回调的处理都在 sona-service 中的 cn.bixin.sona.api.room.SonaStreamCallbackRemoteService
public interface SonaStreamCallbackRemoteService {
/**
* 处理创建回调
*/
Response<Boolean> handleCreateStreamCallback(CreateStreamCallback request);
/**
* 处理关闭流回调
*
* @param callback: {@link CloseStreamCallback}
* @return: true success, otherwise false
*/
Response<Boolean> handleCloseStreamCallback(CloseStreamCallback callback);
/**
* 处理回放回调
*
* @param callback: {@link CreateReplayCallback}
* @return: true success, otherwise false
*/
Response<Boolean> handleCreateReplayCallback(CreateReplayCallback callback);
/**
* 处理混流开始回调
*
* @param callback: {@link CloseStreamCallback}
* @return: true success, otherwise false
*/
Response<Boolean> handleMixStreamStartCallback(MixStreamStartCallback callback);
/**
* 处理混流结束回调
*
* @param callback: {@link CreateReplayCallback}
* @return: true success, otherwise false
*/
Response<Boolean> handleMixStreamEndCallback(MixStreamEndCallback callback);
}
如果想要增加其他云商,可以按照下述步骤:
- 在 sona-web 里面添加对应云商的回调接口,封装参数调用 SonaStreamCallbackRemoteService 对应的方法,可以参考
ZegoController
和TencentController
- 继承 cn.bixin.sona.server.room.strategy.stream.DefaultStrategy,实现新云商相关的逻辑处理
- 在房间配置表里设置 stream_supplier 为新的云商name
- 在 sona/enter 接口中返回新云商的配置,比如 appid、secret等
如果当前房间配置了混流模式,sona 服务端会基于云商的推流回调,然后调用云商的发起混流接口,这样观众就可以通过sona/enter
获取到后端下发的 streamUrl 从CDN拉取混流了
针对于混流时调用Zego API(外网调用)可能会受到网络的波动而造成一些异常情况, 例如: 发起混流请求过频, 混流接口超时, 混流失败等.
所以必须有一些可降级的措施, 目前降级的措施为: 通过捕捉Zego返回码判断混流失败的原因, 在重试一定次数后如果还失败, 将会调用热切服务, 将混流配置(MIXED)修改为单流(MULTI), 并通过房间消息同步给各个客户端
云商服务有时候也会出现故障,sona 提供了 热切操作来规避这种风险,可以同云商之间 单流-混流 的切换,也可以不同云商之间的切换。
在sona 后台管理系统中提供了 云商热切 页面,可以在页面上进行操作,根据 roomId 进行切换 sona-admin
热切的实现也比较简单,调用热切接口之后,会先更新 房间配置信息,然后判断当前房间是否有在线用户,有的话就通过房间消息推送给当前房间内的所有用户,告知客户端配置切换。