基于多服务商的直播方案

2,472 阅读4分钟

作者:贝聊 JAVA工程师 叶志伟

       程序员们的工作大部分都是被动实现产品经理需求,这里分享一次由程序员主动推动并实现需求的过程。
1. 需求背景
       看宝宝与明日之星是贝聊的视频直播产品,目前只是使用七牛一家的直播云服务。基本业务是通过摄像头设备或老师的手机直播,推流到七牛,家长通过H5的页面观看。业务流程图如下:

       可以明显发现:贝聊服务端和客户端都完全依赖七牛云的服务,万一七牛云出现故障,整个视频直播产品就瘫痪了!于是我们的需求就诞生了:接入另一家直播云服务商,提高服务可用性。如此一来,既可做为容灾,也可做流量切换。
2. 直播云服务商选择
       经过调研,我们锁定的备选服务商有腾讯云、阿里云、金山云、网易云。新的直播云服务商选择,不能拍脑袋决定。需要考虑各服务商的优缺点、成本以及是否能满足我们的功能要求等。总结主要有以下几点:
  • 客户端的限制:我们的贝聊老师版APP,安卓系统要求最低是版本4.0,而阿里云和网易云要求最低版本是4.3
  • 现有功能点的限制:产品已经上线,新的服务商应与七牛的功能相似,包括推拉流、鉴权、定时截图、状态回调通知、保存回放等
  • 成本的问题:腾讯云成本最高,阿里云和金山云相对较低
       由于客户端的限制,备选服务商基本锁定在腾讯云和金山云。既然是作为备用,成本就是次要因素了,稳定可靠才是我们的核心关注点。因此,我们最终选择了腾讯云作为备选直播服务商。
3. 实现过程
       接入一家新的直播云服务商,业务流程图调整如下:

3.1 业务变化
  1. 后台增加操作功能,可切换服务商和客户端使用的SDK。目前只有人工切换服务商,后续可以加入系统检测报警机制,并自动进行切换。但若完全靠系统自动切换,会有误报风险。
  2. 直播是以节目为单位,在创建节目时增加一个字段标识使用哪个服务商。后续一切操作,例如:生成推流地址、拉流地址、截图、保存回放都调用这个服务商的接口。
  3. 推流地址是服务器生成并签名后返回给客户端,客户端无需关心使用的服务商,只需关心使用哪个SDK。优先使用腾讯云SDK,由于无法保证其稳定性,所以前期同时接入七牛云和腾讯云的SDK,由后台配置各自使用比例。
  4. 增加对腾讯云回调通知的处理
  5. 包括推流状态回调、截图回调、生成录制文件回调。一个节目有一个流空间,七牛云和腾讯云的流空间是全局唯一的,所以不管是七牛云还是腾讯云的每个回调都能准确的找到对应的节目。
  6. 生成回放的方式完全不同。七牛云是在直播结束时调用接口生成的,而腾讯云是在推流地址后加参数&record=mp4&record_interval=5400,然后接收回调。腾讯云还可以配置全局的推流自动保存。
  7. 腾讯云区分生产环境和测试环境。腾讯云的回调通知是全局配置的,无法区分环境,使用多个账号又增加成本,于是把回调通知都配置成生产环境的,调用异步处理接口时把taskId存到数据库,生产环境找不到则转发到测试环境。
3.2 代码结构变化

       最初只接入一家服务商,代码结构比较简单。如今,为了避免有重复代码,过多使用if、else,所以使用了简单工厂模式。业务代码统一调用工厂类VideoTV3rdLiveServiceFactory,七牛云和腾讯云各写了一套业务代码,分别是VideoTVQcloudLiveService和VideoTVQiniuLiveService,实现生成推流地址、获取拉流地址、保存回放等与业务相关的逻辑代码。QcloudService是对腾讯云API和SDK的封装,PiliService和StorageService是对七牛云SDK的封装。
4. 后续工作
  1. 实现系统故障检测报警。系统定时尝试推流,如果失败累计达到n次后发送邮件、短信报警。
  2. 有新的业务需求需要实现两套,分别对接七牛云和腾讯云。