一文带你深度解析腾讯云直播答题方案

欢迎你们前往云+社区,获取更多腾讯海量技术实践干货哦~web

做者:腾讯视频云json

进入2018年最火的新鲜事物无疑就是“直播答题”了,动辄上百万的奖金更是吸引了大量用户的参与。一场直播动辄几百万的奖金,每人能够分到几十元甚至百万元,愈来愈多的人但愿用本身的智商赚点零花钱。直播答题有多火?小程序

多个直播平台服务器屡次遭到宕机。实际上,几百万人一同在线的确会带给服务器不小的压力,更况且是新上线的 App,他们或许尚未想到本身会火得这么快。微信小程序

近期不少直播答题app出现了我的帐号上显示奖金额数不对、在线用户没法进入游戏、技术故障致使游戏被迫临时取消等状况。某视频平台还出现了系统将正确答案断定错误的状况,致使百万人被迫停止游戏。隔几天就来一次的数组

技术故障除了说明App准备不足外,也从侧面反映了这类游戏的火爆程度。为了让众多公司及开发者尽快遇上风口浪尖,腾讯云直播团队也是第一时间上线了“在线知识竞技解决方案”。缓存

效果体验

iOS平台(ipa)       Android平台(apk)            Obs Studio 定制版本(exe)安全

iOS                          Android                            Obs Studio服务器

在线答题室

建立房间便可体验主持人一端的效果;进入房间便可体验观众端的效果。微信

iPhone 平台的 Demo 采用了企业签名方式,请先到“设置-通用-设备管理”里,添加信任证书。websocket

Demo 仅做演示之用,用来展现腾讯云的技术能力,不表明最终产品形态,接入请仔细阅读文档。

 

体验方式二:Obs Studio

这种体验方式是直接使用腾讯云改造的 Obs Studio 进行推流:

  • 咱们在“工具”菜单栏里面加了一个“题目分发”按钮,能够直接将题目打入直播流中,题目能够预先编辑在 ini 文件中。
  • 使用 iOS 或者 Android 端的演示App,选择 答题播放器 功能,就能够体验观众端题目收取的效果了。
  • OBS Studio 的使用方法,详见 腾讯云定制版 Obs Studio 说明书

SDK下载

下载地址

咱们的优点

  • 精准的“音题画”同步 腾讯云 SDK 和云端均支持在直播流中插入 题目 或 时间同步信令,能够实现声音、画面和题目弹出的完美同步。
  • 超低的观众端延迟差 腾讯云 SDK 的 极速播放模式 所支持的延迟修正技术,可让观众与观众之间延迟差在 1s 之内,从而让观众的答题同步性获得保证。
  • 支持微信小程序接入 腾讯云 SDK 已经默认打包在微信版本中,并以 <live-player> 标签的形式对外提供,设置 mode 为 live 模式,并将 min-cache 和 max-cache 都设置为 1,便可实现很是低延迟的播放效果。

方案解读

方案一:题目透传方案

原理描述

  • 消息发送(Obs): 若是你是在演播室使用 Obs 推流,能够直接使用腾讯云改造的 Obs Studio 替换现有的 Obs 软件,-咱们在“工具”菜单栏里面加了一个“题目分发”按钮,能够直接将题目打入直播流中,题目能够预先编辑在 ini 文件中。
  • 消息发送(APP): 若是想要简单使用 App 进行推流,可使用腾讯云终端 SDK 的 TXLivePusher 的 sendMessage 方法,该方案能将一段buffer塞到RTMP流中(buffer的最大长度限制为10K)。

    // iOS 示例代码 [_answerPusher sendMessage:[mesg dataUsingEncoding:NSUTF8StringEncoding]];

    //Android 示例代码 mTXLivePusher.sendMessage(questionInfo.getBytes("UTF-8"));

  • 消息接收: 利用腾讯云 SDK 的 TXLivePlayer 的 onPlayEvent(PLAY_EVT_GET_MESSAGE : 2012)功能,能够在播放器播放到指定画面的时候,同步地将 MESSAGE 通知给您的 APP,从而将题目同步地扩散到海量的观众端。

消息接收的接入方案能够参考咱们的接入文档(iOS平台 | Android平台

方案二:NTP时间同步方案

原理描述

  1. 腾讯云会每隔 1s 在您的直播流中实时插入通过 NTP 校时的国际标准时间戳。
  2. 演播室的导播员根据主持人的出题节奏,在合适的时间控制发题,发题系统会在每次下发的题目中带上当时的国际标准时间。
  3. SDK 在播放这种打入时间戳的视频流的时候,会定时通知您的 APP 当前 SDK 所播放的画面是在什么时间录制下来的(由于导播台到云端通常都会有一个固定的延迟,须要您提早作一个偏差校调)。
  4. 您的 APP 能够根据 SDK 的时间通知(即当前画面是什么时间录制的),按需显示指定的题目便可。

总结一下:方案二跟方案一的最大区别就在于题目的扩散方式,方案二的核心思路是让题目先经过IM通道快速送达观众端APP,在观众端先缓存下来,等待播放器通知了预期的 NTP 时间戳以后,再把题目显示出来。

方案三:小程序解决方案

方案一和方案二均可以实现“音-话-题”完美同步,可是相比于这种体验上的小优化,APP的扩散能力则是更加剧要的。小程序偏偏提供给了APP能够病毒式传播的能力。

腾讯云 SDK 已经默认打包在微信版本中,并以 <live-player> 标签的形式对外提供,若是:

  • 采用 flv 播放地址
  • 设置 mode 为 live 模式
  • 将 min-cache 和 max-cache 都设置为 1
  • 推流端 gop 为 1

那么就能够实现很是理想的播放延迟,并可以让各观众之间的延迟偏差在1s之内,虽然没法作到“音-话-题”分绝不差(在微信打包视频云 SDK 的时候,在线答题模式尚未兴起,因此不支持在音视频流中夹带消息),但也能达到几乎能够媲美APP的体验效果。

剩下的事情,就是经过小程序的 websocket 通道,或者咱们的 webim 解决方案,向小程序发题就能够了。

接入攻略(方案一)

步骤一:开通腾讯云直播服务

联系咱们开通腾讯云 直播服务,若是您时间比较急,能够 400 客服电话咱们加急审核。

步骤二:获取推流URL

想要简单获取一个推流URL,能够参考文档:快速得到地址

想要了解推流地址和直播间ID的关系,能够参考文档:后台自动拼装

想要了解若是保护本身的推流地址不被盗用,能够参考文档:防盗链签名

步骤三:获取播放URL

播放URL和推流URL是一一映射的,映射规则参考下面的图示您就能明白了:

请务必使用 FLV 格式的播放地址,RTMP在高并发场景下容易出现卡顿问题。

步骤四:配置推流端

若是您是使用APP进行推流,直接参考文档(iOS | Android)。

若是您是使用Obs推流,请注意如下几个重要设置项:

I帧间隔(GOP)

通常演播台的接入方式有两种:OBS Studio 推流或者编码盒推流,这两种推流工具均有比较成熟的设置接口。建议将 GOP(也叫关键帧间隔)设置为 1s ,这样可让观众端的延迟差别很是小。

x264 的 gop 设置对编码效率的影响不是很大,但对延迟的影响很是大:gop越大,服务器缓存越多。因为 SDK 的延迟修正须要一个修正时间,若是 gop 太大,对于刚进入的观众会有很大的影响 。

以下是Obs Studio 设置关键帧间隔的图示:

编码参数

推荐推荐配置

分辨率

视频比特率

帧率

声道数

采样率

音频比特率

优先画质

540x960

1000kbps

25

1

48k

72kbps

优先成本

360x640

600kbps

20

1

48k

72kbps

步骤五:对接播放器

  1. 下载文档第二部分中列出的 SDK 版本。
  2. 参考接入文档(iOS | Android)完成播放器的接入。两个平台所有完成,大概须要 0.5 天的工做量。
  3. 修改默认配置 因为 SDK 的默认配置为普通直播场景,因此须要修改配置,操做方法以下:
//iOS源码
TXLivePlayConfig *config = [[TXLivePlayConfig alloc] init];
TXLivePlayer *player = [[TXLivePlayer alloc] init];
//
//开启消息接受,收不到消息的话就是没打开这个(默认:关)
config.enableMessage = YES;
//
//设置延迟平衡点为1s(考虑到云端和推流端引入的延迟,实际延迟为2s多,SDK推流:2s, obs推流:3-4秒)
config.bAutoAdjustCacheTime = YES;
config.maxAutoAdjustCacheTime = 1;
config.minAutoAdjustCacheTime = 1;
config.cacheTime = 1;
config.connectRetryCount = 3;
config.connectRetryInterval = 3;
config.enableAEC = NO;
//先setConfig再startPlay
[player setConfig:config];
//Android源码
mTXLivePlayConfig = new TXLivePlayConfig();
mTXLivePlayer = new TXLivePlayer(context);
//
//开启消息接收,收不到消息的话就是没打开这个(默认:关)
mTXLivePlayConfig.setEnableMessage(true);
//
//设置延迟平衡点为1s(考虑到云端和推流端引入的延迟,实际延迟为2s多,SDK推流:2s, obs推流:3-4秒)
mTXLivePlayConfig.setAutoAdjustCacheTime(true);
mTXLivePlayConfig.setCacheTime(1.0f);
mTXLivePlayConfig.setMaxAutoAdjustCacheTime(1.0f);
mTXLivePlayConfig.setMinAutoAdjustCacheTime(1.0f);
//
//先setConfig再startPlay
mTXLivePlayer.setConfig(mTXLivePlayConfig);

请务必使用 FLV 格式的播放地址,RTMP在高并发场景下容易出现卡顿问题。

步骤六:题目的扩散

  • 若是是用APP发题,只须要参考TXLivePusher 的 sendMessage 调用方法便可,参考文档见 (iOS | Android)。
  • 若是是用咱们的定制版 Obs Studio 发题,那么可使用本地ini文件提早把题目编辑好,由导播员在合适的时间将题目扩散出去。

可靠性评估

有些客户可能会担忧:音视频通道自己不太稳定,那么万一卡了或者视频数据丢了,会不会致使观众端看不到题目。

  • 首先,直播的音视频数据丢帧是肯定的按照gop为单位来丢帧的,若是gop=1,那么每次会丢1s的音视频数据
  • 其次,以腾讯云目前的节点部署状况来看,视频卡顿90%以上都以因为观众端网速不足引发的,这种状况下其余的网络通信也不会很流畅。

因此,解决这个问题的办法就是每秒钟(gop设置为1s的前提条件下)发送一次题目消息,相同的题号在观众端剔重,这样就能够避免偶尔的音视频卡顿对题目到达可靠性的影响。

步骤七:接收题目消息

在咱们的推流 APP Demo 以及定制版本的 Obs Studio 中,咱们以 json 格式将题目组织成一段buffer,并将其夹在音视频流中送出去。

获取到这个buffer之后,您就能够将其解析出来,并完成对应的 UI 展现。若是你须要调整json格式以支持更多的定制型,请修改源码或者联系咱们。

  • TXLivePlayConfig 中的 enableMessage 开关置为 YES。
  • TXLivePlayer 经过 TXLivePlayListener 监听消息,消息编号:PLAY_EVT_GET_MESSAGE (2012)
// iOS 的代码
 -(void) onPlayEvent:(int)EvtID withParam:(NSDictionary *)param {
    [self asyncRun:^{
        if (EvtID == PLAY_EVT_GET_MESSAGE) {
            dispatch_async(dispatch_get_main_queue(), ^{ //抛到主线程,避免线程安全问题
                if ([_delegate respondsToSelector:@selector(onPlayerMessage:)]) {
                    [_delegate onPlayerMessage:param[@"EVT_GET_MSG"]];
                }
            });
        }
    }];
}
//Android 示例代码
mTXLivePlayer.setPlayListener(new ITXLivePlayListener() {
        @Override
        public void onPlayEvent(int event, Bundle param) {
            if (event == TXLiveConstants.PLAY_ERR_NET_DISCONNECT) {
                roomListenerCallback.onDebugLog("[AnswerRoom] 拉流失败:网络断开");
                roomListenerCallback.onError(-1, "网络断开,拉流失败");
            }
            else if (event == TXLiveConstants.PLAY_EVT_GET_MESSAGE) {
                String msg = null;
                try {
                    msg = new String(param.getByteArray(TXLiveConstants.EVT_GET_MSG), "UTF-8");
                    roomListenerCallback.onRecvAnswerMsg(msg);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
});

步骤八:开发答题系统

因为腾讯云 PAAS 的定位,因此对于跟客户业务绑定比较紧密的答题和支付系统,咱们就不涉及了,须要您来参与开发。

这里广泛采用的方案是:将客户的答案以 HTTP(S) 请求方式汇总到答题服务器上,只是实现过程须要注意解决瞬间高并发的请求压力。

有客户可能会问,IM系统是否适合用来答题,这里目前看是不适合的,由于 IM 系统的主要能力在于消息扩散,而答题的主要目标是信息的收拢。

步骤九:答题结果显示

通常题目出来一段时间之后,就会进入闭题状态。这时,答题系统会将结果进行统计汇总,并将汇总结果下发给观众。

若是是用咱们的定制版 Obs Studio 扩散结果,搭一个简单的服务器,并提供一个 http 接口,而后按照咱们约定的 json 格式跟 Obs 进行题目、答案以及人数的通信。从而实现题目和答案的分发。

这部分协议因为文档篇幅限制,暂时不放在文档中详细列出,有须要的话请 400 电话联系咱们。

接入攻略(方案二)

步骤一:开通腾讯云直播服务

同方案一,再也不赘述。

步骤二:获取推流URL & 加注NTP时间戳

参考方案一,与方案一不一样之处在于,推流 URL 须要额外增长一个参数:

加注NTP时间戳

在推流 URL 以后添加参数 &txAddTimestamp=1 参数,服务器会每隔1s向您的直播流中打入一个带有国际标准时间(偏差在 100ms 之内)的 SEI 时间戳。若是您使用咱们的播放器播放此视频流,那么就会每隔一秒钟收到一次表明当前画面 NTP 时间的消息通知。

步骤三:获取播放URL

同方案一,再也不赘述。

步骤四:配置推流端

同方案一,再也不赘述。

步骤五:对接播放器

参考方案一,与方案一不一样之处在于,此时获取的message再也不是一个json,而是一个8字节的64位时间戳。

long timeStamp = byteArrayToInt(param.getByteArray(TXLiveConstants.EVT_GET_MSG));
/**
* 将8字节的byte数组转成一个long值
*/
public static long byteArrayToInt(byte[] byteArray) {
        byte[] a = new byte[8];
        int i = a.length - 1, j = byteArray.length - 1;
        for (; i >= 0; i--, j--) {// 从b的尾部(即int值的低位)开始copy数据
            if (j >= 0)
                a[i] = byteArray[j];
            else
                a[i] = 0;// 若是b.length不足4,则将高位补0
        }
        // 注意此处和byte数组转换成int的区别在于,下面的转换中要将先将数组中的元素转换成long型再作移位操做,
        // 若直接作位移操做将得不到正确结果,由于Java默认操做数字时,若不加声明会将数字做为int型来对待,此处必须注意。
        long v0 = (long) (a[0] & 0xff) << 56;// &0xff将byte值无差别转成int,避免Java自动类型提高后,会保留高位的符号位
        long v1 = (long) (a[1] & 0xff) << 48;
        long v2 = (long) (a[2] & 0xff) << 40;
        long v3 = (long) (a[3] & 0xff) << 32;
        long v4 = (long) (a[4] & 0xff) << 24;
        long v5 = (long) (a[5] & 0xff) << 16;
        long v6 = (long) (a[6] & 0xff) << 8;
        long v7 = (long) (a[7] & 0xff);
        return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7;
}

 

步骤六:题目的扩散

若是您使用本身的 IM 系统下发题目,请忽略这一部分,若是想使用腾讯云 IM 服务发题,请对接以下几步:

  • 1. 开通 IM 通信服务:开通腾讯云 云通讯 服务。
  • 2. 配置 IM 通信服务 :按照文档进行初始化配置,集成模式请务必选择独立模式。
  • 3. 使用 REST API 建立一个 BChatRoom 用于发题 :腾讯云 IM 的 REST API 是专门提供给服务端接入用的,建立群组这个操做通常是由您的服务器触发,因此适合使用 REST API 方案进行接入。 BChatRoom 这种房间类型很是适合用来发题,由于它本来就是用来作系统通知的,因此消息达到率高,消息可靠性好。 建立群组使用 v4/group_open_http_svc/create_group 能够实现,测试方法见 SDK 开发包中的 IM后台RESTAPI使用方法.pdf - 步骤3。
  • 4. 使用 REST API 建立一个 AVChatRoom 用于弹幕 :AVChatRoom 这种房间类型很是适合用来作聊天室的弹幕消息,有比较严格的脏字过滤和频率限制逻辑,专门为大型聊天室场景优化。 建立群组使用 v4/group_open_http_svc/create_group 能够实现,测试方法见 SDK 开发包中的 IM后台RESTAPI使用方法.pdf - 步骤4。 AVChatroom中默认的频率控制为40条/s,若是您须要调整限制请联系咱们,由于消息越多,带宽费用越高。
  • 5. 使用 REST API 在 BChatRoom 里发送题目广播: 消息发送可使用 v4/group_open_http_svc/send_group_msg ,测试方法见 SDK 开发包中的 IM后台RESTAPI使用方法.pdf - 步骤5。
  • 6. 如何实时获取在线人数? :REST API 是不支持客户端调用的,但即便是后台调用,腾讯云 REST API 的 后台调用频率限制也只有 100次/秒, 因此要实时获取在线人数,就须要先由您的业务后台经过 REST API 低频的获取到在线人数,再经过消息通道,将在线人数下发到客户端。 1)由您的业务服务器经过 v4/group_open_http_svc/get_group_info 得到群的在线人数。

2)以后,由您的业务服务器经过 v4/group_open_http_svc/send_group_msg,定时将人数经过群消息下发给客户端。定时频率能够设定为 3-5s 一次。

特别注意:REST API 不支持客户端调用,在客户端调用会引起私钥泄漏,进而致使您的云服务被恶意盗用和扣费。

步骤七:题目接收&弹幕收发

客户端使用 IM SDK 完成消息的接收和弹幕消息的收发,这里能够按照以下步骤对接

  • 1. 集成精简版 IMSDK 精简版:IMSDK 位于 SDK开发包 中,zip包中的 “接入指引-IMSDK.pdf” 有详细的说明。
  • 2.参考源码完成对接: SDK开发包中有一个叫作 AnswerPlayIMCenter 的源码文件,封装了对于 IMSDK 的简单调用,至关于对于接入文档的代码示例,您能够参考一下,以下是这个类的成员函数说明:

成员函数

做用

initIMCenter

用于初始化,须要填写您在腾讯云的 IM 服务相关信息。

loginIMUser

用于登陆,您能够把 imSDK 当成一个无界面的 QQ,用QQ收发消息确定要登陆,只是将QQ号和登陆密码换成了您的Userid和您的服务器签发的UserSig。

joinIMGroup

用于加入在步骤六中由您的后台服务器经过 REST API 建立的 BChatRoom 和 AVChatRoom。

sendChatMessage

用来发送弹幕评论消息

onRecvChatMessage

用于接收来自 AVChatRoom 的弹幕消息,注意作一下渲染的频率限制,不要收到一条弹幕消息就刷一次屏幕,手机性能可能扛不住,不少客户都是在这里疏忽了,由于测试期间消息很少不易发现。

onRecvIssueMessage

用于接收来自 BChatRoom 的题目消息,按照方案二的设计,每道题目里面都有它应该显示的 NTP 国际时间。

  • 3. 题目的显示时机 :onRecvIssueMessage 收到的题目不要马上显示出来,要等来自播放器的 GET_MESSAGE 回调,若是回调的时间 >= 题目的 NTP 国际时间,就能够把指定的题目显示出来了。
  • 4. UserSig怎么算? :UserSig 是 loginIMUser 时须要的一个重要信息,它的做用等同于登陆QQ用的密码,只是这个密码由您的服务器为您的用户签发;这里使用的密码签发方案是基于 RSA 非对称加密实现的,因此安全性很是高。 UserSig 通常是由您的服务器签发的,签发方案能够参考: TLS 后台 API ,不过为了可以能让您快速调试起来,咱们也提供了一个Windows 的签发小工具,您能够在后台同窗加入项目以前就能够先把终端逻辑调试起来。 注意:小工具里的公私钥都只能用来测试,您可千万别当真的用了。

步骤八:开发答题系统

因为腾讯云 PAAS 的定位,因此对于跟客户业务绑定比较紧密的答题和支付系统,咱们就不涉及了,须要您来参与开发。

这里广泛采用的方案是:将客户的答案以 HTTP(S) 请求方式汇总到答题服务器上,只是实现过程须要注意解决瞬间高并发的请求压力。

有客户可能会问,IM系统是否适合用来答题,这里目前看是不适合的,由于 IM 系统的主要能力在于消息扩散,而答题的主要目标是信息的收拢。

步骤九:答题结果显示

通常题目出来一段时间之后,就会进入闭题状态。这时,答题系统会将结果进行统计汇总,并将汇总结果下发给观众,结果下发能够继续使用 步骤六 中的题目扩散通道。

相关阅读

webrtc 点对点直播

腾讯云直播接入说明

直播类业务云化建设


此文已由做者受权云加社区发布,转载请注明原文出处

相关文章
相关标签/搜索