全部产品
存储与CDN 数据库 域名与网站(万网) 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网 钉钉智能硬件
视频直播

方案介绍

更新时间:2018-01-31 10:02:43

一、概述

直播问答模式是用户在指定时间内登陆直播间,在主持人引导下进行线上答题,答对12道题目即可冲顶奖金,瓜分每期设定的奖金。从2018年伊始,互联网圈就刮起了一阵“大佬狂撒币,网友喜答题”的热潮,那么如何在自己的业务中增加这样强互动的方式,促成用户活跃的提升呢?下面以阿里视频云提供的方案为例,描述下如何搭建直播答题功能:

  • 如果业务中还没有直播的服务,请注册阿里云账号开通视频直播服务

  • 目前我们提供的方式是在直播流中通过APPServer调用openAPI来插入SEI信号,使用阿里云答题播放器解析SEI信号。

二、实现方案

1. 流程说明

  1. 主持人提出问题,此时准备推送题目。
  2. 现场人员发出信息,通过接入方的AppServer,调用阿里云的OpenAPI,在直播视频流当前位置中插入若干SEI帧,帧内容可由业务自定义。
  3. 播放SDK接收到视频流后,解析出SEI帧,并回调给APP。此时APP立即向AppServer请求问题信息,然后显示在APP上,完成整个出题过程。

注1:需要说明的是,在这个方案中,由于推流会产生固定的延时,而现场人员是通过云端服务插入SEI信号,有可能插入SEI的画面比真实插入时间早一点。因此现场人员在出题前需要做好校准,在插入SEI信号时加入一个固定延迟。

举例:现场主持人在12:00:00时提出问题,假设现场到阿里云的推流延时有1秒,那么现场工作人员应在12:00:01时调用添加SEI的OpenAPI(或者在12:00:00时调用,但是OpenAPI里面的delay参数设置为1000),这样正好保证SEI插入的是12:00:00主持人提出问题时的画面。

注2:客户端在收到SEI信号后,需要向服务器获取问题,这会产生一定的通信耗时。因此实际答题系统中,可酌情延长答题时间,比如在原有答题时间上+1秒。

注3:用户答题后,客户端需要上报答案,这会产生一定的通信耗时。因此实际答题系统中,AppServer在接收到答案时,答题超时时间允许有一个宽限值,比如原有的答题时限+1秒之内的均认为及时答题。

详见如下直播问答服务的架构图:

直播推流架构.png

2. 配置与开通

  • 首先需要开通阿里云视频直播服务
  • 提出工单,要求开通视频云添加SEI功能(提交域名和appname信息)
  • 在推流时,需要增加一个推流参数wm=1

3. 服务端API调用

如前流程介绍,在接入方的appserver完成视频流中添加SEI信号时需要调用以下接口。

注:除了通过服务端api方式插入SEI信号完成题目下发,还可以通过我们提供的 定制OBS工具完成推题

(1)添加SEI的OpenAPI

  • 请求参数
参数 类型 必须? 描述
Action String 操作接口名,系统规定参数,取值:AddTrancodeSEI
DomainName String 您的加速域名
AppName String 直播流所属应用名称
StreamName String 流名(SEI将会被添加到该流以及该流所产生的所有转码流上)
Text String SEI文本,长度限制: 4000 字节
Pattern String 追加到每一个关键帧 / 每一帧,取值:keyframe / frame
Repeat Integer 重复次数,-1 代表无限
Delay Integer 接收到命令后的 delay 时间(毫秒)
  • 返回参数
名称 类型 描述
RequestId String 该条任务请求ID
  • 特殊错误码
错误代码 描述 Http 状态码 语义
InvalidDomain.NotFound The domain provided does not exist in our records. 404 当前账户下未查到域名
IllegalOperation Illegal domain operate is not permitted. 403 不支持当前操作,如:非直播类域名
InvalidParams invalid parameters 400 参数不合法
InternalError The request processing has failed due to some unknown error. 500 后台发生未知错误

(2)调用示例:

  1. https://live.aliyuncs.com?Action=AddTrancodeSEI&Domain=test101.cdnpe.com&App=xxx&Stream=xxx&Text=hahaha&Pattern=frame&Repeat=300&Delay=0&<公共请求参数>

注意:在直播答题这种场景下,参数Pattern建议取值frameRepeat建议为3倍的关键帧间隔(示例中为300)。这样设置可以保证在3个关键帧间隔内,即便发生丢帧,只要播放器收到1帧,即可取得SEI信息。由于SEI在多帧内重复,所以播放器需要做SEI去重的工作。

4. 接入答题播放器

首先需要集成阿里云播放器SDK,具体参考如下链接:

针对直播答题,播放器SDK提供了SEI数据的回调,分别来看Android和iOS对应的接口

1. Android SEI数据回调

通过播放器设置SEI数据回调接口,来获取到SEI的数据,从而进行业务的处理。方法如下:

setSEIDataListener

public void setSEIDataListener(MediaPlayerSEIDataListener listener)

描述: 给播放器设置SEI数据的回调,获取流中的SEI数据

参数: 回调监听。

MediaPlayer.MediaPlayerSEIDataListener

public void onSEIdata(String data)

描述:SEI数据的回调监听

参数:data:SEI的数据。

说明:同一次播放,如果SEI数据相同,则只回调一次,后续的相同数据不会回调。

使用示例

  1. aliVcMediaPlayer = new AliVcMediaPlayer(DemoLiveAnswerActivity.this, videoSurface);
  2. aliVcMediaPlayer.setSEIDataListener(new MediaPlayer.MediaPlayerSEIDataListener() {
  3. @Override
  4. public void onSEIdata(String data) {
  5. praseData(data);//解析SEI data数据
  6. }
  7. });
  8. aliVcMediaPlayer.setMaxBufferDuration(3 * 1000);
  9. aliVcMediaPlayer.prepareAndPlay(liveUrl);
  10. private void praseData(String data) {
  11. //具体格式按照自己业务的需求去解析,然后做业务处理
  12. JSONObject jsonObject = null;
  13. try {
  14. jsonObject = new JSONObject(data);
  15. } catch (JSONException e) {
  16. e.printStackTrace();
  17. }
  18. SeiInfo seiInfo = SeiInfo.getFromJson(jsonObject);
  19. if (seiInfo == null) {
  20. Toast.makeText(getApplicationContext(), "SEI 数据错误", Toast.LENGTH_SHORT).show();
  21. return;
  22. }
  23. if (seiInfo.type.equals("startAnswer")) {
  24. //到服务器请求题目
  25. requestQuestion(seiInfo.questionId);
  26. } else if (seiInfo.type.equals("showResult")) {
  27. //到服务器请求答题汇总
  28. requestQuestionReport(seiInfo.questionId, seiInfo.showTime);
  29. }
  30. }

以上方法均可在Demo中找到使用方法。

2. iOS SEI数据回调

通过监听播放器SEI数据通知来获取SEI数据,具体的通知如下:

AliVcMediaPlayerSeiDataNotification

使用示例

添加监听通知接口:

  1. //直播答题接收的消息
  2. [[NSNotificationCenter defaultCenter] addObserver:self
  3. selector:@selector(onSeiData:)
  4. name:AliVcMediaPlayerSeiDataNotification object:self.mediaPlayer];

处理监听通知中SEI数据:

  1. //答题
  2. - (void)onSeiData:(NSNotification *)notification{
  3. /*
  4. {
  5. "questionId": "001”,
  6. "type": "startAnswer"
  7. } 这个是开始答题
  8. {
  9. "questionId": "001”,
  10. "type": "showResult",
  11. "showTime": "5"
  12. } 这个是显示答题结果
  13. */
  14. NSDictionary* dict = [notification userInfo];
  15. if (dict) {
  16. NSString* seiData = [dict objectForKey:@"seiData"];
  17. if (seiData) {
  18. NSLog(@"sei data is %@",seiData);
  19. }
  20. }

可以在Demo中查询具体的使用方法。

三、注意事项

1. 播放器延迟处理

需要控制每个端上的延迟是一致的,可以设置播放器最大的延迟参数来处理,一般的原则是延迟越大,越能够抗网络抖动,延迟越小,则卡顿越频繁。针对直播答题来说,需要考虑到整条链路上的整体延迟,所以这个延迟参数对题目的有效性时间会有影响。如果播放器延迟控制在3秒,答题时间是10秒,则题目的有效性时间需要加上播放器的延迟时间则是13秒。

ios延迟控制参数,单位毫秒@property(nonatomic, readwrite) int dropBufferDuration;

android延迟控制接口:单位毫秒public void setMaxBufferDuration(int duration);

2. 下发题目延迟处理客户端在收到SEI信号后,需要向服务器获取问题,这会产生一定的通信耗时。因此在下发题目时,可酌情加大expiredSeconds,比如在原有答题失效时间上+1秒。

本文导读目录