直播业务集成及再开发

Author Avatar
XibHe 6月 12, 2021
  • 在其它设备中阅读本文章

在项目中集成直播功能,提高运营端营销效率、下单转化率、增加营销方式并成为客户沉淀的重要手段。

直播技术点

视频直播,可以分为 采集,前处理,编码,传输,解码,渲染 这几个环节。

  • 推流端:采集、前处理、编码、推流
  • 服务端:转码、录制、截图、鉴黄
  • 观众端(播放器):拉流、解码、渲染
  • 互动:聊天室、礼物系统、点赞、弹幕等

直播技术点:

直播技术点

直播 App 架构:

直播App架构

业务流程(观众端)

观众端拉流播放功能,基于腾讯云直播基础版(Smart),基础版仅包含直播推流(TXLivePusher)和直播播放(TXLivePlayer)两项功能,对 App 的安装包体积增量最小,适合仅使用移动直播相关功能的客户。

直播间流程图

直播间主要包含四部分功能:

  • 直播拉流播放功能
  • 点播回放功能
  • IM 消息收发展示及处理特殊自定义消息
  • 不同直播状态 UI 样式之间切换及展示

交互流程

1. 首先需要在 AppDelegate 中对腾讯云直播 SDK 和 IM 进行初始配置

[TXLiveBase setLicenceURL:@"" key:@""];
  // 腾讯云 IM SDK 初始化
  V2TIMSDKConfig *config = [[V2TIMSDKConfig alloc] init];
  BOOL isinitSDK = [[V2TIMManager sharedInstance] initSDK: config:config listener:nil];
  NSLog(@"isinitSDK = %@", isinitSDK ? @"YES" : @"NO");

2. 通过首页 CMS 或短信链接或者微信分享的直播链接打开包含 roomId 信息的路由链接。直播间新增直播间对应路由 eg. XXX://activity/live?roomId=1234568

3. 进入直播间调用获取房间详情接口获取直播间信息,根据接口返回的直播状态决定是拉流播放还是点播回放,并展示不同状态的 UI 样式。目前共有101、103、106、108、110、115、206 等 7 种状态。通过返回字段 pullUrl 获取直播拉流地址,若直播状态为 101 则则直接进行拉流播放;否则,根据不同状态展示不同 UI 视图。

4. 已登录情况下,进入直播间三步走:

  • 调用接口 getUserSig 获取用户 Sig;
  • 拿着获取到的用户 Sig 登录 IM ;
  • 在 IM 登录成功后,调用加入直播间群组 API。

⚠️在以上三步成功走完后,就可以在直播间发送文本消息或者自定义点赞消息了。

交互流程图

直播后台推流及状态

推流状态

  • 103 暂停中(或异常): 若上一个状态为 106 待开播,则提示:主播正在赶来的路上,请稍候,否则,提示:主播暂时离开,请稍候。并展示“点击重试” 按钮。可以提过该按钮,触发重试拉流逻辑。

  • 106 待开播,该状态展示开播倒计时(开播时间戳为xxx分钟xxx秒、xxx秒触发倒计时)及展示“开播提醒”按钮,点击会调用订阅及提醒接口

  • 108 已结束,回放生成中,展示已结束提示:“直播已结束”、“回放生成中” 并触发商品弹窗(固定位置且不可关闭)

  • 110 云点播(回放),根据回放地址播放视频,展示自定义播放进度控制条、商品按钮、分享

  • 115 已结束,无回放。展示已结束提示:“直播已结束” 并触发商品弹窗(固定位置且不可关闭)

  • 206 禁播。展示“主播暂时离开,请稍候”及 “看看其他直播”按钮。

⚠️由状态 101 到 108 需要更新“xxxx人观看”视图,而直接为 108 不需要,即,展示“xxxx人观看”

直播 SDK 推流状态

腾讯云直播

腾讯云直播SDK状态

拉流端异常处理:基于直播 SDK 状态码 2003、2004、2006、-2301 等对直播异常状态进行特殊处理。

  • -2301 及其他导致连接失败的异常:此时,更新后台推流状态码为 103 暂停中(或异常) 触发异常逻辑
weakSelf.livePlayerWrapper.playErrorBlock = ^(int event, NSString *msg) {
    dispatch_async(dispatch_get_main_queue(), ^{
//      [weakSelf.livePlayer pause];
//      [MCToast hideLoadingToastInView:weakSelf.playToolBarView];
      [MCKitLoading mcStopLoadingInView:weakSelf.playToolBarView];
      // 暂停中(或异常)
      [weakSelf.livePlayer removeVideoWidget];
      [weakSelf.roomInfoDict mcSetInteger:103 forKey:@"liveStatus"];
      [weakSelf.playToolBarView handleRoomId:weakSelf.roomId roomInfo:weakSelf.roomInfoDict];
      [weakSelf.playToolBarView.liteStatusView configRetryTitle];

//      MCStrongSelf
//      weakSelf.playToolBarView.liteStatusView.retryBlock = ^{
////        [MCToast showLoadingToastInView:strongSelf.view];
//        NSString *pullUrl = [strongSelf.roomInfoDict mcObjectForKey:@"pullUrl"];
//        [strongSelf startPlayWithView:strongSelf.videoPlayerView pullUrl:pullUrl];
//      };
    });
  };
  • 2003、2004、2006 这三种状态,主要用来处理由播放异常到开始播放或者播放结束的过度状态。对应不同的服务端播放状态及 UI 处理逻辑。
// 播放事件回调
  weakSelf.livePlayerWrapper.playEventBlock = ^(int event, NSDictionary * _Nonnull param) {

    switch (event) {
      case EVT_RENDER_FIRST_I_FRAME: {
        // 渲染首个视频数据包(IDR)
        dispatch_async(dispatch_get_main_queue(), ^{
          [MCKitLoading mcStopLoadingInView:weakSelf.playToolBarView];
          [weakSelf.roomInfoDict mcSetInteger:101 forKey:@"liveStatus"];
          [weakSelf.playToolBarView handleRoomId:weakSelf.roomId roomInfo:weakSelf.roomInfoDict];
        });
      }
        break;
      case EVT_VIDEO_PLAY_BEGIN: {
        // 视频播放开始
        dispatch_async(dispatch_get_main_queue(), ^{
          [MCKitLoading mcStopLoadingInView:weakSelf.playToolBarView];
        });
      }
        break;

//      case EVT_VIDEO_PLAY_PROGRESS: {
//        // 视频播放进度
//        dispatch_async(dispatch_get_main_queue(), ^{
//          [MCKitLoading mcStopLoadingInView:weakSelf.playToolBarView];
//        });
//      }
//        break;;
      case EVT_VIDEO_PLAY_END: {
        // 视频播放结束
        dispatch_async(dispatch_get_main_queue(), ^{
          [MCKitLoading mcStopLoadingInView:weakSelf.playToolBarView];
          [weakSelf.roomInfoDict mcSetInteger:108 forKey:@"liveStatus"];
          [weakSelf.playToolBarView handleRoomId:weakSelf.roomId roomInfo:weakSelf.roomInfoDict];
        });
      }
        break;
      default:
        break;
    }

⚠️:原有直播开始回调逻辑,在从异常中断到再次连接开始播放过渡时,不是每次都百分百调用。因此,才需要在 playEventBlock 中处理多种过度状态。

iOS 直播功能目录结构及对应类:

主要分为三部分:直播间管理类及IM 消息管理类、直播间控制器、直播不同状态 UI 视图。

  • 直播间管理类及 IM 消息管理类: XXX 主要处理直播间普通及自定义 IM 消息,包括 IM 登录、加入群组、普通或自定义消息接收及处理、群消息接收、收到强制关闭直播的消息 (1: 后台强制结束 2: 主播涉黄 3: 超时被强制结束 4: 超时未开播)、获取在线人数、退出直播间 (退出 IM 群组)、删除消息
// 收到强制关闭直播的消息 (1: 后台强制结束 2: 主播涉黄 3: 超时被强制结束)
- (void)onRecvRESTRoomID:(NSString *)roomID status:(int)status;
  • 观众播放主控制器,处理直播间不同的直播状态、IM 消息、监听主播端推流状态、配置直播间

  • View 目录下为直播间 UI:IM 消息列表、点赞、分享、商品等所在的观众播放页面工具视图(点赞、评论、分享、点播时的进度条)、顶部视图 (展示观看人数等信息)、直播状态视图、回到直播间悬浮、新的直播间商品弹窗等 UI 视图。

直播推拉流

  1. 推流端(主播端)小程序推
  2. 拉流端(观众端)

基于腾讯云直播 SDK 的二次开发。

IM 普通消息及自定义消息体处理

| 使用自定义消息体payload中的data字段来传输数据,data为字符串Json,约定cmd来做类型区分

eg.
示例

1. 点赞

  • cmd: LIKE
  • num:当前点赞了几次

约定num字段来记录当前用户点赞点了几下,接收方会拿自己本地当前的点赞数累加该num

2. 删除 (只删除 user_id 不是自己的他人发送的消息)

由于小程序端消息体中的 messageId 与 iOS 及 Andriond 两端算法不一致,导致三端无法通过 messageId 删除特定消息体。因此,最后方案是:通过匹配字符串的方式,删除当前消息列表中的消息。

  • cmd: DELETE_MESSAGE
  • msg_text: 当前消息的文本
  • user_id: 当前消息体的发送方id

IM 管理类 MCTXIMManager 中定义的消息体的不同 CMD,用以区分不同的自定义消息体

#define CMD_PUSHER_CHANGE   @"notifyPusherChange"
#define CMD_CUSTOM_TEXT_MSG  @"CustomTextMsg"
#define CMD_CUSTOM_LIKE      @"LIKE"       // 点赞
#define CMD_DELETE_MESSAGE   @"DELETE_MESSAGE"  // 删除消息
#define CMD_LIVE_STATUS_NOTICE @"LIVE_STATUS_NOTICE" // 主播端主动通知的状态

遗留问题

iOS、Andriond、小程序三端进入直播间获取的实时在线人数不一致的问题;

注意事项

  1. iOS 集成腾讯云直播基础版,相比之下,直播专业版本继承了 实时音视频 SDK超级播放器(Player+)短视频(UGSV)等音视频相关的核心功能。根据目前业务需求基础版完全够用了;
  2. 为避免 SDK 版本不一致导致功能性问题,iOS 与 Andriond 直播 SDK 版本固定为:pod ‘TXLiteAVSDK_Smart’, ‘8.7.10102’ 两端而 IM SDK 版本固定为: pod ‘TXIMSDK_iOS’, ‘5.1.62’;
  3. TXIMSDK_iOS 中包含新旧两套 IM API,为了保证稳定性。iOS 和 Andriond 使用最新的 IM API。iOS 使用调用方法名以 V2TIMManager 为开头的新 API;
  4. 点播回放功能并没有集成腾讯单独提供的超级播放器(通过 pod ‘SuperPlayer’ 引入) 而是通过对TXLiteAVSDK_Smart 提供的 TXVodPlayer 点播播放器进行自定义。在 TXVodPlayer 基础之上按照 UI 设计稿样式自定义播放进度条实现;
  5. 未登录可以进入直播间,注意项目中未登录到登录状态的处理逻辑;
  6. 通过 CMS 列表商品从直播间跳转商品详情页的浮窗逻辑;
  7. iOS 发布 App Store 需要经营范围包含“表演”或“网络表演”的《网络文化经营许可证》

参考文档

腾讯云移动直播 SDK

即时通讯 IM

IMSDK (V2TIMManager 版)

即时通讯客户端 SDK API

–EOF–

若无特别说明,本篇文章均为原创,转载请保留链接,谢谢!