# 直播SDK
<style>
.markdown-section h1, .markdown-section h2, .markdown-section h3, .markdown-section h4, .markdown-section h5, .markdown-section h6 {
    font-weight: 700 !important;
}
</style>
[TOC]

## 房间

### 概述

可获取直播间基本信息，如直播开始时间和直播持续时间、在线人数、讲师列表
可获取直播间设置信息，如直播间描述、直播间布局配置、监听直播间播放器、文档布局切换；
可获取观看端设置信息，如页面是否显示在线人数
可监听用户行为，如用户登录、退出；支持用户修改昵称

### 相关API

#### 信息

##### 获取直播开始时间和直播持续时间
```javascript
DWLive.onLiveTime = function (data) {}
```
返回data数据说明
```javascript
{
    liveDuration: 1223,// 直播持续时长（直播未开始该值为0）
    liveStartTime："12:00"// 直播开始时间（直播未开始该值为0）
}
```

#####  监听直播开始事件

```javascript
DWLive.onLiveStart = function (data) {}
```
返回data数据说明
```javascript
{
    "action":"publish_stream"
}
```
##### 监听直播进行中事件
```javascript
DWLive.onLiveStarting = function() {}
```
> 4.0.0前版本PC直播中回调为window._onStart, 已弃用，改用DWLive.onLiveStarting

##### 监听直播停止事件
```javascript
DWLive.onLiveEnd = function (data) {}
```
返回data数据说明
```javascript
{
    "action":"hd-live-stop",
    "msg":{
        "extra":{
            "endNormal":true
        },
    	"tips":{ // 提示语
        	"stu":0,
        	"assistant":0,
            "publisher":0,
        	"host":0,
        	"pool":[""]
         },
        "live":{
            "seminarPrepareMode":false,
            "id":"34D61E6DE933ED0F"
     	}
     }
}
```
##### 获取在线人数

```javascript
DWLive.onUserCountMessage = function (data) {}
```
返回data数据说明
```javascript
"100" // 当前在线人数
```
##### 获取讲师列表

```javascript
DWLive.onOnlineTeachers = function (data) {}
```
返回data数据说明
```javascript
{
    teachers: [
        {
            id: "11ac9ad16e73421d8fb003709c979a65"
            ip: "192.168.202.92"
            name: "123" // 昵称
            role: "publisher" // 角色
        }
    ]
}
```
##### socket链接成功回调
```javascript
window.onSocketConnect = function () {}
```
##### socket链接断开回调
```javascript
window.onSocketDisconnect = function () {}
```
#### 直播间设置

##### 获取直播间描述

```javascript
DWLive.onLiveDesc = function (data) {}
```
返回data数据说明

```javascript
<p>直播间描述</p>
```

##### 获取直播间布局配置

```javascript
DWLive.onRoomSetting = function (data) {}
```
> 讲师端开启/关闭连麦、切换观看端布局到文档/视频为主时，会触发此回调

返回data数据说明

```javascript
{
    1322: "1"
    1323: "0"
    1324: "0"
    allow_chat: "true" // 是否开启聊天
    allow_question: "true" // 是否允许提问
    allow_speak_interaction: "false" // 是否开启连麦
    allow_speak_third_party: {
        provider: 'agora', 
        status: 'false'
    }
    client_host_mode: "0"
    delay_time: "3"
    layout_video_main: "false" // 观看端布局是否以视频为主
    lock_screen: "false"
    mobile_h5_delay: "0"
    open_host_mode: "0"
    room_base_user_count: "0"
    source_type: "20" // 播放源
}
```
使用示例
```javascript
DWLive.onRoomSetting = function (data) {
    var t = data.layout_video_main;
    if (t === 'true') {
        Ui.toggleVideo(true);
    } else {
        Ui.toggleVideo(false);
    }
};
```

##### 获取直播间配置变更

```javascript
DWLive.onRoomSettingChange = function (data) {}
```
> 在直播间管理后台操作直播带货开关的开启/关闭，会触发此回调

返回data数据说明

```javascript
{
    liveCommerce: 0, // 直播带货开关配置变更; 关闭-0，开启-1
}
```
使用示例
```javascript
DWLive.onRoomSettingChange = function (data) {
    const { liveCommerce } = data
    const liveCommerceStatus = liveCommerce === 1 ? '开启' : '关闭'
    console.log('直播带货开关-liveCommerce:', liveCommerceStatus)
};
```

##### 监听直播间播放器/文档布局切换

```javascript
DWLive.onSwitchVideoDoc = function (data) {}
```

返回data数据说明

```javascript
"true" // "true" 以视频为主, "false" 以文档为主 
```

##### 监听当前播放（数据源）场景切换

> 该功能仅限文档直播间使用，主播客户端需使用4.9.0以上版本

```javascript
DWLive.onSwitchSource = function (data) {}
```
返回data数据说明
```javascript
{
    source_type: 0
}
```
source_type说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>值</td>
        <td>含义</td>
    </tr>
    <tr>
        <td>0</td>
        <td>数据源未知，在直播未开始、非文档直播间或使用低版本客户端直播时会返回</td>
    </tr>
    <tr>
        <td>10</td>
        <td>主播将数据源切换为摄像头模式，摄像头为开启状态</td>
    </tr>
    <tr>
        <td>11</td>
        <td>主播将数据源切换为摄像头模式，摄像头为关闭状态</td>
    </tr>
    <tr>
        <td>20</td>
        <td>主播将数据源切换为图片模式</td>
    </tr>
    <tr>
        <td>30</td>
        <td>主播将数据源切换为插播视频</td>
    </tr>
    <tr>
        <td>40</td>
        <td>主播将数据源切换为区域捕获</td>
    </tr>
    <tr>
        <td>50</td>
        <td>主播将数据源切换为桌面共享</td>
    </tr>
    <tr>
        <td>60</td>
        <td>主播将数据源切换为可自定义场景</td>
    </tr>
</table>

#### 观看端设置

##### 页面是否显示在线人数

```javascript
DWLive.showUserCount = function (data) {}
```
> admin后台直播间设置-观看端设置-页面功能设置-显示在线人数开关的状态

返回data数据说明

```javascript
0 // 0: 不显示 1： 显示
```
#### 用户相关

##### 登录成功
```javascript
DWLive.onLoginSuccess =  function (data) {}
```

返回data数据说明
```javascript
{
    live:{
        liveId: "C7B137D9AEE63BDA9C33DC5901307461", // 直播id
        status: 1, // 直播状态 0 未开始 1 直播中
        liveDuration:1223,//直播持续时长（直播未开始该值为0）
        liveStartTime："12:00",//直播开始时间（直播未开始该值为0）
        seminarLayout: 1 // 研讨会直播间直播中布局 1:视频 2：文档
    }
    template:{
        name:"模板一", //直播间模版名称
        desc:"视频", //直播间模版描述信息
        template: 5, // 模板类型
        templateData: {
            chat: 1, // 聊天模板
            qa: 1, // 问答模板
            dp: 1, // 画板模板
            type: 5 // 模板类型
        },
        type: 1, //直播间模板类型 （1:大屏模式 ，2：问答、视频、聊天 ，3：视频、聊天，4：文档、视频。聊天，5：视频、文档、问答、聊天，6：视频、问答
    },
    viewer:{
        id:"ae4dec",// 观看者id
        groupId："1",//观看者分组id
        name："名称" //观看者名称
    },
    basicInfo: {
        title: '房间1', // 房间名称
        liveStartTime: 123 // 直播开始时间 时间戳 单位毫秒,
        desc: '简介内容' // 直播间简介
    },
    settings: {
        barrage: 0, // 是否开启弹幕
        marquee: 0, // 是否开启跑马灯
        watermark: 1, // 水印
        exit: 0, // 是否支持推出
        reward: 0, // 打赏
        mobileAd: 0, // 直播间广告素材开关
        lowLatency: 0, // 是否开启H5低延迟
        customMenu: [ // 直播间自定义菜单
            {
                type: 1,
                name: "文档", // 菜单名称
                index: 1
            },
            {
                type: 2,
                name: "聊天",
                index: 2
            },
            {
                type: 3,
                name: "问答",
                index: 3
            },
            {
                type: 5,
                name: "简介",
                index: 5
            }
        ],
        lotteryV2: 1, // 抽奖2.0开关
        onlineUser: 1, // 是否显示用户在线人数
        pictxts: 0, // 图文直播
        documentDisplayMode: 1,
        warmVideoId: "", // 暖场视频id
        liveCountdown: 0, // 直播倒计时
        chatCharLimit: 300, // 聊天字符限制
        privateChat: 1, // 私聊功能
        multiQuality: 0, // 视频多清晰度
        standardWatermark: 0, // 标准水印 0 关闭 1 开启
        viewMode: 0, // 直播观看模式 0 普通直播 1 低延迟直播 2 无延迟直播
        multiVoiceResolution: 1,
        multiVoice: 0, // 多人连麦权限 1 有 0 无
        threePartScreenMode: 0, // 三分屏模式
        interaction: { // 互动组件
            likeSwitch: 0, // 点赞开关 0:关闭 1:开启
            gift: {
              giftSwitch: 0, // 打赏开关 0:关闭 1:开启
              specialEffects: 2 // 礼物特效类型
            },
            voteSwitch: 0, // 投票开关 0:关闭 1:开启
            redEnvelopesSwitch: 0, // 红包雨开关 0:关闭 1:开启
            inviteSwitch: 0, // 邀请卡开关 0:关闭 1:开启
            inviteRankSwitch: 0, // 邀请卡排行榜开关 0:关闭 1:开启
            questionnaire: { // 问卷
              state: 0 // 开关 0:关闭 1:开启
            },
            enableInteractionGame: 0, // 互动游戏开关 0:关闭 1:开启
            watchRewardSwitch: 0 // 直播观看奖励开关 0:关闭 1:开启
        },
        shareSwitch: 1, // 分享开关，0:关闭 1:开启 默认1
        liveScene: 0, // 直播场景 0为大班课，1是研讨课。默认0
        liveStartTimeSwitch: 0, // 直播开始时间展示开关
        watchFrequencySwitch: 0, // 观看次数开关:0关闭 1开启
        enableSuffixViewerId: 0, // 昵称去重，1开启，0关闭
        mobileViewMode: 1, 
        title: {},
        multiStreamSwitch: 0, // 多流直播开关
        pcAdSwitch: 0, // PC广告位开关 0:关闭 1:开启
        liveForwardReplay: 0, // 直播关联回放，0:关闭 1:开启
        userRoleSwap: 0, // 是否开启'旁听-互动身份互换'，0:关闭 1:开启
        interactionPopover: 0 // 直播结束后关闭互动功能弹窗 0:关闭 1:开启
    }
}
```
##### 登录失败
```javascript
DWLive.onLoginError = function (data) {}
```
 返回data数据说明

```javascript
{
    "success": false,
    "error": {
        "code": 20290005, // 20290007 重复登录; 20290000 限制登录; 20270002 20270003 20290004 20290005 密码错误; 
        "message": "live login param error"
    }
}
```

##### 修改用户昵称

```javascript
DWLive.changeNickname(name)
```

name 参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>name</td>
        <td>string</td>
        <td>昵称</td>
        <td>是</td>
    </tr>
</table>

##### 修改昵称回调
```javascript
DWLive.onChangeNickname = function (data) {}
```
返回data数据说明
```javascript
'new name' // 新昵称
```
##### 退出直播间
```javascript
DWLive.logout(object)
```
object 参数说明：
<table  width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>success</td>
        <td>function</td>
        <td>成功回调（含参数）</td>
        <td>可选</td>
    </tr>
    <tr>
        <td>error</td>
        <td>function</td>
        <td>失败回调（含参数）</td>
        <td>可选</td>
    </tr>
</table>

使用例子：
```javascript
$('#logout').click(function () {
  var isC = confirm('确认要退出登录?')
  if (isC) {
    DWLive.logout({
      success: function (data) {
        window.location.href = './login'
      },
      error: function (data) {
      	console.log(data.msg);
      }
    })
  }
})
```

#####  用户进出直播间消息通知

> 需在admin后台直播间设置-高级设置中开启 用户进入提醒 / 用户离开提醒

```javascript
DWLive.HDUserRemindWithAction = function (data) {}
```
返回data数据说明
```javascript
{
  userId:"2f2645fa08054cd2b9bc110260e43dbe", //用户ID
  userName:"过来我家", //用户昵称
  userRole:"student", //用户角色
  groupId:"123", //分组ID
  clientType:[1,4,2,3], //接收端   1-讲师；2-助教；3-主持人；4-观看端
  prefixContent:"天类鲁鲁饿", //内容前缀
  suffixContent:"妙蛙啊啊啊", //内容后缀
  remindAction: 1 // 1:进   0:出
}
```
使用示例
```javascript
DWLive.HDUserRemindWithAction = function(data) {
    if (e.remindAction === 1) {
        console.log("进入直播间", data);
    } else if (e.remindAction === 0) {
        console.log("退出直播间", data);
    }
};
```

##### 用户被踢出直播间
```javascript
DWLive.onKickOut = function (data) {}
```
返回data数据说明
```javascript
{
    viewerid:"87f5f0106cda4f02a1cce9a32128688b",
    kick_out_type:"20"
}
data.kick_out_type = 10,在允许重复登录前提下，后进入者会登录会踢出先前登录者.
data.kick_out_type = 20,讲师、助教、主持人通过页面踢出按钮踢出用户.
触发条件 
1. 讲师/助教/主持人 主动踢出用户，触发该事件
2. 在允许重复登录的前提下，后进入者会自动踢出先前登录者，触发该事件。
```

#### 销毁

调用destroy会执行关闭跑马灯、移除文档、 socket断连、销毁播放器操作

```javascript
DWLive.destroy()
```

## 播放器

### 概述

可监听播放器加载完成事件
可切换控制条的显示隐藏
支持视频全屏
获取自定义的播放器背景图、提示语
支持切换播放线路、支持切换音频、音量调节、清晰度调节
支持视频截图、视频弹幕、跑马灯
支持视频LOGO

### 相关API

#### 信息

##### 播放器加载完成回调

```javascript
DWLive.onPlayerReady = function () {}
```
> 4.0.0前版本PC端直播播放器加载完成为window.on_cc_swf_loading_completed, 建议弃用，改用DWLive.onPlayerReady

##### 获取当前播放器类型

```javascript

DWLive.on_hd_live_player_type = function (data) {}
```
返回data数据说明
```javascript
'h5' | 'flash' // h5播放器 | flash播放器
```
#### 控制条

##### 视频控制条切换显示/隐藏状态
```javascript
DWLive.showControl(tag)
```
> PC为UI控制条, Mobile为原生控制条

参数说明

<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>tag</td>
        <td>Boolean</td>
        <td>
        true：显示控制条<br>
        false：隐藏控制条
        </td>
        <td>是</td>
    </tr>
</table>

#### 全屏

##### 设置PC端UI控制条全屏按钮显示隐藏

```javascript
DWLive.setShowFullScreenBtn(tag)
```

参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>tag</td>
        <td>Boolean</td>
        <td>
        true：显示全屏按钮<br>
        false：隐藏全屏按钮
        </td>
        <td>是</td>
    </tr>
</table>

##### 直播视频切换全屏状态
```javascript
DWLive.switchFullScreen(tag)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>tag</td>
        <td>Boolean</td>
        <td>
        true：进入全屏<br>
        false：退出全屏
        </td>
        <td>是</td>
    </tr>
</table>

#### 获取自定义内容

##### 获取播放器自定义背景图片
>  播放器背景图在 直播间设置-观看端设置-播放器设置- 播放器背景图 选项中设置

```javacript
DWLive.playerBackgroundImageUri = function (data) {};
```
 返回data数据说明
```javascript
'https://material.csslcloud.net/testimage/3640D8AB19F84895/164984239430343.jpg' // 自定义图片链接
```
#####  获取播放器自定义提示语

```javascript
DWLive.playerBackgroundHint = function(data) {};
```
> 播放器提示语在 直播间设置-观看端设置-播放器设置- 播放器提示语 选项中设置

返回data数据说明

```javascript
'欢迎来到我的直播间' // 自定义提示语
```
#### 直播倒计时

##### 获取直播倒计时

```javascript
DWLive.liveCountdown
```
> admin后台直播间设置-基本信息设置了直播开始时间，同时在观看端设置-播放器设置中打开直播倒计时开关，会返回当前时间距开播时间的总时长

返回值说明

类型 Number 单位 秒

使用示例

```javascript
DWLive.onLoginSuccess = function () {
  console.log('多清晰度:', DWLive.multiQuality)
  console.log('文档显示模式:', DWLive.documentDisplayMode)
  console.log('倒计时:', DWLive.liveCountdown)
}
```
#### 线路

##### 获取线路

```javascript
DWLive.getLine()
```
返回值说明
```javascript
[
    { 
        name: '线路_1',
        selected: true
    },
    {
        name: '线路_2',
        selected: false
    }
]
```
##### 切换线路

```javascript
DWLive.changeLine(line, callBack)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>line</td>
        <td>number</td>
        <td>值为对应在getLine返回数组的index值(0,1)</td>
        <td>是</td>
    </tr>
        <tr>
        <td>callBack</td>
        <td>function</td>
        <td>切换回调</td>
        <td>否</td>
    </tr>
</table>

#### 音频

##### 只听音频

> 第一次调用开启音频模式，再次调用关闭音频模式

```javascript
DWLive.onlyAudio()
```

#### 音量

##### 音量调节
```javascript
DWLive.setSound(n)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>n</td>
        <td>number</td>
        <td>取值0 - 1 之间</td>
        <td>是</td>
    </tr>
</table>

#### 清晰度

> 开启该功能后可以获取多种清晰度线路

##### 清晰度回调

```javascript
DWLive.onHDReceivedVideoQuality = function (data) {}
```
返回data数据说明
```javascript
[
    {
        desc: '原画',
        quality: 0
    },
    {
        desc: '流畅',
        quality: 200
    },{
        desc: '标清',
        quality: 300
    }
]
```
##### 获取当前清晰度

```javascript
DWLive.getQualityIndex()
```

##### 切换清晰度
```javascript
DWLive.changeQuality(quality, callback)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>quality</td>
        <td>number</td>
        <td>清晰度码, 和onHDReceivedVideoQuality返回值中获取的保持一致</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callback</td>
        <td>function</td>
        <td>切换回调</td>
        <td>否</td>
    </tr>
</table>

使用示例
```javascript
DWLive.changeQuality(0, function (resp) {
  console.log(resp)
})
```

#### 截图

##### 截取视频图像
```javascript
DWLive.clipVideoImage()
```
> 该方法会截取视频图像，并且返回base64的视频图像的内容(目前只支持PC端chrome浏览器)

使用示例
```javascript
$('#btn-clip').click(function (e) {
    var base = DWLive.clipVideoImage()
    $('#clipImage_down').attr('href', base)
    $('#clipImage_down')[0].click()
})
```

#### 弹幕

> 需要到直播间设置-观看端设置-播放器设置里，打开 弹幕 选项
##### 弹幕开关
```javascript
DWLive.openBarrage(tag)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>tag</td>
        <td>boolean</td>
        <td>
        true：开启弹幕<br>
        false：关闭弹幕
        </td>
        <td>是</td>
    </tr>
</table>

使用示例
```javascript
// 弹幕开关
$('.open-barrage').click(function () {
    DWLive.openBarrage(true)  // 打开弹幕
})
```

##### 发送弹幕
```javascript
DWLive.barrage(msg, color);
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>msg</td>
        <td>string</td>
        <td>消息</td>
        <td>是</td>
    </tr>
    <tr>
        <td>color</td>
        <td>string</td>
        <td>为十六进制颜色值(0xffffff)</td>
        <td>否</td>
    </tr>
</table>

使用示例
```javascript
// 接收公聊消息，并将消息展示弹幕
DWLive.onPublicChatMessage = function(data){
    // 发送弹幕
    DWLive.barrage(data,'0xff0000');
}
```

#### 跑马灯

> 需要到直播间设置-观看端设置-播放器设置里，打开 跑马灯 选项

##### 获取跑马灯数据

```javascript
DWLive.getMarquee = function(data){}
```

返回data数据说明

```javascript
{
    "loop": -1,
    "type": "text",
    "text": {
        "content": "学员001",
        "font_size": 30,
        "color": "#e2534d"
    },
    "action": [
        {
            "duration": 4000,
            "start": {
                "xpos": 0.3,
                "ypos": 0,
                "alpha": 0.5
            },
            "end": {
                "xpos": 0,
                "ypos": 0.4,
                "alpha": 0.5
            }
        },
        {
            "duration": 16000,
            "start": {
                "xpos": 0,
                "ypos": 0.4,
                "alpha": 0.5
            },
            "end": {
                "xpos": 0.8,
                "ypos": 1,
                "alpha": 0.5
            }
        },
        {
            "duration": 4000,
            "start": {
                "xpos": 0.8,
                "ypos": 1,
                "alpha": 0.5
            },
            "end": {
                "xpos": 1,
                "ypos": 0.8,
                "alpha": 0.5
            }
        },
        {
            "duration": 16000,
            "start": {
                "xpos": 1,
                "ypos": 0.8,
                "alpha": 0.5
            },
            "end": {
                "xpos": 0,
                "ypos": 0.2,
                "alpha": 0.5
            }
        },
        {
            "duration": 4000,
            "start": {
                "xpos": 0,
                "ypos": 0.2,
                "alpha": 0.5
            },
            "end": {
                "xpos": 0.2,
                "ypos": 0,
                "alpha": 0.5
            }
        },
        {
            "duration": 12000,
            "start": {
                "xpos": 0.2,
                "ypos": 0,
                "alpha": 0.5
            },
            "end": {
                "xpos": 1,
                "ypos": 0.6,
                "alpha": 0.5
            }
        },
        {
            "duration": 8000,
            "start": {
                "xpos": 1,
                "ypos": 0.6,
                "alpha": 0.5
            },
            "end": {
                "xpos": 0.4,
                "ypos": 1,
                "alpha": 0.5
            }
        },
        {
            "duration": 8000,
            "start": {
                "xpos": 0.4,
                "ypos": 1,
                "alpha": 0.5
            },
            "end": {
                "xpos": 0,
                "ypos": 0.7,
                "alpha": 0.5
            }
        },
        {
            "duration": 16000,
            "start": {
                "xpos": 0,
                "ypos": 0.7,
                "alpha": 0.5
            },
            "end": {
                "xpos": 1,
                "ypos": 0.3,
                "alpha": 0.5
            }
        },
        {
            "duration": 8000,
            "start": {
                "xpos": 1,
                "ypos": 0.3,
                "alpha": 0.5
            },
            "end": {
                "xpos": 0.3,
                "ypos": 0,
                "alpha": 0.5
            }
        },
        {
            "index": 10,
            "duration": 5000,
            "start": {
                "xpos": 0.3,
                "ypos": 0,
                "alpha": 1
            },
            "end": {
                "xpos": 0.3,
                "ypos": 0,
                "alpha": 1
            }
        },
        {
            "index": 11,
            "duration": 5000,
            "start": {
                "xpos": 0.3,
                "ypos": 0,
                "alpha": 1
            },
            "end": {
                "xpos": 0.3,
                "ypos": 0,
                "alpha": 1
            }
        }
    ]
}
```

##### 视频显示跑马灯

```javascript
DWLive.showMarquee(marquee);
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>marquee</td>
        <td>object</td>
        <td>跑马灯数据</td>
        <td>是</td>
    </tr>
</table>

使用示例
```javascript
var marquee;
DWLive.getMarquee = function(data) {
    console.log(data);
    if (!!data) {
        marquee = data;
        return;
    }
    marquee = $("#viewerMarquee").text();
};
DWLive.onLiveStart = function(data) {
    if (marquee) {
        setTimeout(() => {
            DWLive.showMarquee(marquee);
        }, 1500)
    }
};
```

##### 视频关闭跑马灯

```javascript
DWLive.closeMarquee();
```

#### 异常处理

##### 视频卡顿监听
```javascript
window.cc_player_stream_waiting = function () {}
```

##### 异常断流监听
```javascript
window.cc_player_stream_disconnect = function () {}
```

## 文档

### 概述

支持切换文档模式、文档自适应、跳转指定页
支持文档跑马灯

### 相关API

#### 基本

##### 切换文档模式

> 文档支持两种模式： 自由模式和跟随模式
>
> 跟随模式：讲师端操作文档翻页，观看端同步翻页（默认）
>
> 自由模式:  观看端自行调用api翻页

```javascript
DWLive.setDocMode(type)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>type</td>
        <td>number</td>
        <td>
0：切换至跟随模式<br>
1：切换至自由模式<br>
            不传默认0
        </td>
        <td>是</td>
    </tr>
</table>

##### 文档自适应

> 文档支持两种显示方式：适合窗口和适合宽度
>
> 适合窗口：文档高度撑满，宽度自适应（默认）
>
> 适合宽度：文档宽度撑满，高度自适应

```javascript
DWLive.docAdapt(tag);
```

参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>tag</td>
        <td>boolean</td>
        <td>
        true：切换文档显示方式为适合窗口<br>
        false：切换文档显示方式为适合宽度<br>
            不传默认false
        </td>
        <td>否</td>
    </tr>
</table>

##### 获取直播间所有文档信息

```javascript
DWLive.getDocs(roomId,userId,callback)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>roomId</td>
        <td>string</td>
        <td>直播间的ID(roomid)</td>
        <td>是</td>
    </tr>
    <tr>
        <td>userId</td>
        <td>string</td>
        <td>CC账户ID（userid）</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callback</td>
        <td>function</td>
        <td>获取文档信息后的回调</td>
        <td>否</td>
    </tr>
</table>

callback回调成功后返回信息格式如下:
```javascript
{
    "msg": "操作成功",                                             //返回请求结果提示信息
    "success": true,                                            //请求是否成功
    "datas": {
        "docs": [{
            "mode": 0,//当前文档模式
            "docName": "water_2017111414005847726.jpg",            //文档标题
            "docId": "B21F4FC05EA64D489C33DC5901307461",          //文档id
        "docTotalPage": 1,                                     //当前文档总页数
            "iconSrc": "http://image.csslcloud.net/image/5CE336670ED3B3179C33DC5901307461/B21F4FC05EA64D489C33DC5901307461/0.jpg",//当前文档的缩略图
            "pages": [{
                "title": "",                                    //文档页的标题DWLive
                "pageIndex": 0,                                    //文档页的索引
                "src": "http://image.csslcloud.net/image/5CE336670ED3B3179C33DC5901307461/B21F4FC05EA64D489C33DC5901307461/0.jpg"                                                          //文档页的资源路径
            }]
        }, {
            "mode": 0,
            "docName": "高等数学（一）——初中知识回顾.pdf",
            "docId": "4A82652F23F93D4A9C33DC5901307461",
            "docTotalPage": 5,
            "iconSrc": "http://image.csslcloud.net/image/5CE336670ED3B3179C33DC5901307461/4A82652F23F93D4A9C33DC5901307461/0.jpg",
            "pages": [{
                "title": "",
                "pageIndex": 0,
                "src": "http://image.csslcloud.net/image/5CE336670ED3B3179C33DC5901307461/4A82652F23F93D4A9C33DC5901307461/0.jpg"
            }, {
                "title": "",
                "pageIndex": 1,
                "src": "http://image.csslcloud.net/image/5CE336670ED3B3179C33DC5901307461/4A82652F23F93D4A9C33DC5901307461/1.jpg"
            }, {
                "title": "",
                "pageIndex": 2,
                "src": "http://image.csslcloud.net/image/5CE336670ED3B3179C33DC5901307461/4A82652F23F93D4A9C33DC5901307461/2.jpg"
            }, {
                "title": "",
                "pageIndex": 3,
                "src": "http://image.csslcloud.net/image/5CE336670ED3B3179C33DC5901307461/4A82652F23F93D4A9C33DC5901307461/3.jpg"
            }, {
                "title": "",
                "pageIndex": 4,
                "src": "http://image.csslcloud.net/image/5CE336670ED3B3179C33DC5901307461/4A82652F23F93D4A9C33DC5901307461/4.jpg"
            }]
        }]
    }
}
```
callback请求失败回调如下：
```javascript
{
    errorCode:1,
    msg:'request was aborted'
}
```

#####  获取当前直播间文档信息 

```javascript
DWLive.getDocumentInfo()
```

 返回值说明

```javascript
{
	docId: 'EFB6050DF56C7F3B9C33DC5901307461' // 当前文档ID
	pageNum: 1  // 当前文档页码
}
```

##### 跳转到指定文档页

```javascript
DWLive.changePageTo(docId, pageIndex)
```
> 调用该方法前需要先调用DWLive.setDocMode切换文档模式为自由模式，然后调用DWLive.getDocumentInfo获取直播间所有文档信息，才可以成功翻页

参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>docId</td>
        <td>string</td>
        <td>要跳转到文档id</td>
        <td>是</td>
    </tr>
    <tr>
        <td>pageIndex</td>
        <td>string</td>
        <td>要跳转到指定文档的页码</td>
        <td>是</td>
    </tr>
</table>

使用示例
```javascript
$('#jump_btn').on('click', function () {
  var docId = $('#docId').val()
  var pageIndex = $('#pageIndeId').val()
  DWLive.changePageTo(docId, pageIndex)
})
```

##### 监听翻页
```javascript
DWLive.onPageChange = function (data) {}
```
返回data数据说明
```javascript
{
    "docId": "xxxx",//当前页id
    "docName": "Java.pdf",//当前页name
    "docTotalPage": 105,//总页数
    "pageNum": 0    //当前页索引值
}
```
#####  直播中文档翻页成功回调 

```javascript
window.on_cc_live_pagechange_complete = function(data){}
```

返回data数据说明

```javascript
{
    userId: '565f35bd8d534469992c09e66c9d7c12', // 用户ID
    userName: 'test', // 用户昵称
    docMsg: {
      completeURI: 'http://image.csslcloud.net/image/0.jpg', // 文档图片地址
      time: 10, // 相对开播的时间（单位秒）
      pageNum: 1, // 文档页码
      docId: '64AE990A55B83E749C33DC5901307461' // 文档ID
    }
}
```

#####  直播中文档翻页失败回调 

```javascript
window.on_cc_live_pagechange_error = function(data){}
```

返回data数据说明

```javascript
{
    userId: '565f35bd8d534469992c09e66c9d7c12', // 用户ID
    userName: 'test', // 用户昵称
    docMsg: {
      completeURI: 'http://image.csslcloud.net/image/0.jpg', // 文档图片地址
      time: 10, // 相对开播的时间（单位秒）
      pageNum: 1, // 文档页码
      docId: '64AE990A55B83E749C33DC5901307461' // 文档ID
    }
}
```

#### 弹幕

> 需要到直播间设置-观看端设置-播放器设置里，打开 弹幕 选项

##### 文档弹幕 （依赖flash，不再支持）
```javascript
DWLive.docBarrage(msg, color);
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>msg</td>
        <td>string</td>
        <td>消息</td>
        <td>是</td>
    </tr>
    <tr>
        <td>color</td>
        <td>string</td>
        <td>为十六进制颜色值(0xffffff)</td>
        <td>否</td>
    </tr>
</table>

使用示例
```javascript
// 接收公聊消息，并将消息展示弹幕
DWLive.onPublicChatMessage = function(data){
    // 发送弹幕
    DWLive.docBarrage(data,'0xff0000');
}
```

#### 跑马灯

> 需要到直播间设置-观看端设置-播放器设置里，打开 跑马灯 选项

##### 获取跑马灯数据

```javascript
DWLive.getMarquee = function(data){}
```

> 与视频获取跑马灯数据是同一API

##### 文档显示跑马灯

```javascript
DWLive.showMarqueeDoc(marquee);
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>marquee</td>
        <td>object</td>
        <td>跑马灯数据</td>
        <td>是</td>
    </tr>
</table>

##### 文档关闭跑马灯

```javascript
DWLive.closeMarqueeDoc();
```

## 聊天

### 概述

收发公聊、私聊消息
支持对用户禁言

### 相关API

#### 聊天发送

##### 发送公聊

```javascript
DWLive.sendPublicChatMsg(msg);
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>msg</td>
        <td>string</td>
        <td>消息内容</td>
        <td>是</td>
    </tr>
</table>

使用示例
```javascript
<input type="text" name="" id="msg">
<button id="sendChatMsg">发送消息</button>
```

```javascript
document.querySelector("#sendChatMsg").addEventListener('click', function () {
    let msg = document.querySelector("#msg").value;
    DWLive.sendPublicChatMsg(msg);
})
```

##### 发送私聊

```javascript
DWLive.sendPrivateChatMsg(touserid, tousername, nmsg) // 发送私聊
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>touserid</td>
        <td>string</td>
        <td>接收者的viewerid</td>
        <td>是</td>
    </tr>
    <tr>
        <td>tousername</td>
        <td>string</td>
        <td>接收者的viewername</td>
        <td>是</td>
    </tr>
    <tr>
        <td>msg</td>
        <td>string</td>
        <td>消息内容</td>
        <td>是</td>
    </tr>
</table>

#### 聊天接收

##### 接收公聊消息
```javascript
DWLive.onPublicChatMessage = function (data) {}
```
返回data数据说明
```javascript
// 该返回参数有两种类型
// 类型1 ，当该消息被敏感词过滤后，这条消息只会被自己收到，返回的数据参数格式为：
{
    "isFilterChat":1, //该条消息为敏感词，已被过滤
    "userid": "1bbd4c0ca2694cb7acabf1857198463d", // 发送者id
    "username": "111", // 发送者名字
    "userrole": "student", // 发送者身份(返回值是 string 或 number); 学生:"student"、4; 助教:"teacher"、2; 讲师:"publisher"、1 
    "useravatar": "", // 发送者头像
    "usercustommark": "",// 聊天自定义参数
    "groupId": "1111", // 分组id       
    "msg": "321321", // 消息内容
    "time": "10:16:50" // 发送时间
}
// 类型2，当该条消息为正常消息时，返回的数据参数格式为：
{
    "chatId":'23213',//聊天id
    "status":"1",//聊天消息状态， 0为显示  1为不显示 
    "userid": "1bbd4c0ca2694cb7acabf1857198463d", // 发送者idid
    "username": "111", // 发送者名字
    "userrole": "student", // 发送者身份(返回值是 string 或 number); 学生:"student"、4; 助教:"teacher"、2; 讲师:"publisher"、1 
    "useravatar": "", // 发送者头像
    "usercustommark": "",// 聊天自定义参数
    "groupId": "1111", // 分组id       
    "msg": "321321", // 消息内容
    "time": "10:16:50" // 发送时间
}
```
使用示例
```javascript
DWLive.onPublicChatMessage = function (data) {
	// 发送弹幕
    DWLive.barrage(data,'0xff0000'); 
}
```

##### 接收私聊消息

```javascript
DWLive.onPrivateChatMessage = function (data) {}
```
返回data数据说明
```javascript
{
    "fromuserid":"7a4715874d504b8db78cb5b77d66b8c8",  // 发送者id
    "fromusername":"name",   // 发送者名字
    "touserid":"33ed40d2d7b746919219789733b5bdd4",  // 接收者id
    "tousername":"第三方士大夫",   // 接收者名字
    "msg":"发反反复复",   // 消息内容
    "time":"17:22:15"   // 发送时间
}
```
##### 接收私聊回复

```javascript
DWLive.onPrivateAnswer = function (data) {}
```
返回data数据说明
```javascript
{
    "fromuserid":"33ed40d2d7b746919219789733b5bdd4",  // 发送者id
    "fromusername":"第三方士夫",  // 发送者名字
    "fromuserrole":"student",   // 发送者身份
    "touserid":"7a4715874d504b8db78cb5b77d66b8c8",  // 接收者id
    "tousername":"name",   // 接收者名字
    "msg":"阿斯蒂芬",   // 消息内容
    "time":"17:26:24"  // 发送时间
}
```
#### 聊天置顶

##### 监听聊天置顶事件

```javascript
DWLive.onChatTop = function(data) {}
```

返回data数据说明

```javascript
{
    "roomId": 16599400, // 房间id
    "accountId": 260910, // 账号id
    "id": "63f0a1fd681ff269bedfb9a9", // 聊天id
    "content": "111 ", // 聊天内容
    "fromViewerId": "ea08c057507642f1befd22ee9cfe6795", // 聊天发送人id 
    "fromViewerName": "007", // 聊天发送人昵称
    "fromViewerAvatar": "", // 聊天发送人头像
    "fromViewerGroupId": "", // 聊天发送人聊天组id
    "pusherGroupId": "16599400|260910",
    "fromViewerRole": 4, // 聊天发送人角色
    "top": 1676715629507
}
```



##### 监听取消聊天置顶事件

```javascript
DWLive.onChatTopCancel = function(data) {}
```

返回data数据说明

```javascript
{
    "chatIds": [
        "63f0a1fd681ff269bedfb9a9" // 聊天id
    ]
}
```

##### 获取当前置顶聊天消息

```javascript
DWLive.getChatTop(callback)
```

参数说明

```javascript
{
    success: (res) => {
      // res返回值示例
        {
    "records": [ // 置顶列表
        {
            "id": "63f0a1fd681ff269bedfb9a9", // 聊天id
            "content": "111 ", // 聊天内容
            "fromViewerId": "ea08c057507642f1befd22ee9cfe6795", // 聊天发送人id
            "fromViewerName": "007", // 聊天发送人昵称
            "fromViewerAvatar": "", // 聊天发送人头像
            "fromViewerGroupId": "", // 聊天发送人聊天组id
            "fromViewerRole": 4, // 聊天发送人角色
            "top": 1676715778916
        }
    ]
}
    },
    fail: (msg) => {
       // msg 错误提示文字 
    }    
}
```

#### 聊天自定义表情

##### 获取聊天自定义表情列表

```javascript
DWLive.onChatCustomEmoji = function(data) {}
```

> 自定义表情配置入口：admin后台-全局设置-自定义表情

返回data数据说明

```javascript
{
    "customEmojiArr": [ // 自定义表情名称列表
        "[1]"
    ],
    "customEmojiObj": { // 自定义表情列表
        "[1]": "https://cclivematerial.oss-cn-beijing.aliyuncs.com/image/8E4767F8A312EB9F/1675675029867_11_1191728488_.png" // key 名称 value 图片地址
    }
}
```

#### 禁言
> 教师对学员操作禁言后，学员不可参与聊天

##### 禁言
```javascript
DWLive.onBanChat = function (data) {}
```
返回data数据说明

```javascript
{
    "mode": 1
}
```

##### 禁言并删除聊天记录

```javascript
DWLive.onBanDeleteChat = function (data) {}
```

返回data数据说明

```javascript
{
    "viewerId": "265856540b814aa1aa72f52387109171"
}
```

##### 解除禁言

```javascript
DWLive.onUnBanChat = function (data) {}
```
返回data数据说明

```javascript
{
    "mode": 1 // 1 未禁言 2 已禁言
}
```

##### 直播间禁止聊天时，发送消息的回调通知
> 讲师开启直播间禁言后，直播间所有学员将无法参与聊天

```javascript
DWLive.onInformation = function (data) {}
```

 返回data数据说明

```javascript
'讲师暂停了文字聊天，请专心看直播吧'
```

##### 用户禁言后群发消息通知

```javascript
DWLive.HDBanChatBroadcastWithData = function (data) {}
```
返回data数据说明
```javascript
{
  "userId":"2f2645fa08054cd2b9bc110260e43dbe", //用户ID
  "userName":"过来我家", //用户昵称
  "userRole":"student", //用户角色
  "groupId":"123", //分组ID
  "userAvatar":"123.jpg" //头像
}
```

##### 用户禁言后发送聊天的消息回调
```javascript
DWLive.onSilenceUserChatMessage = function (data) {}
```

返回data数据说明

```javascript
{
    "msg": "hi ", // 内容
    "ip": "192.168.3.234",
    "userid": "3BFB64B75469822E", // 用户id
    "username": "学员001", // 用户昵称
    "userrole": "student", // 角色
    "useravatar": "", // 头像
    "time": "15:56:28", // 发送时间
    "usercustommark": "",
    "groupId": "" // 分组id
}
```

#### 聊天审核


##### 接收聊天审核消息

```
DWLive.onPublicChatLogManage = function (data) {}
```

> admin后台-助教端设置-开启聊天审核开关后，用户聊天消息在助教端审核操作后会观看端会接收到该回调

返回data数据说明

```javascript
{
    "chatIds":["63f0b4614194657932a83516"],
    "status":"0", // 0 聊天内容被助教通过 1 聊天内容助教被删除
    "checkStatus":"5"
}
```

## 问答

### 概述

课堂提问

### 相关API

##### 接收提问消息

```javascript
DWLive.onQuestion = function (data) {}
```
返回data数据说明
```javascript
{
    "action":"question",  // 提问
    "time":-1,
    "value":
    {
        "userId":"C783F0F7CB77E1F3",  // 提问者id
        "userName":"name",   // 提问者名字
        "content":"123145",  // 提问内容
        "userAvatar":"img",     // 提问者头像
        "groupId"："111",      //分组信息
        "id":"1B5BBA4826FFE337"   // 问题id
    }
}
```

##### 接收回答消息
```javascript
DWLive.onAnswer = function (data) {}
```
返回data数据说明
```javascript
{
    "action":"answer",   // 回答
    "time":-1,
    "value":
    {
        "content":"ghghjgug",   // 回答内容
        "isPrivate":0,    // 是否仅提问者可见
        "questionId":"1B5BBA4826FFE337",   // 问题id
        "questionUserId":"C783F0F7CB77E1F3",   // 提问者id
        "userId":"ebadb3d414c3471786d095c93bab8cb5",  // 回答者id
        "userName":"www",   // 回答者名字
        "userAvatar":"img",    // 回答者头像
        "groupId"："111",      //分组信息
        "userRole":"publisher"   // 回答者身份
    }
}
```

##### 发送问题
```javascript
DWLive.sendQuestionMsg(msg)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>msg</td>
        <td>string</td>
        <td>问题内容</td>
        <td>是</td>
    </tr>
</table>

使用示例
```javascript
$(".qasend").click(function(){
    var msg = $(".qainput").val();
    DWLive.sendQuestionMsg(msg); // 发送问题
})
```
###### 监听发布问题
```javascript
DWLive.onQaPublish = function (data) {}
```
返回data数据说明

```javascript
{
    "action": "publish_question",
    "time": 0,
    "value": {
        "questionId": "7EB4FF4912C6302CB463AB73BD4C026B" // 问题id
    }
}
```

使用示例

```javascript
DWLive.onQaPublish = function (data) {
    var $q = $('#' - data.value.questionId).attr('isPublish', '1')
    // 只看自己的问答
    if (!$('#only-me i').hasClass('active')) {
        $q.show()
    }
}
```
##### 直播间禁止提问时，发送消息的回调通知
```javascript
DWLive.onInformation = function (data) {}
```

返回data数据说明

```javascript
'讲师暂停了问答，请专心看直播吧'
```

## 基础互动

### 概述

支持公告、连麦、打卡、签到、抽奖、答题卡、随堂测、问卷等互动

### 相关API

#### 广播

api调用时序

![](images/live_broadcast.jpg)

##### 发布广播消息回调
```javascript
DWLive.onBroadcastMsg = function (data) {}
```
返回data数据说明
```javascript
{
    "createTime": "2023-02-20 16:43:21",
    "userrole": "publisher", // 角色
    "id": "CDA2817BD0FECE6F", // 广播id
    "userid": "1da0d436f71a4711bea7859792163ab4",
    "content": "广播消息内容xxx", // 广播内容
    "username": "js" // 发布者昵称
}
```

##### 删除广播消息回调

```javascript
DWLive.removeBroadcastMsg = function (data) {}
```

返回data数据说明

```javascript
{
    "action": "1",
    "id": "CDA2817BD0FECE6F" // 广播id
}
```

#### 公告

api调用时序

![](images\live_announcement.jpg)

##### 监听进入直播后已发布的公告信息

```javascript
DWLive.onAnnouncementShow = function (data) {};
```

返回data数据说明

```javascript
'公告内容xxxxx'
```

##### 监听直播观看过程中发布和编辑的公告

```javascript
DWLive.onAnnouncementRelease = function (data) {};
```

返回data数据说明

```javascript
'公告内容xxxxx'
```

##### 监听直播过程中删除公告操作

```javascript
DWLive.onAnnouncementRemove = function (data) {};
```
返回data数据说明

```javascript
{
    "action": "remove"
}
```

#### 签到

api调用时序

![](images/live_rollcall.jpg)

##### 监听讲师端发起的签到事件

```javascript
DWLive.onStartRollCall = function (data) {}
```
返回data数据说明

```javascript
{
    "duration": 8,
    "publisherId": "d97c43e9d4c4450aa0892092eb3fdf72", // 签到者id
    "rollcallId": "20230209165749969" // 签到id
}
```

##### 签到

```javascript
DWLive.answerRollcall(rollcallId, publisherId);
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>rollcallId</td>
        <td>string</td>
        <td>签到Id</td>
        <td>是</td>
    </tr>
    <tr>
        <td>publisherId</td>
        <td>string</td>
        <td>签到者Id</td>
        <td>是</td>
    </tr>
</table>

使用示例
```javascript
$('.signbtn button').click(function () {
    DWLive.answerRollcall(rollcallId, publisherId);
})
```

#### 答题卡

api调用时序

![](images/live_vote.jpg)

##### 监听讲师端发起的答题事件
```javascript
DWLive.onStartVote = function (data) {}
```

返回data数据说明

```javascript
{
    "publisherId": "d97c43e9d4c4450aa0892092eb3fdf72",
    "voteCount": 4, // 选项个数
    "voteId": "20230209165930345",
    "voteType": 0 // 题目类型 0 单选题 1 多选题
}
```

使用示例

```javascript
DWLive.onStartVote = function (data) {
    const {publisherId, voteCount, voteId, voteType} = data;
    // 展示答题卡界面
}
```

##### 答题
```javascript
DWLive.replyVote(voteid, option, publisherId)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>voteId</td>
        <td>string</td>
        <td></td>
        <td>是</td>
    </tr>
    <tr>
        <td>option</td>
        <td>array | number</td>
        <td></td>
        <td>是</td>
    </tr>
    <tr>
        <td>publisherId</td>
        <td>string</td>
        <td></td>
        <td>是</td>
    </tr>
</table>

使用示例
```javascript
$('.votebtn button').click(function () {
    if ($('.vote-option li').hasClass('active')) {
        if (voteType == 1) { // 多选题
            DWLive.replyVote(voteid, voteOptions, publisherId)
        } else {
            DWLive.replyVote(voteid, option, publisherId)
        }
    }
})
```

##### 监听答题结果统计

```javascript
DWLive.onVoteResult = function (data) {}
```

返回data数据说明

```javascript
{
    "answerCount": 1, // 答题人数
    "correctOption": -1, // 正确选项序号
    "statisics": [ // 结果
        {
            "count": 0, // 数量
            "option": 0, // 序号
            "percent": "0" // 百分比
        },
        {
            "count": 1,
            "option": 1,
            "percent": "100"
        },
        {
            "count": 0,
            "option": 2,
            "percent": "0"
        },
        {
            "count": 0,
            "option": 3,
            "percent": "0"
        }
    ],
    "voteCount": 4, // 选项数量
    "voteId": "20230209165930345", // 答题id
    "voteType": 0 // 类型 0 单选 1 多选
}
```

##### 监听答题结束事件

```javascript
DWLive.onStopVote = function (data) {}
```
返回data数据说明

```javascript
{
    "voteId": "20230209165930345" // 答题id
}
```

使用示例

```javascript
DWLive.onStopVote = function () {
    $('.vote').hide()
    $('.vote-option, .vote-list').empty()
    $('.votebtn button').css('opacity', 0.6)
    $('.votebtn').remove()
}
```

#### 问卷

api调用时序

![](images/live_questionnaire.jpg)

##### 监听讲师端发布自定义问卷事件
```javascript
DWLive.onQuestionnairePublish = function (data) {}
```

返回data数据说明

```javascript
{
    "questionnaireId": "A815CBC6051F01CF" // 问卷id
}
```

##### 监听讲师端发布的第三方问卷事件

```javascript
DWLive.onExternalQuestionnairePublish = function (data) {}
```

返回data数据说明

```javascript
{
    "externalUrl": "https://view.csslcloud.net/api/view/index?roomid=D97A352E7A5866F59C33DC5901307461&userid=8E4767F8A312EB9F", // 问卷地址
    "title": "123" // 标题
}
```

##### 获取问卷

```javascript
DWLive.getPublishingQuestionnaire(questionnaireId, callBack)
```

参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>questionnaireId</td>
        <td>string</td>
        <td>问卷id</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callBack</td>
        <td>function</td>
        <td>响应回调</td>
        <td>否</td>
    </tr>
</table>

callback返回数据说明

```javascript
{
    "success": true,
    "data": {
        "questionnaire": {
            "subjects": [ // 问卷项
                {
                    "score": 12, // 分值
                    "options": [ // 选项
                        {
                            "correct": 1, // 是否是正确选项 1 正确 0 错误
                            "index": 0,
                            "id": "FB1B7431EF736B4F", // 选项id
                            "content": "问卷选项A", // 选项内容
                            "indexDesc": "A"
                        },
                        {
                            "correct": 0,
                            "index": 1,
                            "id": "A4B93EB0645A8E3A",
                            "content": "问卷选项B",
                            "indexDesc": "B"
                        },
                        {
                            "correct": 0,
                            "index": 2,
                            "id": "3FB09171EAD5A75B",
                            "content": "问卷选项C",
                            "indexDesc": "C"
                        },
                        {
                            "correct": 0,
                            "index": 3,
                            "id": "74387AD5CA9D89EE",
                            "content": "问卷选项D",
                            "indexDesc": "D"
                        }
                    ],
                    "index": 0,
                    "id": "0A8C3B7FFEB8E178",
                    "type": 0, // 题目类型 0 radio 单选 1 checkbox 多选 2 input 输入框
                    "content": "问卷题目xxx", // 题目内容
                    "subjectIndex": 1,
                    "isSingleSubject": true,
                    "typeDesc": "单选"
                }
            ],
            "forcibly": 1, // 强制用户答卷 1 强制 0 不强制
            "action": 1, // 问卷提交后的操作：  0 关闭问卷  1 显示答案
            "id": "B38C17F15DD07114", // 问卷ID
            "title": "问卷标题xxx", // 问卷标题
            "submitedAction": 1, // 提交后显示答案 1 显示 0 不显示
            "questionnaireTip": "问卷调查",
            "successTip": "操作成功",
            "failTip": "操作失败",
            "tipSubmit": "提交"
        }
    },
    "datas": {
        "questionnaire": {
            "subjects": [
                {
                    "score": 12,
                    "options": [
                        {
                            "correct": 1,
                            "index": 0,
                            "id": "FB1B7431EF736B4F",
                            "content": "问卷选项A",
                            "indexDesc": "A"
                        },
                        {
                            "correct": 0,
                            "index": 1,
                            "id": "A4B93EB0645A8E3A",
                            "content": "问卷选项B",
                            "indexDesc": "B"
                        },
                        {
                            "correct": 0,
                            "index": 2,
                            "id": "3FB09171EAD5A75B",
                            "content": "问卷选项C",
                            "indexDesc": "C"
                        },
                        {
                            "correct": 0,
                            "index": 3,
                            "id": "74387AD5CA9D89EE",
                            "content": "问卷选项D",
                            "indexDesc": "D"
                        }
                    ],
                    "index": 0,
                    "id": "0A8C3B7FFEB8E178",
                    "type": 0,
                    "content": "问卷题目xxx",
                    "subjectIndex": 1,
                    "isSingleSubject": true,
                    "typeDesc": "单选"
                }
            ],
            "forcibly": 1,
            "action": 1,
            "id": "B38C17F15DD07114",
            "title": "问卷标题xxx",
            "submitedAction": 1,
            "questionnaireTip": "问卷调查",
            "successTip": "操作成功",
            "failTip": "操作失败",
            "tipSubmit": "提交"
        }
    }
}
```

##### 提交问卷

```javascript
DWLive.submitQuestionnaire(params, callback)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>params</td>
        <td>object</td>
        <td>提交问卷的回答信息</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callback</td>
        <td>function</td>
        <td>响应回调</td>
        <td>否</td>
    </tr>
</table>

params数据说明
```javascript
{
    questionnaireid:"0FF0486DAB9938FB", // 问卷ID
    answers:[
        {
            selectedOptionId:"A63DA4D314D96DFB",        //提交答案的ID（单选题）
            subjectId:"45AC816D86E6AAC3"                //提交问题的ID
        },
        {
            selectedOptionIds:"98809D2B35693987,5F862A1577662D15",//多个答案的ID（多选题）
            subjectId:"68E9B354A52ABF40"
        },
        {
            answerContent:"我是问答题的答案",              //问答题答案 (问答题)
            subjectId:"F5EF68012BEF40BE"
        }
    ]
}
```
##### 监听问卷结束事件
```javascript
DWLive.onQuestionnairePublishStop = function (data) {}
```

返回data数据说明

```javascript
{
    "questionnaireId": "A815CBC6051F01CF" // 问卷ID
}
```

##### 监听问卷统计结果

```javascript
DWLive.onQuestionnairePublishStatis = function (data) {}
```

返回data数据说明

```javascript
{
    "success": true,
    "data": {
        "id": "A815CBC6051F01CF", // 问卷id
        "title": "普通问卷", // 问卷标题
        "submitCount": 0, // 提交答案人数
        "submitAction": 0, // 问卷提交后的操作  0 关闭问卷  1 显示答案
        "subjects": [
            {
                "options": [
                    {
                        "selectedCount": 0, // 选择人数
                        "index": 0, // 选项顺序
                        "id": "6B0C1F26A5FE0D27", // 选项ID
                        "correct": 0, // 是否正确  0 否 1是
                        "content": "1" // 选项描述
                    },
                    {
                        "selectedCount": 0,
                        "index": 1,
                        "id": "D8889A2E1334DC13",
                        "correct": 0,
                        "content": "2"
                    },
                    {
                        "selectedCount": 0,
                        "index": 2,
                        "id": "1361B4F007421DB3",
                        "correct": 0,
                        "content": "3"
                    },
                    {
                        "selectedCount": 0,
                        "index": 3,
                        "id": "30B8C3D821C2E701",
                        "correct": 0,
                        "content": "4"
                    }
                ],
                "index": 0, // 题目顺序
                "score": 0, // 分数
                "id": "1E0820069B96D9C9", // 题目ID
                "type": 0, // 题目类型
                "content": "1" // 题目问题
            }
        ]
    }
}
```

#### 随堂测

api调用时序

![](images/live_practice.jpg)

##### 监听讲师端发起的随堂测开始事件
```javascript
DWLive.onPracticePublish = function (data) {}
```
返回data数据说明

```javascript
{
    "publisherId": "b23e0b1b60d94561958e157c25338f41",
    "practiceId": "2698BFB47549DCD0"
}
```

##### 获取随堂测数据
```javascript
DWLive.getPracticeInfomation(practiceId, callback);
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>practiceId</td>
        <td>string</td>
        <td>随堂测id(没有则传空字符串)</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callback</td>
        <td>function</td>
        <td>响应回调</td>
        <td>否</td>
    </tr>
</table>

callback返回数据说明
```javascript
// 无随堂测：
{
    datas: {},//返回数据
    errorCode: 426,//错误码
    msg: "practice not exists,check params",//错误信息
    success: false  //是否成功
}
// 有随堂测：
{
    datas: {     
        isExist: 1,
        practice:{
        id: "F1EE56C62300B088" ,  //随堂测id
        isAnswered: "false" ,     //是否已经回答
        options: [               //选项（选项index和选项id）
            {index: 0, id: "9F10F2FF461AD740"},
            {index: 1, id: "8F9FA1BE0AC52C5C"},
                    …
        ]
        publishTime: "2019-11-22 14:08:44", //发布时间
        status: 1,                //随堂测状态 1 是正在发布 2 结束答题进入统计
        type: 1                 //随堂测类型 1单选题，2是多选 0 判断题
        }
    },
    errorCode: 0,
    msg: "操作成功",
    success: true
}
```

##### 提交随堂测

```javascript
DWLive.submitPracticeInfo(practiceId, opt, callback)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>practiceId</td>
        <td>string</td>
        <td>随堂测Id</td>
        <td>是</td>
    </tr>
    <tr>
        <td>opt</td>
        <td>string</td>
        <td>选择的选项id(多个选项用空格隔开)</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callback</td>
        <td>function</td>
        <td>响应回调</td>
        <td>否</td>
    </tr>
</table>

callback返回数据说明
```javascript
{  
  datas: { 
    practice: {      
      answerResult: 1  //选项结果 1为正确 0为错误
      id: "9F9D0EC468390E22"
      isRepeatAnswered: "false", //是否重复回答
      options: [
        { index: 0,//索引
           id: "2715AA75469DCD54", //选项id
           isCorrect: 0, //该选项是否正确 0为错误 1为正确
           count: 0, //选择该选项人数
           percent: "0%"//选择该选项的比例
        }, 
        ...
      ],
      submitRecord: [{
          optionId: "754251300D86E12B",//选择选项的id
          optionIndex: 1               //选择选项的索引
        }],
      type: 1 //选择题类型
    }
  errorCode: 0
  msg: "操作成功"
  success: true
}
```

##### 	随堂测停止答题消息回调
```javascript
DWLive.onPracticePublishStop = function (data) {}
```

返回data数据说明

```javascript
{
    "practiceId": "2698BFB47549DCD0" // 随堂测id
}
```

##### 获取随堂测统计信息

```javascript
DWLive.getPracticeStatisInfo(practiceId, callback)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>practiceId</td>
        <td>string</td>
        <td>随堂测id</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callback</td>
        <td>function</td>
        <td>响应回调</td>
        <td>否</td>
    </tr>
</table>

callback返回数据说明

```javascript
{
    "success": true,
    "data": {
        "practice": {
            "id": "6C59043BF5FF23FA",
            "type": 1, // 选项题类型 1 单选 2 多选
            "status": 2, // 随堂测状态 1  测试进行中 2 测试结束答题
            "stopTime": 9,
            "publisherId": "b23e0b1b60d94561958e157c25338f41",
            "ranking": [ // 排名数据
                {
                    "costTime": 3,
                    "userName": "11", // 学员昵称
                    "userId": "8c00fadbc9db4334ab996aec1b2f9d76"
                }
            ],
            "statistic": { // 统计信息
                "answerCount": 1, // 作答总人数
                "correctCount": 1, //  作答正确人数
                "correctPercent": "100%", // 正确率
                "options": [ // 选项
                    {
                        "correct": 0, // 是否是正确选项 1 是 0 否
                        "count": 0, // 该选项作答数量
                        "index": 0,
                        "id": "782AAF9EBB4C3AC0",
                        "percent": "0%"  // 该选项作答占比
                    },
                    {
                        "correct": 1,
                        "count": 1,
                        "index": 1,
                        "id": "B2C8B11D65A257DF",
                        "percent": "100%"
                    },
                    {
                        "correct": 0,
                        "count": 0,
                        "index": 2,
                        "id": "8DDA4CE51CACD39F",
                        "percent": "0%"
                    },
                    {
                        "correct": 0,
                        "count": 0,
                        "index": 3,
                        "id": "C4EAEF6B7DA1397D",
                        "percent": "0%"
                    }
                ]
            }
        }
    }
}
```

##### 获取随堂测排名数据

```javascript
DWLive.getPracticeRanking(practiceId, callback)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>practiceId</td>
        <td>string</td>
        <td>随堂测id</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callback</td>
        <td>function</td>
        <td>响应回调</td>
        <td>否</td>
    </tr>
</table>

callback返回数据说明

```javascript
{
    "success": true,
    "data": {
        "practice": {
            "id": "6C59043BF5FF23FA", // 随堂测id
            "type": 1,
            "status": 2,
            "stopTime": 9,
            "publisherId": "b23e0b1b60d94561958e157c25338f41",
            "ranking": [ // 排名数据
                {
                    "costTime": 3,
                    "userName": "11",
                    "userId": "8c00fadbc9db4334ab996aec1b2f9d76"
                }
            ],
            "statistic": {
                "answerCount": 1,
                "correctCount": 1,
                "correctPercent": "100%",
                "options": [
                    {
                        "correct": 0,
                        "count": 0,
                        "index": 0,
                        "id": "782AAF9EBB4C3AC0",
                        "percent": "0%"
                    },
                    {
                        "correct": 1,
                        "count": 1,
                        "index": 1,
                        "id": "B2C8B11D65A257DF",
                        "percent": "100%"
                    },
                    {
                        "correct": 0,
                        "count": 0,
                        "index": 2,
                        "id": "8DDA4CE51CACD39F",
                        "percent": "0%"
                    },
                    {
                        "correct": 0,
                        "count": 0,
                        "index": 3,
                        "id": "C4EAEF6B7DA1397D",
                        "percent": "0%"
                    }
                ]
            }
        }
    }
}
```



##### 关闭随堂测

```javasvript
DWLive.onPracticeClose = function (data) {}
```

 返回data数据说明

```javascript
{
    "practiceId": "2698BFB47549DCD0" // 随堂测id
}
```

#### 计时器

api调用时序

![](images/timer.jpg)

##### 监听开始计时

```javascript
DWLive.onTimerStart = function (data) {}
```

data数据说明

```javascript
{
    "duration": 60000, // 计时器总时长，单位毫秒
    "publisherId": "e8ed987f24794d268937ecad5a2c499a", // 发起计时的用户ID
    "serverTimestamp": 1774515842817, // 当前服务器时间
    "id": "bce171ad75a24d41acc044f3a2beab41", // 当前计时器ID
    "startTimestamp": 1774515842817, // 发起计时的服务器时间
    "status": 1  // 当前计时器状态，1进行中、0已结束
}
// duration - (serverTimestamp - startTimestamp) 所得时间为计时器剩余时间（单位ms）
```

##### 监听计时结束

```javascript
DWLive.onTimerStop = function (data) {}
```

data数据说明

```javascript
{
    "duration": 60000, // 计时器总时长，单位毫秒
    "publisherId": "e8ed987f24794d268937ecad5a2c499a", // 发起计时的用户ID
    "serverTimestamp": 1774515842817, // 当前服务器时间
    "id": "bce171ad75a24d41acc044f3a2beab41", // 当前计时器ID
    "startTimestamp": 1774515842817, // 发起计时的服务器时间
    "status": 0  // 当前计时器状态，1进行中、0已结束
}
```

##### 监听查询计时器异常

后进学员查询当前计时器接口异常时触发

```javascript
DWLive.onTimerError = function (error) {
  console.log('onTimerError', error)
}
```

#### 打卡

api调用时序

![](images/live_punch.jpg)

##### 监听讲师端发起打卡事件

```javascript
DWLive.onHdLiveStartPunch = function (data) {}
```
data数据说明
```javascript
{
  "punchId":"5de0c0d36fd538473af20740",//打卡id
  "expireTime":"2019-11-29 14:55:25",//打卡开始时间
  "remainDuration":9, //打卡持续时长
  "tips":"提示语", //没有设置提示语则不返回该字段
}
```

#####  获取打卡信息

```javascript
DWLive.getHdInquirePunchInformation(callback)
```

callback返回数据说明

```javascript
{
    "success": true,
    "data": {
        "punch": {
            "id": "63e61023fdd9cc4c246a3b51", // 打开id
            "expireTime": 1676021805000, // 失效时间
            "remainTime": 9 // 剩余时长
        }
    }
}
```

##### 提交打卡

```javascript
DWLive.hdCommitPunch(punchId, callback)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>punchId</td>
        <td>string</td>
        <td>打卡Id</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callback</td>
        <td>function</td>
        <td>响应回调</td>
        <td>否</td>
    </tr>
</table>

callback返回数据说明

```javascript
{
    "data": { },
    "success": true
}
```

##### 监听打卡停止事件

```javascript
DWLive.onHdLiveStopPunch = function (data) {}
```
返回data数据说明

```javascript
{
    "punchId": "63e610f244de7d3fac86f7ab"
}
```

#### 抽奖
> 抽奖1.0 （默认） 按号码抽奖，用户凭中奖号码领奖
> 抽奖2.0 （需单独开启权限）支持多种设置 奖品名称、过滤已中奖用户、中奖人数、预设中奖、中奖用户信息收集
> 两种抽奖方式只可选择一种

 api调用时序

![](images/live_lottery.jpg)

##### 开始抽奖
```javascript
DWLive.onStartLottery =  function (data) {}
```

 返回data数据说明

```javascript
{
    "lotteryId": "20230210142058056" // 抽奖id
}
```

##### 中奖

```javascript
DWLive.onWinLottery = function (data) {}
```
返回data数据说明

```javascript
{
    "lotteryCode": "6437", // 中奖码
    "lotteryId": "20230210142058056", // 抽奖id
    "remainNum": "0",
    "viewerId": "cb9da31aa7ab45a6a16d9630677a5b7f", // 中奖者id
    "viewerName": "cc" // 中奖者昵称
}
```

使用示例

```javascript
DWLive.onWinLottery = function (data) {
    var code = data.lotteryCode,
        name = data.viewerName
    if (data.viewerId == DWLive.viewerid) {
        $('.lotterynum').html(code)
        $('.lotterybox').hide()
        $('.lotterynum, .lotterytext, .lottery').show()
        $('.lotteryh3').html('恭喜您中奖啦')
        $('.lotterynum, .lotterytext').css('z-index', 9)
        win = true
    } else {
        $('.lotteryname').html(name)
        $('.lotterybox, .lottery').show()
        if (win == true) {
        $('.lotteryh3').html('恭喜您中奖啦')
        } else {
        $('.lotteryh3').html('哎呀，就差一点')
        }
        setTimeout(function () {
        $('.lotterybox').hide()
        if (win == true) {
            $('.lotteryh3').html('恭喜您中奖啦')
        } else {
            $('.lotteryh3').html('正在抽奖')
        }
        }, 2000)
    }
}
```
##### 结束抽奖
```javascript
DWLive.onStopLottery = function (data) {}
```
返回data数据说明

```javascript
{
    "lotteryId": "20230210142058056" // 抽奖id
}
```

使用示例

```javascript
DWLive.onStopLottery = function () {
    stop = true
    if (win == false) {
        setTimeout(function () {
        $('.lottery').hide()
        }, 2000)
    }
}
```
##### 抽奖回调监听 （抽奖2.0）

> 抽奖2.0功能需单独开通权限使用

```javascript
DWLive.onLottery = function (data) {}
```
返回data数据说明
```javascript
{
  //抽奖订单ID
  lotteryId: String
  //抽奖订单状态   0抽奖创建成功， 1抽奖取消成功， 2抽奖已完成， 3抽奖异常结束
  lotteryStatus: int 
  //抽奖订单类型   0普通抽奖类型（暂无别的抽奖类型）
  lotteryType: int
  //是否存在抽奖  注意当该字段为false的时候 无其他字段
  haveLottery: boolean
  //中奖信息
  LotteryWinInfo: {
           //中奖人需要提交的信息
    collectTemplate: [
        {
          //索引 提交抽奖的时候用到
          index: int
          //标题
          title: String 
          //提示语
          tips: String
                }
    ];
    //是否中奖  true中奖  false未中奖
    isWinner: boolean
    //自己的信息
    LotteryOwnUserInfo: {
      userAvatar: 'xxxx' String
        //名称
        priuserNamevate: 'xxxx' String
        //用户id
        userId: 'xxxx' String
        //中奖码
        prizeCode: 'xxxx' String
    };
    //中奖人名单信息
    userInfos: array [
      {
      //头像
      userAvatar: 'xxx' String
      //用户名
      userName:'xxxx' String
      //用户id
      userId: 'xxxx' String
            }
    ];
    //奖品信息
    LotteryPrize:  {
      name: 'xxxx' string
    };
  };
}
```
使用示例
```javascript
DWLive.onLottery = function (data) {
    if (data.haveLottery) { // 有抽奖
        lotteryId = data.lotteryId
        if (data.lotteryStatus === 0) { // 抽奖ing
        } else if (data.lotteryStatus === 1) { // 取消抽奖
        } else if (data.lotteryStatus === 2) { // 抽奖结束
            if (data.LotteryWinInfo.isWinner) {  // 中奖
            } else { // 未中奖
            }
        } else if (data.lotteryStatus === 3) { // 抽奖异常结束

        }
    } else { // 没有抽奖，隐藏抽奖相关
    }
}
```
##### 提交抽奖信息（抽奖2.0）
```javascript
DWLive.commitLottery(commitInfos, callback)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>commitInfos</td>
        <td>object</td>
        <td>抽奖信息</td>
        <td>是</td>
    </tr>
    <tr>
        <td>callback</td>
        <td>object</td>
        <td>回调</td>
        <td>否</td>
    </tr>
</table>


callback返回值说明

```javascript
{
    "lotteryId": "63e60b016d51bf41f85473d9", // 抽奖id
    "collectInfos": [
        {
            "index": 1,
            "value": "123"
        },
        {
            "index": 2,
            "value": "13111111111"
        }
    ]
}
```

使用示例

```javascript
let commitInfos = {
  lotteryId: '' // 抽奖id
  collectInfos: [
    {
      	// 收到中奖信息中对应的 LotteryCollectTemplate.index
        index:int ;
        //用户填写的信息
        value: String ;
    }
  ]
}
DWLive.commitLottery(commitInfos, {
    onSuccess: function (reuslt) {
        console.log('commitLottery:: reuslt', reuslt)
    },
    onError: function (err) {
        console.log('commitLottery:: err', err)
    }
})
```

#### 连麦

api调用时序

![](images/live_interaction.jpg)

##### 请求视频/语音互动

```javascript
DWLive.requestInteraction({
    video: isVideo,
    audio: isAudio
})
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>video</td>
        <td>boolean</td>
        <td>视频互动</td>
        <td>是</td>
    </tr>
        <tr>
        <td>audio</td>
        <td>boolean</td>
        <td>语音互动</td>
        <td>是</td>
    </tr>
</table>

##### 挂断双向视频
```javascript
DWLive.hangupInteraction()
```

##### 讲师接受视频/语音互动
```javascript
window.on_cc_live_interaction_accept = function (data) {}
```
返回data数据说明

```javascript
{
    "video": true,
    "audio": true
}
```

使用示例

```javascript
window.on_cc_live_interaction_accept = function (p) {
  if (p.video) {
    $('li[name="interaction"][t="video"] a').removeClass('audio applying calling').addClass('calling')
    $('#videoInteraction .call-tit').hide()
  } else {
    $('li[name="interaction"][t="audio"] a').removeClass('audio applying calling').addClass('calling')
  }
  $('#interactionMsg').text('通话中...')
  $('#btn-network').addClass('wl-disable')
}
```
##### 已经在聊天的列表信息
```javascript
window.on_cc_live_interaction_chatusers = function (data) {}
```

返回data数据说明

```javascript
[
    {
        "id": "f7500f206d5446c5be9603af74639eb6",
        "name": "js",
        "role": "publisher",
        "avatar": "",
        "isMainSpeaker": true
    },
    {
        "id": "8E4767F8A312EB9F",
        "name": "cc",
        "role": "student",
        "avatar": "",
        "isMainSpeaker": false
    }
]
```

##### 挂断互动信息

```javascript
window.on_cc_live_interaction_disconnect = function (data, type) {}
```

##### 连麦频道内异常事件监听
```javascript
DWLive.onLiveInteractionException = function(evt) {}
```
evt数据说明
```javascript
// 返回值evt说明：解码失败时的evt
{
    'code': 1005,
    'msg': '接收视频解码失败',
    'uid': '88888'
}
// 返回值evt说明：解码恢复正常时的evt
{
    'code': 3005,
    'msg': '接收视频解码恢复正常',
    'uid': '88888'
}
```

## 营销互动

### 概述

支持点赞、打赏、直播带货等互动

### 相关API

#### 组件初始化

##### 完成互动组件服务认证

```javascript
DWLive.onInteractionToken = function (hdtoken) {
  // 互动token
  console.log(hdtoken)
}
```

##### 互动组件服务认证失败
```javascript
DWLive.onInteractiveAuthFailed = function (data) {}
```

##### 房间互动组件配置

```javascript
DWLive.onInteractionSettings = function (data) {}
```

返回data数据说明

```json
{
  likeSwitch: 0, // 点赞开关 0:关闭 1:开启
  gift: {
    giftSwitch: 0, // 打赏开关 0:关闭 1:开启
    specialEffects: 2 // 礼物特效类型
  },
  voteSwitch: 0, // 投票开关 0:关闭 1:开启
  redEnvelopesSwitch: 0, // 红包雨开关 0:关闭 1:开启
  inviteSwitch: 0, // 邀请卡开关 0:关闭 1:开启
  inviteRankSwitch: 0, // 邀请卡排行榜开关 0:关闭 1:开启
  questionnaire: { // 问卷
    state: 0 // 开关 0:关闭 1:开启
  },
  enableInteractionGame: 0, // 互动游戏开关 0:关闭 1:开启
  watchRewardSwitch: 0 // 直播观看奖励开关 0:关闭 1:开启
}
```

#### 点赞

api调用时序

![](images/live_like.jpg)

##### 完成点赞组件初始化
```javascript
window.on_cc_like_ready = function () {}
```

##### 点赞组件初始化失败
```javascript
window.on_cc_like_error = function (error) {}
```

#####  获取点赞数

```javascript
DWLive.getLikeCount()
```

##### 点赞

```javascript
DWLive.addLikeCount(data)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>count</td>
        <td>number</td>
        <td>点赞数</td>
        <td>是</td>
    </tr>
    <tr>
        <td>success</td>
        <td>function</td>
        <td>点赞成功回调</td>
        <td>否</td>
    </tr>
        <tr>
        <td>fail</td>
        <td>function</td>
        <td>点赞失败回调</td>
        <td>否</td>
    </tr>
</table>

使用示例
```javascript
window.on_cc_like_ready = () => {
    console.log('点赞组件完成初始化')
    $('#likeBtn').click(function(){
        DWLive.addLikeCount({
        count: 1, // 必须
        success: () => { 
            console.log('点赞成功')
        },
        fail: (err) => { 
            console.log('点赞失败', err)
        }
        })
    })
}
```

##### 接收点赞推送消息
```javascript
DWLive.receiveLikeInfo = function (data) {}
```
data数据说明
```javascript
8 // 最新点赞总数
```

##### 获取点赞数回调
```javascript
window.on_get_like_count_info = function (data) {}
```
data数据说明
```javascript
{
    status: 200, // 状态码
    statusText: '', // 接口状态描述信息
    data: { // 数据主体
      activityId: string, // 点赞活动ID
      basicNumbers: number, // 基础点赞数
      basicTimes: number, // 基础倍数, 大于等于1
      currentNumbers: number, // 当前点赞总数, 大于等于0
      roomId: string // 房间ID
    }
}
```

##### 断开点赞服务消息监听
```javascript
DWLive.disconnectLike()
```
#### 打赏

api调用时序

![](images/live_gift.jpg)

##### 完成打赏组件初始化
```javascript
window.on_cc_gift_ready = function () {}
```

##### 打赏组件初始化失败
```javascript
window.on_cc_gift_error = function (error) {}
```

##### 获取打赏礼物列表
```javascript
DWLive.getRewardList()
```
使用示例
```javascript
window.on_cc_gift_ready = () => {
    console.log('礼物组件完成初始化')
    DWLive.getRewardList()
}
```

##### 获取打赏历史记录
```javascript
DWLive.getRewardHistoryRecord()
```
使用示例
```javascript
$('#getRewardHistoryRecord').click(function(){
    console.log('获取礼物历史记录列表')
    DWLive.getRewardHistoryRecord()
})
```

##### 获取打赏礼物动效配置
```javascript
DWLive.getRewardSpecialEffects()
```
使用示例
```javascript
$('#getRewardSpecialEffects').click(function(){
    console.log('获取礼物动效配置')
    DWLive.getRewardSpecialEffects()
})
```

##### 打赏礼物
```javascript
DWLive.sendGift(data)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>giftId</td>
        <td>number</td>
        <td>礼物ID</td>
        <td>是</td>
    </tr>
        <tr>
        <td>giftNum</td>
        <td>number</td>
        <td>送礼物数量</td>
        <td>是</td>
    </tr>
        <tr>
        <td>giftType</td>
        <td>function</td>
        <td>礼物类型 默认1</td>
        <td>否</td>
    </tr>
    <tr>
        <td>success</td>
        <td>function</td>
        <td>打赏礼物成功回调</td>
        <td>否</td>
    </tr>
        <tr>
        <td>fail</td>
        <td>function</td>
        <td>打赏礼物失败回调</td>
        <td>否</td>
    </tr>
</table>

使用示例
```javascript
window.on_get_reward_list = (res) => {
    console.log('获取礼物列表', res.data.data)
    const _data = res.data.data
    var cmHtml = "";
    $.each(_data, function (index, data) {
        cmHtml -= Template.gift({
            giftName: data.giftName,
            id: data.id
        })
    })
    $('#gifts').html(cmHtml)
    $('#gifts li').click(function() {
        const giftId = $(this).data('id')
        // console.log(777, $(this).data('id'))
        DWLive.sendGift({
            data: {
                giftId: giftId,
                giftNum: 1,
                giftType: 1
            }, 
            success: () => { 
                console.log('打赏成功')
            },
            fail: (err) => { 
                console.log('打赏失败', err)
            }
        })
    })
}
```

##### 接收打赏礼物推送消息
```javascript
DWLive.receiveRewardInfo = function (data) {}
```
##### 获取打赏礼物列表回调
```javascript
window.on_get_reward_list = function (data) {}
```
data数据说明
```javascript
{
status: 200, // 状态码
statusText: '', // 接口状态描述信息
    data: { // 数据主体
    data: [
        {
        createTime: string, // 创建时间
        giftDefault: number, // 礼物默认类型
        giftName: string, // 礼物名称
        giftStatus: number, // 礼物状态
        giftThumbnail: string, // 礼物图片
        id: number, // 礼物ID
        price number, // 礼物价格（单位分）
        updateTime: string // 更新时间
        }
    ],
    pagination: {
        pageNo: number, // 当前页码
        pageSize: number, // 每页长度
        total: number // 列表长度最大值
    }
    }
}
```

##### 获取打赏礼物历史记录回调

```javascript
window.on_get_reward_history_record = function (data) {}
```
data数据说明
```javascript
// 返回值data说明 (最多返回100条)
{
    status: 200, // 状态码
    statusText: '', // 接口状态描述信息
    data: { // 数据主体
      data: [
        {
          avatar: string, // 打赏人头像
          fromUser: number, // 打赏人昵称
          fromUserId: string, // 打赏人ID
          img: number, // 礼物图片
          name: string, // 礼物名称
          num: number // 打赏礼物个数
        }
      ]
    }
}
```
##### 获取打赏礼物动效配置回调
```javascript
window.on_get_reward_special_effects = function (data) {}
```
data数据说明
```javascript
{
    status: 200, // 状态码
    statusText: '', // 接口状态描述信息
    data: { // 数据主体
      specialEffects: number // 打赏动效类型（1左侧显示 2居中显示）
    }
}
```

##### 断开打赏服务消息监听
```javascript
DWLive.disconnectGift()
```
使用示例
```javascript
$('#disconnectGift').click(function(){
    console.log('已断开礼物服务----')
    DWLive.disconnectGift()
})
```

#### 直播带货

api调用时序

![](images/live_commodity.jpg)

##### 直播带货组件加载完成回调

```javascript
window.on_cc_commodity_ready()
```

#####  直播带货组件加载失败回调

```javascript
window.on_cc_commodity_error(error)
```

#####  接收直播带货推送消息 

> 在助教端进行商品推送、取消推送操作时触发

```javascript
DWLive.receiveCommodityInfo({ onEventName, data })
```

返回值

```javascript
DWLive.receiveCommodityInfo = ({ onEventName, data }) => {
    onEventName: 'live_commerce_push', // live_commerce_push: 推送商品消息  live_commerce_push_del: 取消推送商品消息
    data:{
        id: '商品id', 
        cover: '商品封面' 
        title: '商品标题' 
        currentPrice: '商品现价，到分' 
        originPrice: '商品原价，到分' 
    }
};
```

##### 获取直播带货商品列表

```javascript
DWLive.getCommodityList({pageSize, pageNo})
```

参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>pageSize</td>
        <td>Number</td>
        <td>每页大小</td>
        <td>是</td>
    </tr>
    <tr>
        <td>pageNo</td>
        <td>Number</td>
        <td>页码</td>
        <td>是</td>
    </tr>
</table>

返回值说明

```javascript
const params = { pageSize: 10, pageNo: 1 }
DWLive.getCommodityList(params).then(res => {
    console.log(res)
     // 返回值: 
     {  
        id: '商品id', 
        cover: '商品封面'  
        title: '商品标题' 
        desc: '商品描述' 
        tag: '商品标签，多个以逗号分隔' 
        currentPrice: '商品现价，到分' 
        originPrice: '商品原价，到分' 
        button: '商品按钮文案' 
        top: '商品置顶标记：0' // 0-未置顶；1-置顶 
        push: '商品推送标记：0' // 0-未推送；1-推送 
        score: '商品序号' 
     }  
})
```

#####  获取直播带货商品详情 

```javascript
DWLive.getCommodityDetail(id)
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>id</td>
        <td>String</td>
        <td>商品id</td>
        <td>是</td>
    </tr>
</table>

返回值说明

```javascript
DWLive.getCommodityDetail(id).then(res => {
    console.log(res)
    // 返回值: 
    {  
        id: '商品id', 
        cover: '商品封面'  
        title: '商品标题' 
        currentPrice: '商品现价，到分' 
        originPrice: '商品原价，到分' 
    } 
})
```

#####  获取直播带货商品链接 

```
DWLive.getCommodityLink({ productId: id })
```
参数说明
<table width="900px">
    <tr  style="background:#F60;color:#FFF">
        <td>参数名称</td>
        <td>参数类型</td>
        <td>说明</td>
        <td>是否必须</td>
    </tr>
    <tr>
        <td>ProductId</td>
        <td>String</td>
        <td>商品id</td>
        <td>是</td>
    </tr>
</table>

返回值说明

```javascript
const parasm = { productId: id }
DWLive.getCommodityLink(parasm).then(res => {
    console.log(res)
    // 返回值: 
    { 
        link: '商品链接' 
    } 
})
```

#####  断开直播带货服务消息监听 

```javascript
DWLive.disconnectCommodity()
```


## 备注与说明

### 响应事件返回数据格式说明

响应事件返回的默认都为字符串格式，请自行按需求转化为JSON对象。 

使用直播带货相关api首先需要开启直播带货权限

直播画笔流畅度优化需要使用Windows客户端5.8.3及以上版本

### userRole和fromuserrole对应关系

如下表：  

 <table>
 	<tr>
 		<td>unknow</td>
    	<td>未知角色</td>
    </tr>
     <tr>
         <td>publisher</td>
         <td>主讲</td>
	</tr>
     <tr>
         <td>teacher</td>
         <td>助教</td>
     </tr>
     <tr>
     	<td>host</td>
         <td>主持人</td>
     </tr>
     <tr>
     	<td>student</td>
         <td>学员（观众）</td>
     </tr>
</table>

### 图片、表情、a链接解析处理方法

```javascript
function showEm(str) {
    if (!$.trim(str)) {
        return '';
    }
    str = str.replace(/\</g, '&lt;');
    str = str.replace(/\>/g, '&gt;');
    str = str.replace(/\n/g, '<br/>');
    str = str.replace(/\[em_([0-9]*)\]/g, '<img src="//view.csslcloud.net/img/em/$1.gif" border="0" />');
    str = str.replace(/\[em2_([0-9]*)\]/g, '<img src="//view.csslcloud.net/img/em2/$1.png" border="0" />');
    // 自定义表情解析
    customEmjArr.forEach((item, index) => {
     const emj = customEmjObj[item]
     const pattern = /[`~!@#_$%^&*()=|{}':;',\\\[\\\].<>/?~！@#￥……&*（）——|{}【】‘；：”“'。，、？\s]/g;
     const obj = item.replace(pattern, (match => '\\' - match));
     const reg = new RegExp(obj, 'gim')     
     str = str.replace(reg, `<img src="${emj}" border="0" />`)
   })

    var nmsg = '';    //解析表情
    $.each(str.split(' '), function (i, n) {
        n = $.trim(n);
        if (n.indexOf('[uri_') == 0 && n.indexOf(']') == n.length - 1 && n.length > 6) {
            var u = n.substring(5, n.length - 1) - ' ';
            nmsg -= '<a target="_blank" style="color: #2f53ff" href="' - u - '">' - u - '</a>' - ' ';
        } else {
            nmsg -= n - ' ';
        }
    });

    var nmsg = '';      //解析图片
    var reg = new RegExp(/\[img_http(s)?:\/\/(.*?)\]/g);
    var isImage =reg.test(str)
    if(isImage){
        var sIndex = str.indexOf('_') - 1;
        nmsg = str.slice(sIndex,str.length-1);
        var imgTag = '<div class="chatImage" style="width: 100%" ><img src="'-nmsg-'"  style="width: 100%;cursor:pointer;" onclick="showMsgImage(event)"/></div>';
        return imgTag;
    }

    return nmsg;
}
```

需要发送图片时，格式如下：`[img_http://www.xxx.com]`

需要发送带链接的a标签时，格式如下：[uri_[http://www.xxx.com](http://www.xxx.com/)] （注意：前后都需要加空格）

在收发消息的时候，用showEm('消息内容')处理一下消息内容即可，原理就是匹配[img*url]和[em2**]，让它变为对应的图片或者表情图片，匹配[uri _* ]，让它变为可点击的a链接。

### 直播连麦浏览器支持情况
<table width="900px">
	<tr style="background:#F60;color:#FFF">
		<td>平台</td>
		<td>Chrome</td>
		<td>Firefox</td>
		<td>Safari</td>
		<td>Opera</td>
		<td>QQ 浏览器</td>
		<td>Edge 浏览器</td>
	</tr>
	<tr>
		<td>最低版本</td>
		<td>60-</td>
		<td>56-</td>
		<td>13-</td>
		<td>45-</td>
		<td>10.5-</td>
		<td>80-</td>
	</tr>
</table>
