|
## 1.概述
|
|
|
|
Live_iOS_Play_SDK 是一个适用于iOS平台的直播SDK,使用此SDK可以与CC视频云服务进行对接,在iOS端使用CC视频的直播功能,本SDK只针对iOS手机播放端。
|
|
|
|
|
|
|
|
### 1.1 功能特性
|
|
|
|
| 功能 | 描述 |
|
|
|
|
| :------- | :----------------------------- |
|
|
|
|
| 直播视频 | 观看直播视频 |
|
|
|
|
| 文档展示 | 能够观看当前直播文档 |
|
|
|
|
| 线路更换 | 观看卡顿请换个线路 |
|
|
|
|
| 清晰度 | 支持直播多清晰度切换播放 |
|
|
|
|
| 答题卡 | 支持实时检测课堂学生的掌握程度 |
|
|
|
|
| 问答 | 能够发送问题和接受回答信息 |
|
|
|
|
| 简介 | 支持对直播间的信息展示 |
|
|
|
|
| 问卷 | 支持对观看直播的人进行信息采集 |
|
|
|
|
| 广播 | 支持发送全体消息 |
|
|
|
|
| 连麦 | 支持与直播人员进行音视频沟通 |
|
|
|
|
| 签到 | 支持签到功能 |
|
|
|
|
| 抽奖 | 支持抽奖功能 |
|
|
|
|
| 投票 | 支持投票功能 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 1.2 阅读对象
|
|
|
|
本文档为技术文档,需要阅读者:
|
|
|
|
* 具备基本的iOS开发能力
|
|
|
|
* 准备接入CC视频的直播SDK相关功能
|
|
|
|
* 对CC云直播产品使用方法有基础的了解,[使用帮助地址](http://doc.bokecc.com/live/manual/introduction/)
|
|
|
|
## 2.开发准备
|
|
|
|
|
|
|
|
### 2.1 开发环境
|
|
|
|
* Xcode : Xcode 开发IDE
|
|
|
|
### 2.2错误码及错误描述
|
|
|
|
```
|
|
|
|
(1). 业务错误
|
|
|
|
|
|
|
|
typedef NS_ENUM(NSInteger, ERROR_SERVICE_TYPE) {
|
|
# 1.概述
|
|
|
|
|
|
ERROR_ROOM_STATE = 1001,//@"直播间状态不可用,可能没有开始推流"
|
|
## 1.1 阅读对象
|
|
|
|
|
|
ERROR_USELESS_INFO = 1002,//@"没有获取到有用的视频信息"
|
|
本文档为技术文档,需要阅读者:
|
|
|
|
|
|
ERROR_PASSWORD = 1003,//@"密码错误"
|
|
- 具备基本的iOS开发能力
|
|
|
|
- 准备接入CC视频的直播SDK相关功能
|
|
|
|
- 对CC云直播产品使用方法有基础的了解,[使用帮助地址](https://doc.bokecc.com/live/)
|
|
|
|
|
|
};
|
|
##1.2 功能特性
|
|
|
|
|
|
(2). 系统错误
|
|
| 功能 | 描述 |
|
|
|
|
| -------- | ---------------------------------------- |
|
|
|
|
| 直播视频 | 观看直播视频 |
|
|
|
|
| 文档展示 | 能够观看当前直播文档,文档添加水印 |
|
|
|
|
| 线路更换 | 观看卡顿请换个线路 |
|
|
|
|
| 清晰度 | 支持直播多清晰度切换播放 |
|
|
|
|
| 答题卡 | 支持实时检测课堂学生的掌握程度 |
|
|
|
|
| 问答 | 能够发送问题和接受回答信息 |
|
|
|
|
| 简介 | 支持对直播间的信息展示 |
|
|
|
|
| 问卷 | 支持对观看直播的人进行信息采集 |
|
|
|
|
| 广播 | 支持发送全体消息 |
|
|
|
|
| 连麦 | 支持与直播人员进行音视频沟通 |
|
|
|
|
| 签到 | 支持签到功能 |
|
|
|
|
| 抽奖 | 支持抽奖功能 |
|
|
|
|
| 随堂测 | 支持随堂测互动 |
|
|
|
|
| 修改昵称 | 支持自定义昵称 |
|
|
|
|
| 聊天互动 | 支持与房间内的其他人聊天互动和一对一私聊 |
|
|
|
|
| 跑马灯 | 支持直播防录屏功能 |
|
|
|
|
|
|
|
|
|
|
|
|
# 2.开发准备
|
|
|
|
|
|
|
|
## 2.1 开发环境
|
|
|
|
|
|
typedef NS_ENUM(NSInteger, ERROR_SYSTEM_TYPE) {
|
|
- Xcode : Xcode 开发IDE
|
|
|
|
- Version 10.0 及以上
|
|
|
|
|
|
|
|
##2.2 SDK配置
|
|
|
|
|
|
|
|
### 2.2.1 CocoaPods集成
|
|
|
|
|
|
|
|
**已安装CocoaPods**
|
|
|
|
|
|
|
|
```
|
|
|
|
如果是有连麦的SDK:
|
|
|
|
pod 'CCLivePlaySDK', '~> 3.8.0'
|
|
|
|
如果是无连麦的SDK:
|
|
|
|
pod 'CCLivePlaySDK', :podspec => 'https://raw.githubusercontent.com/CCVideo/Live_iOS_Play_SDK/3.8.0/CCLivePlaySDK.podspec'
|
|
|
|
|
|
|
|
注:3.8.0为版本号,修改为自己想要的版本号即可
|
|
|
|
```
|
|
|
|
|
|
|
|
**未安装CocoaPods**
|
|
|
|
|
|
|
|
1. 安装CocoaPods
|
|
|
|
|
|
|
|
打开终端:>_
|
|
|
|
1、查看当前Ruby版本
|
|
|
|
|
|
|
|
```
|
|
|
|
ruby -v
|
|
|
|
```
|
|
|
|
|
|
ERROR_RETURNDATA = 1004,//@"返回内容格式错误"
|
|
2、升级Ruby环境,首先需要安装rvm(第一步要下载一些东西等两分钟左右)
|
|
|
|
|
|
ERROR_PARAMETER = 1005,//@"可能是参数错误"
|
|
```
|
|
|
|
curl -L get.rvm.io | bash -s stable
|
|
|
|
source ~/.bashrc
|
|
|
|
source ~/.bash_profile
|
|
|
|
```
|
|
|
|
|
|
|
|
3、查看rvm版本
|
|
|
|
|
|
|
|
```
|
|
|
|
rvm -v
|
|
|
|
|
|
|
|
显示如下(或者是其他版本)
|
|
|
|
rvm 1.29.3 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]
|
|
|
|
```
|
|
|
|
|
|
|
|
4、列出ruby可安装的版本信息
|
|
|
|
|
|
|
|
```
|
|
|
|
rvm list known
|
|
|
|
|
|
|
|
显示如下
|
|
|
|
# MRI Rubies
|
|
|
|
[ruby-]1.8.6[-p420]
|
|
|
|
[ruby-]1.8.7[-head] # security released on head
|
|
|
|
[ruby-]1.9.1[-p431]
|
|
|
|
[ruby-]1.9.2[-p330]
|
|
|
|
[ruby-]1.9.3[-p551]
|
|
|
|
[ruby-]2.0.0[-p648]
|
|
|
|
[ruby-]2.1[.10]
|
|
|
|
[ruby-]2.2[.10]
|
|
|
|
[ruby-]2.3[.7]
|
|
|
|
[ruby-]2.4[.4]
|
|
|
|
[ruby-]2.5[.1] // 重点在这里 重点在这里 重点在这里
|
|
|
|
[ruby-]2.6[.0-preview2] // 测试版
|
|
|
|
ruby-head
|
|
|
|
.....
|
|
|
|
```
|
|
|
|
|
|
ERROR_NETWORK = 1006,//@"网络错误"
|
|
5、安装一个ruby版本
|
|
|
|
|
|
};
|
|
```
|
|
|
|
rvm install 2.5.1
|
|
|
|
// 注意:安装过程中需要两次按下 Enter 键, 第二次按下后需要输入电脑访问密码(不可见,只管输入就行);
|
|
|
|
// 如果你电脑没有安装Xcode和Command Line Tools for Xcode以及Homebrew 会自动下载安装,建议提前安装这三者.
|
|
|
|
|
|
|
|
|
|
|
|
这里很多小伙伴会遇到错误,大部分是因为没有安装Homebrew造成,所以所以所以要提前安装比较好
|
|
|
|
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
|
|
|
```
|
|
|
|
|
|
```
|
|
6、设置为默认版本
|
|
|
|
|
|
|
|
```
|
|
|
|
rvm use 2.5.1 --default
|
|
|
|
```
|
|
|
|
|
|
|
|
7、更换源
|
|
|
|
|
|
**日志工具类**
|
|
```
|
|
(1) 单例模式
|
|
sudo gem update --system
|
|
|
|
|
|
|
|
gem sources --remove https://rubygems.org/
|
|
|
|
|
|
|
|
gem sources --add https://gems.ruby-china.com/
|
|
|
|
```
|
|
|
|
|
|
```
|
|
8、为了验证你的Ruby镜像是并且仅是ruby-china,执行以下命令查看
|
|
/**
|
|
|
|
|
|
|
|
- @brief 获取单例对象
|
|
```
|
|
*/
|
|
gem sources -l
|
|
|
|
|
|
|
|
|
|
|
|
如果是以下结果说明正确,如果有其他的请自行百度解决
|
|
|
|
*** CURRENT SOURCES ***
|
|
|
|
|
|
|
|
https://gems.ruby-china.com/
|
|
|
|
```
|
|
|
|
|
|
- (instancetype)sharedInstance;
|
|
9、这时候才正式开始安装CocoaPods
|
|
|
|
|
|
/**
|
|
```
|
|
|
|
sudo gem install -n /usr/local/bin cocoapods
|
|
|
|
```
|
|
|
|
|
|
- @brief 是否需要存储日志信息到文件中,最好在AppDelegate类里面调用,这样就适用于全局日
|
|
10、如果安装了多个Xcode使用下面的命令选择(一般需要选择最近的Xcode版本)
|
|
- 志的存储,当然中途调用也可以,从调用后开始应用之后的日志存储逻辑
|
|
|
|
*/
|
|
|
|
-(void)isNeedToSaveLog:(BOOL)needsave;
|
|
|
|
|
|
|
|
/**
|
|
```
|
|
|
|
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
|
|
|
|
```
|
|
|
|
|
|
- @brief 存储日志的信息
|
|
11、安装本地库
|
|
- action相当于key,也可以理解为存储的事件名称
|
|
|
|
- logStr相当于value,也可以理解为存储的日志信息字符串
|
|
|
|
*/
|
|
|
|
-(void)saveLog:(NSString *)logStr action:(NSString *)action;
|
|
|
|
|
|
|
|
```
|
|
```
|
|
|
|
pod setup
|
|
|
|
```
|
|
|
|
|
|
|
|
12、执行以上命令后
|
|
|
|
|
|
|
|
```
|
|
|
|
Setting up CocoaPods master repo
|
|
|
|
$ /usr/bin/git clone https://github.com/CocoaPods/Specs.git master --progress
|
|
|
|
Cloning into 'master'...
|
|
|
|
remote: Counting objects: 1879515, done.
|
|
|
|
remote: Compressing objects: 100% (321/321), done.
|
|
|
|
Receiving objects: 21% (404525/1879515), 73.70 MiB | 22.00 KiB/
|
|
|
|
然后就是漫长的等待,当然,网络好的情况下会更快
|
|
|
|
```
|
|
|
|
|
|
(2) 示例应用及说明
|
|
2. 在Podfile文件中添加
|
|
|
|
|
|
```
|
|
```
|
|
在CCSDK中相关的信息已经做了日志打印的相关处理操作,但是在demo中也添加了几句话,用户也可以自定义添加自己需要的日志,用于记录或者调试都可以。
|
|
如果是有连麦的SDK:
|
|
|
|
pod 'CCLivePlaySDK', '~> 3.8.0'
|
|
|
|
如果是无连麦的SDK:
|
|
|
|
pod 'CCLivePlaySDK', '~> 3.8.0', :podspec => 'https://raw.githubusercontent.com/CCVideo/Live_iOS_Play_SDK/master/CCLivePlaySDK.podspec'
|
|
|
|
```
|
|
|
|
|
|
注意:
|
|
3. 在终端中执行
|
|
|
|
|
|
1) SDK中设置的日志存储目录为:NSHomeDirectory()/Library/CCLog/ ,存储文件名为yyyy-MM-dd.log
|
|
```
|
|
|
|
pod install
|
|
|
|
```
|
|
|
|
|
|
2) SDK中如果开启了日志存储以后,日志只存不删,需要使用者按照自己的逻辑进行删除
|
|
**ps:目前CocoaPods集成仅支持3.8.0及以后的版本,旧版本暂不支持CocoaPods集成**
|
|
|
|
|
|
1. 在AppDelegate.m中添加了
|
|
|
|
[[SaveLogUtil sharedInstance]isNeedToSaveLog:YES];
|
|
|
|
表示设置为记录日志log
|
|
|
|
2. 在PlayForPCVC.m中添加了
|
|
|
|
[[SaveLogUtil sharedInstance] saveLog:@"" action:@"视频加载成功或开始播放,多次调用,不必关心"];
|
|
|
|
表示视频加载成功或开始播放
|
|
|
|
3. PlayBackVC.m中添加了
|
|
|
|
[[SaveLogUtil sharedInstance] saveLog:@"" action:@"视频加载成功或开始播放,多次调用,不必关心"];
|
|
|
|
表示视频加载成功或开始播放
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
###2.2.2 手动集成
|
|
|
|
|
|
|
|
1.将SDK文件夹内的所有文件拖到项目中
|
|
|
|
|
|
## 3. 快速集成
|
|
```
|
|
|
|
command + b 编译,如果报错" file '...xxx/IJKMediaFramework.framework/IJKMediaFramework' for architecture arm64 "
|
|
|
|
解决方案:
|
|
|
|
Targets -> Build Settings -> 搜索 "Enable Bitcode" 设置为 "NO"
|
|
|
|
```
|
|
|
|
2.command + r 运行
|
|
|
|
|
|
首先,需要下载最新版本的SDK,下载地址为:[Live_iOS_Play_SDK](https://github.com/CCVideo/Live_iOS_Play_SDK)
|
|
```
|
|
集成前需要知道的事情:
|
|
如果报错" dyld: Library not loaded: @rpath/XXX.framework "
|
|
1. 工程分三个部分:一个有连麦功能(Demo-观看端有连麦),体积较大,一个无连麦功能(Demo-观看端无连麦),体积较小,第三个部分是离线下载回放(Demo-离线下载),其中离线下载回放中的CCSDK用有连麦的库和无连麦的库都可以,示例中用的无连麦的库(体积较小)
|
|
解决方案:
|
|
2. (重要)本SDK只支持真机,不支持模拟器
|
|
Targets -> Build Phases ->
|
|
3. (重要)本SDK只支持iOS8.0及以上版本,iOS7.x版本不支持
|
|
点击左上角 "+" 按钮 ->
|
|
4. (重要) 当使用有连麦工程时,分为音视频连麦和音频连麦两种连麦,有连麦的demo中没有以页面体现两种连麦的按钮,当选中简介时,连麦为音视频连麦,当选中 文档,聊天或问答任意一个时,连麦为音频连麦,代码使中用_isAudioVideo加以区分,当_isAudioVideo==YES;时为音视频连麦,当_isAudioVideo==NO;时为音频连麦
|
|
选择 "New Copy Files Phase" ->
|
|
### 3.1 导入framework
|
|
点击新添加的 Copy Files 前面的下拉箭头 ->
|
|
三个工程SDK目录都在工程目录下的CCSDK文件夹中,文件夹中的所有文件都属于SDK部分,应全部应用(注意不要遗漏socketio.html文件)
|
|
Destination 选择 "Frameworks" ->
|
|
|
|
点击当前目录下的 "+" 将SDK包含的.framework 包添加即可
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 3.2 Demo
|
|
|
|
1. Demo-观看端有连麦实现了基本的播放,在线回放逻辑,可以直接运行
|
|
|
|
2. Demo-观看端无连麦实现了基本的播放,在线回放逻辑,可以直接运行,除无连麦外,功能同上
|
|
|
|
3. Demo-离线下载实现了基本的离线下载和离线回放逻辑,可以直接运行(其中的CCSDK用4,5两个工程中的任意一个CCSDK文件夹即可)
|
|
|
|
|
|
|
|
### 3.3 配置依赖库
|
|
##2.3 日志存储
|
|
|
|
|
|
在项目/General/Linked framework and libraries 中不要忘记添加对用的依赖
|
|
在AppDelegate.m文件导入头文件
|
|
|
|
|
|
**基础配置类PlayParameter**
|
|
|
|
```
|
|
```
|
|
@property(nonatomic, copy)NSString *userId;//用户ID
|
|
#import "CCSDK/SaveLogUtil.h"
|
|
@property(nonatomic, copy)NSString *roomId;//房间ID
|
|
|
|
@property(nonatomic, copy)NSString *viewerName;//用户名称
|
|
|
|
@property(nonatomic, copy)NSString *token;//房间密码
|
|
|
|
@property(nonatomic, copy)NSString *liveId;//回放ID,回放时才用到
|
|
|
|
@property(nonatomic, copy)NSString *recordId;//回放ID
|
|
|
|
@property(nonatomic, copy)NSString *viewerCustomua;//用户自定义参数,需和后台协商,没有定制传@""
|
|
|
|
@property(nonatomic, copy)NSString *destination;//下载文件解压到的目录路径(离线下载相关)
|
|
|
|
@property(nonatomic,strong)UIView *docParent;//文档父类窗口
|
|
|
|
@property(nonatomic,assign)CGRect docFrame;//文档区域
|
|
|
|
@property(nonatomic,strong)UIView *playerParent;//视频父类窗口
|
|
|
|
@property(nonatomic,assign)CGRect playerFrame;//视频区域
|
|
|
|
@property(nonatomic,assign)BOOL security;//是否使用https,静态库暂时只能使用http协议
|
|
|
|
/*
|
|
|
|
* 0:IJKMPMovieScalingModeNone
|
|
|
|
* 1:IJKMPMovieScalingModeAspectFit
|
|
|
|
* 2:IJKMPMovieScalingModeAspectFill
|
|
|
|
* 3:IJKMPMovieScalingModeFill
|
|
|
|
*/
|
|
|
|
@property(assign, nonatomic)NSInteger scalingMode;//屏幕适配方式,含义见上面
|
|
|
|
@property(nonatomic,strong)UIColor *defaultColor;//ppt默认底色,不设置(nil)默认为白色
|
|
|
|
@property(nonatomic,assign)BOOL pauseInBackGround;//后台是否继续播放,注意:如果开启后台播放需要打开 xcode->Capabilities->Background Modes->on->Audio,AirPlay,and Picture in Picture
|
|
|
|
/*
|
|
|
|
* PPT适配模式分为三种,
|
|
|
|
* 1.一种是全部填充屏幕,可拉伸变形,
|
|
|
|
* 2.第二种是等比缩放,横向或竖向贴住边缘,另一方向可以留黑边,
|
|
|
|
* 3.第三种是等比缩放,横向或竖向贴住边缘,另一方向出边界,裁剪PPT,不可以留黑边
|
|
|
|
* 4.根据直播间文档显示模式的返回值进行设置(推荐)(The New Method)
|
|
|
|
*/
|
|
|
|
@property(assign, nonatomic)NSInteger PPTScalingMode;//PPT适配方式,含义见上面
|
|
|
|
/**
|
|
|
|
* json格式字符串,可选,自定义用户信息,该信息会记录在用户访问记录中,用于统计分析使用(长度不能超过1000个字符,若直播间启用接口验证则该参数无效)如果不需要的话就不要传值
|
|
|
|
* 格式如下:
|
|
|
|
* viewercustominfo: '{"exportInfos": [ {"key": "城市", "value": "北京"}, {"key": "姓名", "value": "哈哈"}]}'
|
|
|
|
*/
|
|
|
|
@property(nonatomic, copy)NSString *viewercustominfo;
|
|
|
|
```
|
|
```
|
|
|
|
|
|
### 3.4 登录直播间
|
|
在启动方法中添加日志存储
|
|
**可以登录也可以不登录,本文档是按照需要登录设计的,如不需登录请跳过3.4**
|
|
|
|
(1). 首先导入头文件
|
|
|
|
```
|
|
|
|
#import "CCSDK/CCLiveUtil.h"
|
|
|
|
#import "CCSDK/RequestData.h"
|
|
|
|
```
|
|
|
|
(2). 配置参数
|
|
|
|
```
|
|
|
|
PlayParameter *parameter = [[PlayParameter alloc] init];
|
|
|
|
parameter.userId = @"用户ID";
|
|
|
|
parameter.roomId = @"房间ID";
|
|
|
|
parameter.viewerName = @"用户名称";
|
|
|
|
parameter.token = @"房间密码";
|
|
|
|
parameter.security = @"是否使用https,静态库暂时只能使用http协议";
|
|
|
|
parameter.viewerCustomua = @"viewercustomua";
|
|
|
|
RequestData *requestData = [[RequestData alloc] initLoginWithParameter:parameter];
|
|
|
|
requestData.delegate = self;//需要实现RequestDataDelegate代理方法
|
|
|
|
```
|
|
|
|
(3). 实现代理方法
|
|
|
|
```
|
|
|
|
#pragma mark - RequestDataDelegate
|
|
|
|
//@optional
|
|
|
|
/**
|
|
|
|
* @brief 请求成功
|
|
|
|
*/
|
|
|
|
-(void)loginSucceedPlayBack {
|
|
|
|
控制器跳转
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
|
/**
|
|
/**
|
|
* @brief 登录请求失败
|
|
* @brief 是否存储日志
|
|
*/
|
|
*/
|
|
-(void)loginFailed:(NSError *)error reason:(NSString *)reason {
|
|
[[SaveLogUtil sharedInstance]isNeedToSaveLog:YES];
|
|
NSString *message = nil;
|
|
return YES;
|
|
if (reason == nil) {
|
|
|
|
message = [error localizedDescription];
|
|
|
|
} else {
|
|
|
|
message = reason;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
```
|
|
```
|
|
### 3.5 开启观看视频直播
|
|
|
|
跳转到直播页面配置观看直播同样需要导入头文件
|
|
|
|
```
|
|
|
|
#import "CCSDK/CCLiveUtil.h"
|
|
|
|
#import "CCSDK/RequestData.h"
|
|
|
|
```
|
|
|
|
配置参数,和登录时配置的参数差不多,很多参数都是登录传过来的
|
|
|
|
```
|
|
|
|
PlayParameter *parameter = [[PlayParameter alloc] init];
|
|
|
|
parameter.userId = @"登录传过来的";
|
|
|
|
parameter.roomId = @"登录传过来的";
|
|
|
|
parameter.viewerName = @"用户名称";
|
|
|
|
parameter.token = @"房间密码";
|
|
|
|
parameter.playerParent = self.videoView;//视频父类窗口
|
|
|
|
parameter.playerFrame = _videoRect//视频区域;
|
|
|
|
parameter.security = NO;
|
|
|
|
parameter.PPTScalingMode = 2;
|
|
|
|
parameter.defaultColor = [UIColor whiteColor];
|
|
|
|
parameter.scalingMode = 1;
|
|
|
|
parameter.pauseInBackGround = NO;
|
|
|
|
parameter.viewerCustomua = @"viewercustomua";
|
|
|
|
_requestData = [[RequestData alloc] initWithParameter:parameter];
|
|
|
|
|
|
|
|
```
|
|
## 2.4 错误码
|
|
|
|
服务错误类型
|
|
|
|
|
|
### 3.6 文档观看
|
|
|
|
PlayParameter增加两个属性
|
|
|
|
```
|
|
```
|
|
@property(nonatomic,strong)UIView *docParent;//文档父类窗口
|
|
ERROR_SERVICE_TYPE
|
|
@property(nonatomic,assign)CGRect docFrame;//文档区域
|
|
|
|
|
|
ERROR_ROOM_STATE = 1001 直播间状态不可用,可能没有开始推流
|
|
|
|
ERROR_USELESS_INFO = 1002 没有获取到有用的视频信息
|
|
|
|
ERROR_PASSWORD = 1003 密码错误
|
|
```
|
|
```
|
|
## 4. 功能使用
|
|
系统错误类型
|
|
### 4.1 RequestData直播请求类介绍
|
|
|
|
#### 4.1.1 在直播类PlayViewController.m文件中主要调用此类来和此SDK交互
|
|
|
|
|
|
|
|
#### 4.1.2 RequestData中的成员变量
|
|
|
|
```
|
|
```
|
|
@property (weak,nonatomic) id<RequestDataDelegate> delegate;//代理
|
|
ERROR_SYSTEM_TYPE
|
|
@property (retain, atomic) id<IJKMediaPlayback> ijkPlayer;//播放器
|
|
|
|
|
|
ERROR_RETURNDATA = 1004 返回内容格式错误
|
|
|
|
ERROR_PARAMETER = 1005 直播间信息填写错误
|
|
|
|
ERROR_NETWORK = 1006 网络异常
|
|
|
|
ERROR_LOGINDATA = 1007 登录
|
|
|
|
ERROR_PLAYERURL = 1008 视频播放地址
|
|
|
|
ERROR_QUESTIONLIST = 1009 问卷列表
|
|
|
|
ERROR_STATISTICAL = 1010 问卷统计
|
|
|
|
ERROR_DOCLIST = 1011 文档列表
|
|
|
|
ERROR_HISTORY = 1012 历史信息
|
|
|
|
PRACTICE_LIST = 1013 随堂测试
|
|
|
|
PRACTICECOMMIT = 1014 提交随堂测试
|
|
|
|
PRACTICESTATIS = 1015 获取随堂测统计
|
|
|
|
PRACTICERANK = 1016 获取随堂测排名
|
|
|
|
ERROR_SOCKET = 1017 socket加载失败
|
|
|
|
ERROR_PUNCH = 1018 获取打卡信息失败
|
|
|
|
ERROR_PUNCHCOMMIT = 1019 获取打卡提交结果失败
|
|
|
|
ERROR_DRMURL = 1020 获取加密地址失败
|
|
```
|
|
```
|
|
#### 4.1.3 RequestData中的成员方法
|
|
|
|
|
|
|
|
(1). 初始化登录
|
|
|
|
|
|
# 3.快速集成
|
|
|
|
|
|
|
|
## 3.1 配置参数
|
|
|
|
|
|
|
|
3.1.1 调用方法
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 登录房间
|
|
* @brief 登录房间
|
|
* @param parameter 配置参数信息
|
|
* @param parameter 配置参数信息
|
|
* 必填参数 userId;
|
|
* 必填参数 userId; //用户ID
|
|
* 必填参数 roomId;
|
|
* 必填参数 roomId; //房间ID
|
|
* 必填参数 viewerName;
|
|
* 必填参数 viewerName; //用户名
|
|
* 必填参数 token;
|
|
* 必填参数 token; //房间密码
|
|
* 必填参数 security;
|
|
* (已弃用!) security //是否使用https
|
|
* (选填参数) viewercustomua;
|
|
* (选填参数) viewercustomua; //用户自定义参数,需和后台协商,没有定制传@""
|
|
*/
|
|
*/
|
|
- (id)initLoginWithParameter:(PlayParameter *)parameter;
|
|
- (id)initLoginWithParameter:(PlayParameter *)parameter;
|
|
```
|
|
/**
|
|
(2). 进入房间
|
|
* @brief 进入房间,并请求画图聊天数据并播放视频(可以不登陆,直接从此接口进入直播间)
|
|
```
|
|
* @param parameter 配置参数信息
|
|
/**
|
|
* 必填参数 userId; //用户ID
|
|
* @brief 进入房间,并请求画图聊天数据并播放视频(可以不登陆,直接从此接口进入直播间)
|
|
* 必填参数 roomId; //房间ID
|
|
* @param parameter 配置参数信息
|
|
* 必填参数 viewerName; //用户名称
|
|
* 必填参数 userId;
|
|
* 必填参数 token; //房间密码
|
|
* 必填参数 roomId;
|
|
* 必填参数 docParent; //文档父类窗口
|
|
* 必填参数 viewerName;
|
|
* 必填参数 docFrame; //文档区域
|
|
* 必填参数 token;
|
|
* 必填参数 playerParent; //视频父类窗口
|
|
* 必填参数 docParent;
|
|
* 必填参数 playerFrame; //视频区域
|
|
* 必填参数 docFrame;
|
|
* 必填参数 scalingMode; //屏幕适配方式
|
|
* 必填参数 playerParent;
|
|
* (已弃用!) security //是否使用https
|
|
* 必填参数 playerFrame;
|
|
* 必填参数 defaultColor; //ppt默认底色,不写默认为白色
|
|
* 必填参数 PPTScalingMode;
|
|
* 必填参数 PPTScalingMode; //PPT适配方式 PPT适配模式分为四种,1.一种是全部填充屏幕,可拉伸变形,2.第二种是等比缩放,横向或竖向贴住边缘,另一方向可以留黑边,3.第三种是等比缩放,横向或竖向贴住边缘,另一方向出边界,裁剪PPT,不可以留黑边,4.根据直播间文档显示模式的返回值进行设置(推荐)(The New Method)
|
|
* 必填参数 security;
|
|
* 必填参数 pauseInBackGround; //后台是否继续播放,注意:如果开启后台播放需要打开 xcode->Capabilities->Background Modes->on->Audio,AirPlay,and Picture in Picture
|
|
* 必填参数 defaultColor;
|
|
* (选填参数)viewercustomua; //用户自定义参数,需和后台协商,没有定制传@""
|
|
* 必填参数 scalingMode;
|
|
*/
|
|
* 必填参数 pauseInBackGround;
|
|
|
|
* (选填参数) viewercustomua;
|
|
|
|
*/
|
|
|
|
- (id)initWithParameter:(PlayParameter *)parameter;
|
|
- (id)initWithParameter:(PlayParameter *)parameter;
|
|
```
|
|
```
|
|
(3). 提问
|
|
|
|
|
|
代理方法
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 提问
|
|
* @brief 登录成功
|
|
* @param message 提问内容
|
|
*/
|
|
*/
|
|
- (void)loginSucceedPlay;
|
|
- (void)question:(NSString *)message;
|
|
|
|
```
|
|
|
|
(4). 发送公聊
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 发送公聊信息
|
|
* @brief 登录失败
|
|
* @param message 发送的消息内容
|
|
*/
|
|
*/
|
|
-(void)loginFailed:(NSError *)error reason:(NSString *)reason;
|
|
- (void)chatMessage:(NSString *)message;
|
|
|
|
```
|
|
|
|
(5). 发送私聊
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 发送私聊信息
|
|
* @brief 请求成功
|
|
*/
|
|
*/
|
|
- (void)privateChatWithTouserid:(NSString *)touserid msg:(NSString *)msg;
|
|
-(void)requestSucceed;
|
|
```
|
|
|
|
(6). 退出播放时销毁文档和视频
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 销毁文档和视频,清除视频和文档的时候需要调用,推出播放页面的时候也需要调用
|
|
* @brief 登录请求失败
|
|
*/
|
|
*/
|
|
- (void)requestCancel;
|
|
-(void)requestFailed:(NSError *)error reason:(NSString *)reason;
|
|
```
|
|
```
|
|
(7). 房间人数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3.1.2 集成
|
|
|
|
|
|
|
|
导入头文件
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
#import "CCSDK/RequestData.h"//SDK
|
|
* @brief 获取在线房间人数,当登录成功后即可调用此接口,登录不成功或者退出登录后就不可以调用了,如果要求实时性比较强的话,可以写一个定时器,不断调用此接口,几秒钟发一次就可以,然后在代理回调函数中,处理返回的数据
|
|
|
|
*/
|
|
|
|
- (void)roomUserCount;
|
|
|
|
```
|
|
```
|
|
(8). 文档宽高比
|
|
|
|
|
|
声明变量
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
@property (nonatomic,strong)RequestData * requestData;//sdk
|
|
* @brief 获取文档区域内白板或者文档本身的宽高比,返回值即为宽高比,做屏幕适配用
|
|
|
|
*/
|
|
|
|
- (CGFloat)getDocAspectRatio;
|
|
|
|
```
|
|
```
|
|
(9). 改变文档区域大小
|
|
|
|
|
|
配置参数:PlayParameter的属性如下
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 改变文档区域大小,主要用在文档生成后改变文档窗口的frame
|
|
* @brief 用户ID
|
|
*/
|
|
*/
|
|
- (void)changeDocFrame:(CGRect) docFrame;
|
|
@property(nonatomic, copy)NSString *userId;//用户ID
|
|
```
|
|
|
|
(10). 改变播放器frame
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 改变播放器frame
|
|
* @brief 房间ID
|
|
*/
|
|
*/
|
|
- (void)changePlayerFrame:(CGRect) playerFrame;
|
|
@property(nonatomic, copy)NSString *roomId;//房间ID
|
|
```
|
|
|
|
(11). 改变播放器父窗口
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 改变播放器父窗口
|
|
* @brief 用户名称
|
|
*/
|
|
*/
|
|
- (void)changePlayerParent:(UIView *) playerParent;
|
|
@property(nonatomic, copy)NSString *viewerName;//用户名称
|
|
```
|
|
|
|
(12). 改变文档父窗口
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 改变文档父窗口
|
|
* @brief 房间密码
|
|
*/
|
|
*/
|
|
- (void)changeDocParent:(UIView *) docParent;
|
|
@property(nonatomic, copy)NSString *token;//房间密码
|
|
```
|
|
|
|
(13). 播放器暂停
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 播放器暂停
|
|
* @brief 用户自定义参数,需和后台协商,没有定制传@""
|
|
*/
|
|
*/
|
|
- (void)pausePlayer;
|
|
@property(nonatomic, copy)NSString *viewerCustomua;//用户自定义参数,需和后台协商,没有定制传@""
|
|
```
|
|
|
|
(14). 播放器播放
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 播放器播放
|
|
* json格式字符串,可选,自定义用户信息,该信息会记录在用户访问记录中,用于统计分析使用(长度不能超过1000个字符,若直播间启用接口验证则该参数无效)如果不需要的话就不要传值
|
|
*/
|
|
* 格式如下:
|
|
- (void)startPlayer;
|
|
* viewercustominfo: '{"exportInfos": [ {"key": "城市", "value": "北京"}, {"key": "姓名", "value": "哈哈"}]}'
|
|
```
|
|
*/
|
|
(15). 播放器关闭并移除
|
|
@property(nonatomic, copy)NSString *viewercustominfo;
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 播放器关闭并移除
|
|
* @brief 文档父类窗口
|
|
*/
|
|
*/
|
|
- (void)shutdownPlayer;
|
|
@property(nonatomic,strong)UIView *docParent;//文档父类窗口
|
|
```
|
|
|
|
(16). 播放器停止
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 播放器停止
|
|
* @brief 文档区域
|
|
*/
|
|
*/
|
|
- (void)stopPlayer;
|
|
@property(nonatomic,assign)CGRect docFrame;//文档区域
|
|
```
|
|
|
|
(17). 切换播放线路
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 切换播放线路
|
|
* @brief 视频父类窗口
|
|
* firIndex表示第几个源
|
|
*/
|
|
* key表示该源对应的描述信息
|
|
@property(nonatomic,strong)UIView *playerParent;//视频父类窗口
|
|
*/
|
|
|
|
- (void)switchToPlayUrlWithFirIndex:(NSInteger)firIndex key:(NSString *)key;
|
|
|
|
```
|
|
|
|
(18). 重新加载视频
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* 重新加载视频,参数force表示是否强制重新加载视频,
|
|
|
|
* 一般重新加载视频的时间间隔应该超过3秒,如果强制重新加载视频,时间间隔可以在3S之内
|
|
|
|
*/
|
|
|
|
-(void)reloadVideo:(BOOL)force;
|
|
|
|
```
|
|
|
|
(19). 签到
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
*签到
|
|
|
|
*/
|
|
|
|
-(void)answer_rollcall;
|
|
|
|
```
|
|
|
|
(20). 答单选题
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
*答单选题
|
|
|
|
*/
|
|
|
|
-(void)reply_vote_single:(NSInteger)index;
|
|
|
|
```
|
|
|
|
(21). 答多选题
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
*答多选题
|
|
|
|
*/
|
|
|
|
-(void)reply_vote_multiple:(NSMutableArray *)indexArray;
|
|
|
|
```
|
|
|
|
(22). 播放器是否播放
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 播放器是否播放
|
|
* @brief 视频区域
|
|
*/
|
|
*/
|
|
- (BOOL)isPlaying;
|
|
@property(nonatomic,assign)CGRect playerFrame;//视频区域
|
|
```
|
|
|
|
(23). 设置后台是否可播放
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 设置后台是否可播放
|
|
* @brief
|
|
*/
|
|
* 0:IJKMPMovieScalingModeNone
|
|
- (void)setpauseInBackGround:(BOOL)pauseInBackGround;
|
|
* 1:IJKMPMovieScalingModeAspectFit
|
|
```
|
|
* 2:IJKMPMovieScalingModeAspectFill
|
|
(24). 提交问卷结果
|
|
* 3:IJKMPMovieScalingModeFill
|
|
```
|
|
*/
|
|
/*
|
|
@property(assign, nonatomic)NSInteger scalingMode;//屏幕适配方式,含义见上面
|
|
* @brief 提交问卷结果
|
|
|
|
*/
|
|
|
|
-(void)commitQuestionnaire:(NSDictionary *)dic;
|
|
|
|
```
|
|
|
|
(25). 修改昵称
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 修改昵称(The new method)
|
|
* @brief ppt默认底色,不写默认为白色
|
|
* @param nickName 修改后的昵称
|
|
*/
|
|
*/
|
|
@property(nonatomic,strong)UIColor *defaultColor;//ppt默认底色,不写默认为白色
|
|
- (void)changeNickName:(NSString *)nickName;
|
|
/**
|
|
```
|
|
* @brief /后台是否继续播放,注意:如果开启后台播放需要打开 xcode->Capabilities->Background Modes->on->Audio,AirPlay,and Picture in Picture
|
|
(26). 连麦相关方法
|
|
*/
|
|
```
|
|
@property(nonatomic,assign)BOOL pauseInBackGround;//后台是否继续播放,注意:如果开启后台播放需要打开 xcode->Capabilities->Background Modes->on->Audio,AirPlay,and Picture in Picture
|
|
/*(连麦相关方法)
|
|
/**
|
|
* 当收到- (void)acceptSpeak:(NSDictionary *)dict;回调方法后,调用此方法
|
|
* @brief PPT适配模式分为四种,
|
|
* dict 正是- (void)acceptSpeak:(NSDictionary *)dict;接收到的的参数
|
|
* 1.一种是全部填充屏幕,可拉伸变形,
|
|
* remoteView 是远程连麦页面的view,需要自己设置并发给SDK,SDK将要在这个view上进行远程画面渲染
|
|
* 2.第二种是等比缩放,横向或竖向贴住边缘,另一方向可以留黑边,
|
|
*/
|
|
* 3.第三种是等比缩放,横向或竖向贴住边缘,另一方向出边界,裁剪PPT,不可以留黑边
|
|
- (void)saveUserInfo:(NSDictionary *)dict remoteView:(UIView *)remoteView;
|
|
* 4.根据直播间文档显示模式的返回值进行设置(推荐)
|
|
```
|
|
*/
|
|
```
|
|
@property(assign, nonatomic)NSInteger PPTScalingMode;//PPT适配方式,含义见上面
|
|
/*(连麦相关方法)
|
|
/**
|
|
* 观看端主动断开连麦时候需要调用的接口
|
|
* @brief PPT是否允许滚动
|
|
*/
|
|
*/
|
|
- (void)disConnectSpeak;
|
|
@property(nonatomic, assign)BOOL pptInteractionEnabled;
|
|
```
|
|
/**
|
|
```
|
|
* @brief 设置当前的文档模式,
|
|
/*(连麦相关方法)
|
|
* 1.切换至跟随模式(默认值)值为0,
|
|
* 当观看端主动申请连麦时,需要调用这个接口,并把本地连麦预览窗口传给SDK,SDK会在这个view上
|
|
* 2.切换至自由模式;值为1,
|
|
* 进行远程画面渲染
|
|
*/
|
|
*/
|
|
@property(assign, nonatomic)NSInteger DocModeType;//设置当前的文档模式
|
|
-(void)requestAVMessageWithLocalView:(UIView *)localView;
|
|
/**
|
|
```
|
|
* @brief 聊天分组id
|
|
```
|
|
* 使用聊天分组功能时传入,不使用可以不传
|
|
/*(连麦相关方法)
|
|
*/
|
|
*设置本地预览窗口的大小,连麦成功后调用才生效,连麦不成功调用不生效
|
|
@property(copy, nonatomic)NSString *groupid;
|
|
*/
|
|
|
|
-(void)setLocalVideoFrameA:(CGRect)localVideoFrame;
|
|
|
|
```
|
|
|
|
```
|
|
|
|
/*(连麦相关方法)
|
|
|
|
*设置远程连麦窗口的大小,连麦成功后调用才生效,连麦不成功调用不生效
|
|
|
|
*/
|
|
|
|
-(void)setRemoteVideoFrameA:(CGRect)remoteVideoFrame;
|
|
|
|
```
|
|
|
|
```
|
|
```
|
|
/*(连麦相关方法)
|
|
|
|
*将要连接WebRTC
|
|
开始配置
|
|
*/
|
|
|
|
-(void)gotoConnectWebRTC;
|
|
|
|
```
|
|
```
|
|
**连麦方法调用顺序**
|
|
第一步:实例化参数类
|
|
|
|
PlayParameter *parameter = [[PlayParameter alloc] init];
|
|
|
|
//配置PlayParameter里面的属性,如userId,roomId等!
|
|
|
|
第二步实例化RequestData类
|
|
|
|
_requestData = [[RequestData alloc] initWithParameter:parameter];
|
|
|
|
第三步添加代理
|
|
|
|
_requestData.delegate = self;
|
|
```
|
|
```
|
|
(1)-(void)gotoConnectWebRTC; //申请视频连麦
|
|
|
|
|
|
|
|
(2)回调- (void)whetherOrNotConnectWebRTCNow:(BOOL)connect;//现在情况下是否可以连麦
|
|
添加代理
|
|
|
|
|
|
(3)-(void)requestAVMessageWithLocalView:(UIView *)localView;//连麦,传进去本机的预览窗口view
|
|
```
|
|
|
|
@interface 您的控制器 ()<RequestDataDelegate>
|
|
|
|
```
|
|
|
|
|
|
(4)回调- (void)acceptSpeak:(NSDictionary *)dict;//主播接受视频连麦
|
|
实现代理
|
|
|
|
|
|
(5)- (void)saveUserInfo:(NSDictionary *)dict remoteView:(UIView *)remoteView;//传回dict数据,和远端的视图view
|
|
```
|
|
|
|
/**
|
|
|
|
* @brief 请求成功
|
|
|
|
*/
|
|
|
|
-(void)requestSucceed {
|
|
|
|
|
|
(6)回调- (void)connectWebRTCSuccess;//表示连麦成功,不成功不用管,会自动挂断
|
|
}
|
|
|
|
/**
|
|
|
|
* @brief 登录请求失败
|
|
|
|
*/
|
|
|
|
-(void)requestFailed:(NSError *)error reason:(NSString *)reason {
|
|
|
|
|
|
断开连麦:
|
|
}
|
|
|
|
```
|
|
|
|
|
|
(1)- (void)disConnectSpeak;//主动断开连接
|
|
|
|
|
|
|
|
(2)回调-(void)speak_disconnect:(BOOL)isAllow;//参数isAllow表示是否直播间允许连麦,在这里写一些UI的操作,一般里面都会调用- (void)allowSpeakInteraction:(BOOL)isAllow;这个方法类似的内容
|
|
|
|
|
|
|
|
(3)回调方法- (void)allowSpeakInteraction:(BOOL)isAllow;//表示此房间是否允许连麦,一般做一些UI的内容,此方法不止调用一次(登陆,断网联网,改变房间是否允许连麦状态的时候都会回调此代理方法),尽量不要做一些重复的操作
|
|
**至此您的项目已经可以运行了,并且已经集成好了视频和文档基本功能;如果不需要文档功能则不配置文档相关属性即可**
|
|
|
|
|
|
连麦预览中可以调用:
|
|
|
|
|
|
|
|
(1)-(void)setLocalVideoFrameA:(CGRect)localVideoFrame;//修改本地预览窗口大小,连麦过程中,本地预览窗口就销毁,因为不会展示本地预览窗口了,只会展示远端窗口
|
|
|
|
|
|
|
|
连麦过程中调用:
|
|
## 3.2 观看直播
|
|
|
|
|
|
(1)-(void)setRemoteVideoFrameA:(CGRect)remoteVideoFrame;//修改远端视频窗口的大小,推流中只会展示远端窗口
|
|
3.2.1 代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
|
|
/**
|
|
|
|
* @brief 主讲开始推流
|
|
|
|
*/
|
|
|
|
- (void)onLiveStatusChangeStart;
|
|
|
|
|
|
### 4.2 事件监听
|
|
/**
|
|
|
|
* @brief 停止直播,endNormal表示是否异常停止推流,这个参数对观看端影响不大
|
|
事件监听只需要实现对应的代理方法即可
|
|
*/
|
|
|
|
- (void)onLiveStatusChangeEnd:(BOOL)endNormal;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 收到踢出消息,停止推流并退出播放(被主播踢出)(change)
|
|
|
|
* dictionary[@"kick_out_type"] 踢出类型
|
|
|
|
* dictionary[@"viewerid"] 用户ID
|
|
|
|
* kick_out_type: 踢出类型
|
|
|
|
* 10 在允许重复登录前提下,后进入者会登录会踢出先前登录者
|
|
|
|
* 20 讲师、助教、主持人通过页面踢出按钮踢出用户
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
- (void)onKickOut:(NSDictionary *)dictionary;
|
|
|
|
|
|
#### 4.2.1 请求播放地址成功
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 请求播放地址成功
|
|
* @brief 收到播放直播状态 0直播 1未直播
|
|
*/
|
|
*/
|
|
-(void)requestSucceed;
|
|
- (void)getPlayStatue:(NSInteger)status;
|
|
```
|
|
|
|
#### 4.2.2 请求播放地址失败
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 请求播放地址失败
|
|
* @brief 直播间被禁
|
|
*/
|
|
*/
|
|
-(void)requestFailed:(NSError *)error reason:(NSString *)reason;
|
|
- (void)theRoomWasBanned;
|
|
```
|
|
|
|
#### 4.2.3 收到提问
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 收到提问,用户观看时和主讲的互动问答信息
|
|
* @brief 直播间解禁
|
|
*/
|
|
*/
|
|
- (void)onQuestionDic:(NSDictionary *)questionDic;
|
|
- (void)theRoomWasCleared;
|
|
```
|
|
|
|
#### 4.2.4 收到回答
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 收到回答,用户观看时和主讲的互动问答信息
|
|
* @brief 客户端关闭摄像头
|
|
*/
|
|
数据源类型 数据源值 数据源类型描述 数据源类型描述值
|
|
- (void)onAnswerDic:(NSDictionary *)answerDic;
|
|
source_type 0 source_type_desc 数据源类型:默认值,
|
|
|
|
source_type 10 source_type_desc 数据源类型:摄像头打开
|
|
|
|
source_type 11 source_type_desc 数据源类型:摄像头关闭
|
|
|
|
source_type 20 source_type_desc 数据源类型:图片
|
|
|
|
source_type 30 source_type_desc 数据源类型:插播视频
|
|
|
|
source_type 40 source_type_desc 数据源类型:区域捕获
|
|
|
|
source_type 50 source_type_desc 数据源类型:桌面共享
|
|
|
|
source_type 60 source_type_desc 数据源类型:自定义场景
|
|
|
|
|
|
|
|
ps:
|
|
|
|
source_type 参数 0 值 应用场景:
|
|
|
|
1. 文档模式下 0 默认值
|
|
|
|
2. 非文档模式下 0 无意义
|
|
|
|
3. 低版本客户端 0 无意义
|
|
|
|
source_type 参数 60 值 应用场景:
|
|
|
|
当以上场景无法满足要求时,主播可自定义场景,用户不需要关心自定义场景细节内容
|
|
|
|
*/
|
|
|
|
- (void)receivedSwitchSource:(NSDictionary *)dic;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 视频或者文档大窗
|
|
|
|
* isMain 1为视频为主,0为文档为主"
|
|
|
|
*/
|
|
|
|
- (void)onSwitchVideoDoc:(BOOL)isMain;
|
|
|
|
/**
|
|
|
|
* @brief 加载视频失败
|
|
|
|
*/
|
|
|
|
- (void)play_loadVideoFail;
|
|
|
|
/**
|
|
|
|
* @brief 视频状态
|
|
|
|
* rseult playing/paused/loading/buffing
|
|
|
|
*/
|
|
|
|
-(void)videoStateChangeWithString:(NSString *) result;
|
|
```
|
|
```
|
|
#### 4.2.5 主讲和其他用户的历史互动问答信息
|
|
|
|
|
|
3.2.2 主动方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 收到提问&回答,在用户登录之前,主讲和其他用户的历史互动问答信息
|
|
* @brief 改变播放器frame
|
|
|
|
*/
|
|
|
|
- (void)changePlayerFrame:(CGRect) playerFrame;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 改变播放器父窗口
|
|
|
|
*/
|
|
|
|
- (void)changePlayerParent:(UIView *) playerParent;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 播放器暂停
|
|
|
|
*/
|
|
|
|
- (void)pausePlayer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 播放器播放
|
|
|
|
*/
|
|
|
|
- (void)startPlayer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 播放器关闭并移除
|
|
|
|
*/
|
|
|
|
- (void)shutdownPlayer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 播放器停止
|
|
|
|
*/
|
|
|
|
- (void)stopPlayer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 重新加载视频,参数force表示是否强制重新加载视频,
|
|
|
|
* 一般重新加载视频的时间间隔应该超过3秒,如果强制重新加载视频,时间间隔可以在3S之内
|
|
|
|
*/
|
|
|
|
-(void)reloadVideo:(BOOL)force;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 播放器是否播放
|
|
|
|
*/
|
|
|
|
- (BOOL)isPlaying;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 设置后台是否可播放
|
|
|
|
*/
|
|
|
|
- (void)setpauseInBackGround:(BOOL)pauseInBackGround;
|
|
|
|
/**
|
|
|
|
* @brief 销毁文档和视频,清除视频和文档的时候需要调用,退出播放页面的时候也需要调用
|
|
|
|
*/
|
|
|
|
- (void)requestCancel;
|
|
|
|
/**
|
|
|
|
* @brief 获取直播开始时间和直播时长
|
|
|
|
* liveDuration 直播持续时间,单位(s),直播未开始返回-1"
|
|
|
|
* liveStartTime 新增开始直播时间(格式:yyyy-MM-dd HH:mm:ss),如果直播未开始,则返回空字符串
|
|
|
|
*/
|
|
|
|
- (void)startTimeAndDurationLiveBroadcast:(NSDictionary *)dataDic;
|
|
|
|
/**
|
|
|
|
获取已播放时长,调用后会响应onLivePlayedTime方法,调用间隔三秒
|
|
|
|
*/
|
|
|
|
- (void)getLivePlayedTime;
|
|
|
|
/**
|
|
|
|
* @brief 回调已播放时长, 如果未开始,则time为-1
|
|
|
|
* 触发此方法需要调用getLivePlayedTime
|
|
*/
|
|
*/
|
|
- (void)onQuestionArr:(NSArray *)questionArr onAnswerArr:(NSArray *)answerArr;
|
|
- (void)onLivePlayedTime:(NSDictionary *)dic;
|
|
```
|
|
```
|
|
#### 4.2.6 历史聊天数据
|
|
|
|
|
|
## 3.3 文档功能
|
|
|
|
|
|
|
|
3.3.1 代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 历史聊天数据
|
|
* @brief 获取文档内白板或者文档本身的宽高,来进行屏幕适配用的
|
|
*/
|
|
*/
|
|
- (void)onChatLog:(NSArray *)chatLogArr;
|
|
- (void)getDocAspectRatioOfWidth:(CGFloat)width height:(CGFloat)height;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 获取ppt当前页数和总页数(The new method)
|
|
|
|
*
|
|
|
|
* 回调当前翻页的页数信息
|
|
|
|
* 白板docTotalPage一直为0, pageNum从1开始
|
|
|
|
* 其他文档docTotalPage为正常页数,pageNum从0开始
|
|
|
|
* @param dictionary 翻页信息
|
|
|
|
* dictionary :{docId 文档ID
|
|
|
|
* docName 文档名
|
|
|
|
* docTotalPage 文档总页数
|
|
|
|
* pageNum 文档页码}
|
|
|
|
*/
|
|
|
|
- (void)onPageChange:(NSDictionary *) dictionary;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 双击ppt
|
|
|
|
*/
|
|
|
|
- (void)doubleCllickPPTView;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 获取所有文档列表
|
|
|
|
* @param listDic [{ docId //文档ID
|
|
|
|
docName //文档名称
|
|
|
|
docTotalPage //文档总页数
|
|
|
|
iconSrc //图标地址
|
|
|
|
pages [{ pageIndex //当前页位置
|
|
|
|
src //当前页地址
|
|
|
|
title //当前页标题 }]}]
|
|
|
|
*/
|
|
|
|
- (void)receivedDocsList:(NSDictionary *)listDic;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 视频或者文档大窗
|
|
|
|
* isMain 1为视频为主,0为文档为主"
|
|
|
|
*/
|
|
|
|
- (void)onSwitchVideoDoc:(BOOL)isMain;
|
|
|
|
/**
|
|
|
|
* @brief 文档加载状态
|
|
|
|
* index
|
|
|
|
* 0 文档组件初始化完成
|
|
|
|
* 1 动画文档加载完成
|
|
|
|
* 2 非动画文档加载完成
|
|
|
|
* 3文档组件加载失败
|
|
|
|
* 4文档图片加载失败
|
|
|
|
* 5文档动画加载失败
|
|
|
|
* 6画板加载失败
|
|
|
|
*/
|
|
|
|
- (void)docLoadCompleteWithIndex:(NSInteger)index;
|
|
```
|
|
```
|
|
#### 4.2.7 主讲开始推流
|
|
|
|
|
|
3.3.2 主动方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 主讲开始推流
|
|
* @brief 获取文档区域内白板或者文档本身的宽高比,返回值即为宽高比,做屏幕适配用
|
|
|
|
*/
|
|
|
|
- (CGFloat)getDocAspectRatio;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 改变文档区域大小,主要用在文档生成后改变文档窗口的frame
|
|
|
|
*/
|
|
|
|
- (void)changeDocFrame:(CGRect) docFrame;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 改变文档父窗口
|
|
|
|
*/
|
|
|
|
- (void)changeDocParent:(UIView *) docParent;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 切换当前的文档模式
|
|
|
|
* 1.切换至跟随模式(默认值)值为0,
|
|
|
|
* 2.切换至自由模式;值为1,
|
|
|
|
*/
|
|
|
|
- (void)changeDocMode:(NSInteger)mode;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 查找并获取当前文档的信息
|
|
|
|
* @param docId 文档的docId
|
|
|
|
* @param pageIndex 跳转的页数
|
|
|
|
*/
|
|
|
|
- (void)changePageToNumWithDocId:(NSString *)docId pageIndex:(NSInteger)pageIndex;
|
|
|
|
/**
|
|
|
|
重新加载文档
|
|
*/
|
|
*/
|
|
- (void)onLiveStatusChangeStart;
|
|
- (void)docReload;
|
|
|
|
/**
|
|
|
|
改变文档背景颜色
|
|
|
|
|
|
|
|
@param hexColor 字符串,传颜色的HEXColor 如:#000000
|
|
|
|
*/
|
|
|
|
- (void)changeDocWebColor:(NSString *)hexColor;
|
|
|
|
/**
|
|
|
|
* 获取ppt列表(只能在登陆成功后调用)
|
|
|
|
*/
|
|
|
|
- (void)getDocsList;
|
|
|
|
|
|
```
|
|
```
|
|
#### 4.2.8 停止直播
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##3.4 房间信息
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 停止直播,endNormal表示是否异常停止推流,这个参数对观看端影响不大
|
|
* @brief 获取房间信息,主要是要获取直播间模版来类型,根据直播间模版类型来确定界面布局
|
|
|
|
* 房间简介:dic[@"desc"];
|
|
|
|
* 房间名称:dic[@"name"];
|
|
|
|
* 房间模版类型:[dic[@"templateType"] integerValue];
|
|
|
|
* 模版类型为1: 聊天互动: 无 直播文档: 无 直播问答: 无
|
|
|
|
* 模版类型为2: 聊天互动: 有 直播文档: 无 直播问答: 有
|
|
|
|
* 模版类型为3: 聊天互动: 有 直播文档: 无 直播问答: 无
|
|
|
|
* 模版类型为4: 聊天互动: 有 直播文档: 有 直播问答: 无
|
|
|
|
* 模版类型为5: 聊天互动: 有 直播文档: 有 直播问答: 有
|
|
|
|
* 模版类型为6: 聊天互动: 无 直播文档: 无 直播问答: 有
|
|
|
|
*/
|
|
|
|
-(void)roomInfo:(NSDictionary *)dic;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief 服务器端给自己设置的信息
|
|
|
|
* viewerId 服务器端给自己设置的UserId
|
|
|
|
* groupId 分组id
|
|
|
|
* name 用户名
|
|
|
|
*/
|
|
|
|
-(void)setMyViewerInfo:(NSDictionary *) infoDic;
|
|
|
|
/**
|
|
|
|
* @brief 房间设置信息
|
|
|
|
* dic{
|
|
|
|
"allow_chat" = true;//是否允许聊天
|
|
|
|
"allow_question" = true;//是否允许问答
|
|
|
|
"room_base_user_count" = 0;//房间基础在线人数
|
|
|
|
"source_type" = 0;//对应receivedSwitchSource方法的source_type
|
|
|
|
}
|
|
|
|
*ps:当房间类型没有聊天或者问答时,对应的字段默认为true
|
|
*/
|
|
*/
|
|
- (void)onLiveStatusChangeEnd:(BOOL)endNormal;
|
|
-(void)roomSettingInfo:(NSDictionary *)dic;
|
|
|
|
/**
|
|
|
|
* @brief 服务器端给自己设置的UserId
|
|
|
|
*/
|
|
|
|
-(void)setMyViewerId:(NSString *)viewerId;
|
|
```
|
|
```
|
|
#### 4.2.9 收到公聊消息
|
|
|
|
|
|
##3.5 聊天功能
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 收到公聊消息
|
|
* @brief 历史聊天数据
|
|
*/
|
|
* @param chatLogArr [{ chatId //聊天ID
|
|
|
|
content //聊天内容
|
|
|
|
groupId //聊天组ID
|
|
|
|
time //时间
|
|
|
|
userAvatar //用户头像
|
|
|
|
userId //用户ID
|
|
|
|
userName //用户名称
|
|
|
|
userRole //用户角色}]
|
|
|
|
*/
|
|
|
|
- (void)onChatLog:(NSArray *)chatLogArr;
|
|
|
|
/*
|
|
|
|
* @brief 收到公聊消息
|
|
|
|
@param message { groupId //聊天组ID
|
|
|
|
msg //消息内容
|
|
|
|
time //发布时间
|
|
|
|
useravatar //用户头像
|
|
|
|
userid //用户ID
|
|
|
|
username //用户名称
|
|
|
|
userrole //用户角色}
|
|
|
|
*/
|
|
- (void)onPublicChatMessage:(NSDictionary *)message;
|
|
- (void)onPublicChatMessage:(NSDictionary *)message;
|
|
```
|
|
|
|
#### 4.2.10 收到私聊信息
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 收到私聊信息
|
|
* @brief 收到私聊信息
|
|
*/
|
|
* @param dic {fromuserid //发送者用户ID
|
|
|
|
* fromusername //发送者用户名
|
|
|
|
* fromuserrole //发送者角色
|
|
|
|
* msg //消息内容
|
|
|
|
* time //发送时间
|
|
|
|
* touserid //接受者用户ID
|
|
|
|
* tousername //接受者用户名}
|
|
|
|
*/
|
|
- (void)OnPrivateChat:(NSDictionary *)dic;
|
|
- (void)OnPrivateChat:(NSDictionary *)dic;
|
|
```
|
|
|
|
#### 4.2.11 自己被禁言
|
|
|
|
```
|
|
|
|
/*
|
|
/*
|
|
* @brief 收到自己的禁言消息,如果你被禁言了,你发出的消息只有你自己能看到,其他人看不到
|
|
* @brief 收到自己的禁言消息,如果你被禁言了,你发出的消息只有你自己能看到,其他人看不到
|
|
*/
|
|
@param message { groupId //聊天组ID
|
|
|
|
msg //消息内容
|
|
|
|
time //发布时间
|
|
|
|
useravatar //用户头像
|
|
|
|
userid //用户ID
|
|
|
|
username //用户名称
|
|
|
|
userrole //用户角色}
|
|
|
|
*/
|
|
- (void)onSilenceUserChatMessage:(NSDictionary *)message;
|
|
- (void)onSilenceUserChatMessage:(NSDictionary *)message;
|
|
```
|
|
|
|
#### 4.2.12 收到在线人数
|
|
|
|
```
|
|
|
|
/**
|
|
|
|
* @brief 收到在线人数
|
|
|
|
*/
|
|
|
|
- (void)onUserCount:(NSString *)count;
|
|
|
|
```
|
|
|
|
#### 4.2.13 主讲全体禁言时,你再发消息
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 当主讲全体禁言时,你再发消息,会出发此代理方法,information是禁言提示信息
|
|
* @brief 当主讲全体禁言时,你再发消息,会出发此代理方法,information是禁言提示信息
|
|
*/
|
|
*/
|
|
- (void)information:(NSString *)information;
|
|
- (void)information:(NSString *)information;
|
|
```
|
|
|
|
#### 4.2.14 服务器端给自己设置的UserId
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 服务器端给自己设置的UserId
|
|
* @brief 自定义消息
|
|
*/
|
|
*/
|
|
-(void)setMyViewerId:(NSString *)viewerId;
|
|
- (void)customMessage:(NSString *)message;
|
|
```
|
|
|
|
#### 4.2.15 收到踢出消息
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 收到踢出消息,停止推流并退出播放(被主播踢出)
|
|
* @brief 收到聊天禁言并删除聊天记录
|
|
*/
|
|
* viewerId 禁言用户id,是自己的话别删除聊天历史,其他人需要删除该用户的聊天
|
|
- (void)onKickOut;
|
|
*/
|
|
```
|
|
-(void)onBanDeleteChat:(NSDictionary *) viewerDic;
|
|
#### 4.2.16 获取房间信息
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 获取房间信息,主要是要获取直播间模版来类型,根据直播间模版类型来确定界面布局
|
|
* @brief 收到聊天禁言
|
|
* 房间简介:dic[@"desc"];
|
|
* mode 禁言类型 1:个人禁言 2:全员禁言
|
|
* 房间名称:dic[@"name"];
|
|
*/
|
|
* 房间模版类型:[dic[@"templateType"] integerValue];
|
|
-(void)onBanChat:(NSDictionary *) modeDic;
|
|
* 模版类型为1: 聊天互动: 无 直播文档: 无 直播问答: 无
|
|
|
|
* 模版类型为2: 聊天互动: 有 直播文档: 无 直播问答: 有
|
|
|
|
* 模版类型为3: 聊天互动: 有 直播文档: 无 直播问答: 无
|
|
|
|
* 模版类型为4: 聊天互动: 有 直播文档: 有 直播问答: 无
|
|
|
|
* 模版类型为5: 聊天互动: 有 直播文档: 有 直播问答: 有
|
|
|
|
* 模版类型为6: 聊天互动: 无 直播文档: 无 直播问答: 有
|
|
|
|
*/
|
|
|
|
-(void)roomInfo:(NSDictionary *)dic;
|
|
|
|
```
|
|
|
|
#### 4.2.17 直播状态
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 收到播放直播状态 0直播 1未直播
|
|
* @brief 收到解除禁言事件
|
|
*/
|
|
* mode 禁言类型 1:个人禁言 2:全员禁言
|
|
- (void)getPlayStatue:(NSInteger)status;
|
|
*/
|
|
|
|
-(void)onUnBanChat:(NSDictionary *) modeDic;
|
|
|
|
/**
|
|
|
|
* @brief 聊天管理
|
|
|
|
* status 聊天消息的状态 0 显示 1 不显示
|
|
|
|
* chatIds 聊天消息的id列列表
|
|
|
|
*/
|
|
|
|
-(void)chatLogManage:(NSDictionary *) manageDic;
|
|
```
|
|
```
|
|
#### 4.2.18 白板或者文档本身的宽高
|
|
|
|
|
|
主动方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 获取文档内白板或者文档本身的宽高,来进行屏幕适配用的
|
|
* @brief 发送公聊信息
|
|
*/
|
|
* @param message 发送的消息内容
|
|
- (void)getDocAspectRatioOfWidth:(CGFloat)width height:(CGFloat)height;
|
|
*/
|
|
|
|
- (void)chatMessage:(NSString *)message;
|
|
|
|
/**
|
|
|
|
* @brief 发送私聊信息
|
|
|
|
*/
|
|
|
|
- (void)privateChatWithTouserid:(NSString *)touserid msg:(NSString *)msg;
|
|
|
|
/**
|
|
|
|
* @brief 发送公聊信息
|
|
|
|
* @param message 发送的消息内容
|
|
|
|
* completion 发送回调 成功或者失败
|
|
|
|
*/
|
|
|
|
- (void)sendChatMessage:(NSString *)message completion:(void (^)(BOOL success))completion;
|
|
```
|
|
```
|
|
#### 4.2.19 登录成功
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 3.6 问答功能
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 登录成功
|
|
* @brief 收到提问,用户观看时和主讲的互动问答信息
|
|
*/
|
|
* @param questionDic { groupId //分组ID
|
|
- (void)loginSucceedPlay;
|
|
content //问答内容
|
|
|
|
userName //问答用户名
|
|
|
|
userId //问答用户ID
|
|
|
|
time //问答时间
|
|
|
|
id //问答主键ID
|
|
|
|
useravatar //用户化身 }
|
|
|
|
*/
|
|
|
|
- (void)onQuestionDic:(NSDictionary *)questionDic;
|
|
|
|
/**
|
|
|
|
* @brief 收到回答
|
|
|
|
* @param answerDic {content //回复内容
|
|
|
|
userName //用户名
|
|
|
|
questionUserId //问题用户ID
|
|
|
|
time //回复时间
|
|
|
|
questionId //问题ID
|
|
|
|
isPrivate //1 私聊回复 0 公聊回复 }
|
|
|
|
*/
|
|
|
|
- (void)onAnswerDic:(NSDictionary *)answerDic;
|
|
|
|
/**
|
|
|
|
* @brief 收到历史提问&回答
|
|
|
|
* @param questionArr [{content //问答内容
|
|
|
|
encryptId //加密ID
|
|
|
|
groupId //分组ID
|
|
|
|
isPublish //1 发布的问答 0 未发布的问答
|
|
|
|
questionUserId //问答用户ID
|
|
|
|
questionUserName //问答用户名
|
|
|
|
time //问答时间
|
|
|
|
triggerTime //问答具体时间}]
|
|
|
|
* @param answerArr [{answerUserId //回复用户ID
|
|
|
|
answerUserName //回复名
|
|
|
|
answerUserRole //回复角色(主讲、助教)
|
|
|
|
content //回复内容
|
|
|
|
encryptId //加密ID
|
|
|
|
groupId //分组ID
|
|
|
|
isPrivate //1 私聊回复 0 公共回复
|
|
|
|
time = 135; //回复时间
|
|
|
|
triggerTime //回复具体时间}]
|
|
|
|
*/
|
|
|
|
- (void)onQuestionArr:(NSArray *)questionArr onAnswerArr:(NSArray *)answerArr;
|
|
|
|
/**
|
|
|
|
* @brief 发布问题的ID
|
|
|
|
*/
|
|
|
|
- (void)publish_question:(NSString *)publishId;
|
|
```
|
|
```
|
|
#### 4.2.20 登录失败
|
|
|
|
|
|
主动方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 登录失败
|
|
* @brief 提问
|
|
*/
|
|
* @param message 提问内容
|
|
-(void)loginFailed:(NSError *)error reason:(NSString *)reason;
|
|
*/
|
|
|
|
- (void)question:(NSString *)message;
|
|
```
|
|
```
|
|
#### 4.2.21 连麦相关代理方法
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 3.7 连麦功能
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/*(连麦相关代理方法)
|
|
/**
|
|
* @brief WebRTC连接成功,在此代理方法中主要做一些界面的更改
|
|
* @brief 本房间为允许连麦的房间,会回调此方法,在此方法中主要设置UI的逻辑,
|
|
*/
|
|
* 在断开推流,登录进入直播间和改变房间是否允许连麦状态的时候,都会回调此方法
|
|
|
|
*/
|
|
|
|
- (void)allowSpeakInteraction:(BOOL)isAllow;
|
|
|
|
/**
|
|
|
|
* @brief WebRTC连接成功,在此代理方法中主要做一些界面的更改
|
|
|
|
*/
|
|
- (void)connectWebRTCSuccess;
|
|
- (void)connectWebRTCSuccess;
|
|
```
|
|
/**
|
|
#### 4.2.22 当前是否可以连麦
|
|
* @brief 当前是否可以连麦
|
|
```
|
|
*/
|
|
/*(连麦相关代理方法)
|
|
|
|
* @brief 当前是否可以连麦
|
|
|
|
*/
|
|
|
|
- (void)whetherOrNotConnectWebRTCNow:(BOOL)connect;
|
|
- (void)whetherOrNotConnectWebRTCNow:(BOOL)connect;
|
|
```
|
|
/**
|
|
#### 4.2.23 主播端接受连麦请求
|
|
* @brief 主播端接受连麦请求,在此代理方法中,要调用DequestData对象的
|
|
```
|
|
* - (void)saveUserInfo:(NSDictionary *)dict remoteView:(UIView *)remoteView;方法
|
|
/*(连麦相关代理方法)
|
|
* 把收到的字典参数和远程连麦页面的view传进来,这个view需要自己设置并发给SDK,SDK将要在这个view上进行渲染
|
|
* @brief 主播端接受连麦请求,在此代理方法中,要调用DequestData对象的
|
|
*
|
|
* - (void)saveUserInfo:(NSDictionary *)dict remoteView:(UIView *)remoteView;方法
|
|
* @param dict {type //audio 音频 audiovideo 音视频
|
|
* 把收到的字典参数和远程连麦页面的view传进来,这个view需要自己设置并发给SDK,SDK将要在这个view上进行渲染
|
|
* videosize //视频尺寸
|
|
*/
|
|
* viewerId //申请连麦ID
|
|
|
|
* viewerName //申请连麦名}
|
|
|
|
*/
|
|
- (void)acceptSpeak:(NSDictionary *)dict;
|
|
- (void)acceptSpeak:(NSDictionary *)dict;
|
|
```
|
|
/**
|
|
#### 4.2.24 主播端发送断开连麦
|
|
* @brief 主播端发送断开连麦的消息,收到此消息后做断开连麦操作
|
|
```
|
|
*/
|
|
/*(连麦相关代理方法)
|
|
|
|
* @brief 主播端发送断开连麦的消息,收到此消息后做断开连麦操作
|
|
|
|
*/
|
|
|
|
-(void)speak_disconnect:(BOOL)isAllow;
|
|
-(void)speak_disconnect:(BOOL)isAllow;
|
|
|
|
|
|
```
|
|
```
|
|
#### 4.2.25 允许连麦的房间
|
|
|
|
```
|
|
主动方法(可选)
|
|
/*(连麦相关代理方法)
|
|
|
|
* @brief 本房间为允许连麦的房间,会回调此方法,在此方法中主要设置UI的逻辑,
|
|
|
|
* 在断开推流,登录进入直播间和改变房间是否允许连麦状态的时候,都会回调此方法
|
|
|
|
*/
|
|
|
|
- (void)allowSpeakInteraction:(BOOL)isAllow;
|
|
|
|
```
|
|
|
|
#### 4.2.26 切换源
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* @brief 切换源,firRoadNum表示一共有几个源,secRoadKeyArray表示每
|
|
|
|
* 个源的描述数组,具体参见demo,firRoadNum是下拉列表有面的tableviewcell
|
|
|
|
* 的行数,secRoadKeyArray是左面的tableviewcell的描述信息数组
|
|
|
|
*/
|
|
|
|
- (void)firRoad:(NSInteger)firRoadNum secRoadKeyArray:(NSArray *)secRoadKeyArray;
|
|
|
|
```
|
|
|
|
#### 4.2.27 自定义消息
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* 自定义消息
|
|
|
|
*/
|
|
|
|
- (void)customMessage:(NSString *)message;
|
|
|
|
```
|
|
|
|
#### 4.2.28 公告
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* 公告
|
|
|
|
*/
|
|
|
|
- (void)announcement:(NSString *)str;
|
|
|
|
```
|
|
|
|
#### 4.2.29 监听到有公告消息
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* 监听到有公告消息
|
|
|
|
*/
|
|
|
|
- (void)on_announcement:(NSDictionary *)dict;
|
|
|
|
```
|
|
|
|
#### 4.2.30 开始抽奖
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* 开始抽奖
|
|
|
|
*/
|
|
|
|
- (void)start_lottery;
|
|
|
|
```
|
|
|
|
#### 4.2.31 抽奖结果
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* 抽奖结果
|
|
|
|
*/
|
|
|
|
- (void)lottery_resultWithCode:(NSString *)code myself:(BOOL)myself winnerName:(NSString *)winnerName remainNum:(NSInteger)remainNum;
|
|
|
|
```
|
|
|
|
#### 4.2.32 退出抽奖
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* 退出抽奖
|
|
|
|
*/
|
|
|
|
- (void)stop_lottery;
|
|
|
|
```
|
|
|
|
#### 4.2.33 开始签到
|
|
|
|
```
|
|
```
|
|
/*
|
|
|
|
* 开始签到
|
|
/**
|
|
*/
|
|
* @brief 设置远程连麦窗口的大小,连麦成功后调用才生效,连麦不成功调用不生效
|
|
- (void)start_rollcall:(NSInteger)duration;
|
|
*/
|
|
|
|
-(void)setRemoteVideoFrameA:(CGRect)remoteVideoFrame;
|
|
|
|
/**
|
|
|
|
* @brief 设置本地预览窗口的大小,连麦成功后调用才生效,连麦不成功调用不生效
|
|
|
|
*/
|
|
|
|
-(void)setLocalVideoFrameA:(CGRect)localVideoFrame;
|
|
|
|
/**
|
|
|
|
* @brief 当观看端主动申请连麦时,需要调用这个接口,并把本地连麦预览窗口传给SDK,SDK会在这个view上
|
|
|
|
* 进行远程画面渲染
|
|
|
|
* param localView:本地预览窗口,传入本地view,连麦准备时间将会自动绘制预览画面在此view上
|
|
|
|
* param isAudioVideo:是否是音视频连麦,不是音视频即是纯音频连麦(YES表示音视频连麦,NO表示音频连麦)
|
|
|
|
*/
|
|
|
|
-(void)requestAVMessageWithLocalView:(UIView *)localView isAudioVideo:(BOOL)isAudioVideo;
|
|
|
|
/**
|
|
|
|
* @brief 当收到- (void)acceptSpeak:(NSDictionary *)dict;回调方法后,调用此方法
|
|
|
|
* dict 正是- (void)acceptSpeak:(NSDictionary *)dict;接收到的的参数
|
|
|
|
* remoteView 是远程连麦页面的view,需要自己设置并发给SDK,SDK将要在这个view上进行远程画面渲染
|
|
|
|
*/
|
|
|
|
- (void)saveUserInfo:(NSDictionary *)dict remoteView:(UIView *)remoteView;
|
|
|
|
/**
|
|
|
|
* @brief 将要连接WebRTC
|
|
|
|
*/
|
|
|
|
-(void)gotoConnectWebRTC;
|
|
|
|
/**
|
|
|
|
* @brief 观看端主动断开连麦时候需要调用的接口
|
|
|
|
*/
|
|
|
|
- (void)disConnectSpeak;
|
|
|
|
|
|
```
|
|
```
|
|
#### 4.2.34 开始答题
|
|
|
|
|
|
|
|
|
|
|
|
|
|
##3.8 切换线路和清晰度
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/*
|
|
|
|
* 开始答题
|
|
/**
|
|
*/
|
|
* @brief 切换线路
|
|
- (void)start_vote:(NSInteger)count singleSelection:(BOOL)single;
|
|
* @param firRoadNum 线路
|
|
|
|
* @param secRoadKeyArray 清晰度[@"标清",@"高清"]
|
|
|
|
*/
|
|
|
|
- (void)firRoad:(NSInteger)firRoadNum secRoadKeyArray:(NSArray *)secRoadKeyArray;
|
|
```
|
|
```
|
|
#### 4.2.35 结束答题
|
|
|
|
|
|
主动方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/*
|
|
/**
|
|
* 结束答题
|
|
* @brief 切换播放线路和清晰度
|
|
*/
|
|
* firIndex表示第几个线路
|
|
- (void)stop_vote;
|
|
* key表示该线路对应的secRoadKeyArray里面的元素
|
|
|
|
*/
|
|
|
|
- (void)switchToPlayUrlWithFirIndex:(NSInteger)firIndex key:(NSString *)key;
|
|
```
|
|
```
|
|
#### 4.2.36 答题结果
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 3.9 答题卡功能
|
|
|
|
|
|
```
|
|
```
|
|
/*
|
|
/**
|
|
* 答题结果
|
|
* @brief 开始答题
|
|
*/
|
|
*/
|
|
|
|
- (void)start_vote:(NSInteger)count singleSelection:(BOOL)single;
|
|
|
|
/**
|
|
|
|
* @brief 结束答题
|
|
|
|
*/
|
|
|
|
- (void)stop_vote;
|
|
|
|
/**
|
|
|
|
* @brief 答题结果
|
|
|
|
* @param resultDic {answerCount //参与回答人数
|
|
|
|
correctOption //正确答案 (单选字符串,多选字符串数组)
|
|
|
|
statisics[{ //统计数组
|
|
|
|
count //选择当前选项人数
|
|
|
|
option //选项序号
|
|
|
|
percent //正确率 }]
|
|
|
|
voteCount //题目数量
|
|
|
|
voteId //题目ID
|
|
|
|
voteType //题目类型}
|
|
|
|
*/
|
|
- (void)vote_result:(NSDictionary *)resultDic;
|
|
- (void)vote_result:(NSDictionary *)resultDic;
|
|
|
|
/**
|
|
|
|
* @brief 收到打卡提交结果
|
|
|
|
* dic{
|
|
|
|
"success": true,
|
|
|
|
"data": {
|
|
|
|
"isRepeat": false//是否重复提交打卡
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
-(void)hdReceivedPunchResultWithDict:(NSDictionary *)dic;
|
|
|
|
/**
|
|
|
|
* @brief 收到开始打卡
|
|
|
|
* dic {
|
|
|
|
"punchId": "punchId",
|
|
|
|
"expireTime": "2019-10-26 10:00:00",
|
|
|
|
"remainDuration": 124
|
|
|
|
}
|
|
|
|
* 当没有设置时长,即无过期时间时
|
|
|
|
* {
|
|
|
|
"punchId": "asasdasdasdasd",
|
|
|
|
"remainDuration": -1 //其中-1表示剩余无限时间。
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
-(void)hdReceivedStartPunchWithDict:(NSDictionary *)dic;
|
|
|
|
/**
|
|
|
|
* @brief 收到结束打卡
|
|
|
|
* dic{
|
|
|
|
"punchId": "punchId"
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
-(void)hdReceivedEndPunchWithDict:(NSDictionary *)dic;
|
|
```
|
|
```
|
|
#### 4.2.37 加载视频失败
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* 加载视频失败
|
|
|
|
*/
|
|
|
|
- (void)play_loadVideoFail;
|
|
|
|
```
|
|
|
|
#### 4.2.38 接收到发送的广播
|
|
|
|
```
|
|
|
|
/*
|
|
|
|
* 接收到发送的广播
|
|
|
|
*/
|
|
|
|
- (void)broadcast_msg:(NSDictionary *)dic;
|
|
|
|
```
|
|
|
|
#### 4.2.39 发布问题的ID
|
|
|
|
```
|
|
```
|
|
/*
|
|
/**
|
|
* 发布问题的ID
|
|
* @brief 答单选题
|
|
*/
|
|
*/
|
|
- (void)publish_question:(NSString *)publishId;
|
|
-(void)reply_vote_single:(NSInteger)index;
|
|
|
|
/**
|
|
|
|
* @brief 答多选题
|
|
|
|
@param IndexArray [题目index,题目index] 例:[1,2]
|
|
|
|
*/
|
|
|
|
-(void)reply_vote_multiple:(NSMutableArray *)indexArray;
|
|
```
|
|
```
|
|
#### 4.2.40 发布问卷
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 3.10 问卷功能
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/*
|
|
/**
|
|
* 发布问卷
|
|
* @brief 发布问卷
|
|
*/
|
|
*/
|
|
- (void)questionnaire_publish;
|
|
- (void)questionnaire_publish;
|
|
```
|
|
/**
|
|
#### 4.2.41 结束发布问卷
|
|
* @brief 结束发布问卷
|
|
```
|
|
*/
|
|
/*
|
|
|
|
* 结束发布问卷
|
|
|
|
*/
|
|
|
|
- (void)questionnaire_publish_stop;
|
|
- (void)questionnaire_publish_stop;
|
|
```
|
|
/**
|
|
#### 4.2.42 问卷详细内容
|
|
* @brief 获取问卷详细内容
|
|
```
|
|
* @param detailDic { forcibly //1就是强制答卷,0为非强制答卷
|
|
/*
|
|
id //问卷主键ID
|
|
* 获取问卷详细内容
|
|
subjects //包含的项目
|
|
*/
|
|
submitedAction //1提交后查看答案,0为提交后不查看答案
|
|
|
|
title //标题 }
|
|
|
|
*/
|
|
- (void)questionnaireDetailInformation:(NSDictionary *)detailDic;
|
|
- (void)questionnaireDetailInformation:(NSDictionary *)detailDic;
|
|
```
|
|
/**
|
|
#### 4.2.43 提交问卷结果
|
|
* @brief 获取问卷统计
|
|
```
|
|
* @param staticsDic { forcibly //1就是强制答卷,0为非强制答卷
|
|
/*
|
|
id //问卷主键ID
|
|
* 提交问卷结果(成功,失败)
|
|
subjects //包含的项目
|
|
*/
|
|
submitedAction //1提交后查看答案,0为提交后不查看答案
|
|
|
|
title //标题 }
|
|
|
|
*/
|
|
|
|
- (void)questionnaireStaticsInformation:(NSDictionary *)staticsDic;
|
|
|
|
/**
|
|
|
|
* @brief 提交问卷结果(成功,失败)
|
|
|
|
*/
|
|
- (void)commitQuestionnaireResult:(BOOL)success;
|
|
- (void)commitQuestionnaireResult:(BOOL)success;
|
|
```
|
|
|
|
#### 4.2.44 观看直播修改昵称
|
|
|
|
```
|
|
|
|
/**
|
|
/**
|
|
* @brief 修改后的昵称(The new method)
|
|
* @brief 问卷功能
|
|
* @param nickName 修改后的昵称
|
|
*/
|
|
*/
|
|
- (void)questionnaireWithTitle:(NSString *)title url:(NSString *)url;
|
|
- (void)onChangeNickname:(NSString *)nickNime;
|
|
|
|
```
|
|
```
|
|
#### 4.2.45 获取PPT当前页数和总页数
|
|
|
|
|
|
主动方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 获取ppt当前页数和总页数(The new method)
|
|
* @brief 提交问卷结果
|
|
*
|
|
* @param dic{subjectsAnswer[{selectedOptionId //选中选项ID
|
|
* 回调当前翻页的页数信息 <br/>
|
|
subjectId //题目ID}]}
|
|
* 白板docTotalPage一直为0, pageNum从1开始<br/>
|
|
*/
|
|
* 其他文档docTotalPage为正常页数,pageNum从0开始<br/>
|
|
-(void)commitQuestionnaire:(NSDictionary *)dic;
|
|
* @param dictionary 翻页信息
|
|
/**
|
|
*/
|
|
* @brief 主动请求问卷
|
|
- (void)onPageChange:(NSDictionary *) dictionary;
|
|
*/
|
|
|
|
-(void)getPublishingQuestionnaire;
|
|
```
|
|
```
|
|
#### 4.2.46 获取最近一条广播
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 3.11 广播功能
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 收到最近一条广播(The new method)
|
|
* @brief 接收到发送的广播
|
|
* content 广播内容
|
|
* @param dic {content //广播内容
|
|
* time 发布时间(单位:秒)
|
|
userid //发布者ID
|
|
*/
|
|
username //发布者名字
|
|
- (void)broadcastHistory_msg:(NSArray *)History_msg;
|
|
userrole //发布者角色 }
|
|
|
|
*/
|
|
|
|
- (void)broadcast_msg:(NSDictionary *)dic;
|
|
|
|
/**
|
|
|
|
* @brief 接收到最后一条广播(直播中途进入,会返回最后一条广播)
|
|
|
|
* @param array[{ content //广播内容
|
|
|
|
publisherId //发布者ID
|
|
|
|
publisherName //发布者名字
|
|
|
|
publisherRole //发布者角色
|
|
|
|
time //发布时间
|
|
|
|
}]
|
|
|
|
*/
|
|
|
|
- (void)broadcastLast_msg:(NSArray *)array;
|
|
```
|
|
```
|
|
#### 4.2.47 获取最近一条广播
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 3.12 签到功能
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 获取直播开始时间和直播时长(The new method)
|
|
* @brief 开始签到
|
|
* liveDuration 直播持续时间,单位(s),直播未开始返回-1"
|
|
|
|
* liveStartTime 新增开始直播时间(格式:yyyy-MM-dd HH:mm:ss),如果直播未开始,则返回空字符串
|
|
|
|
*/
|
|
*/
|
|
- (void)startTimeAndDurationLiveBroadcast:(NSDictionary *)dataDic;
|
|
- (void)start_rollcall:(NSInteger)duration;
|
|
```
|
|
```
|
|
#### 4.2.48 直播间封禁和解禁代理
|
|
|
|
|
|
主动方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 直播间被禁(The new method)
|
|
* @brief 签到
|
|
*/
|
|
*/
|
|
- (void)theRoomWasBanned;
|
|
-(void)answer_rollcall;
|
|
|
|
/**
|
|
|
|
提交打卡
|
|
|
|
|
|
|
|
@param punchId 打卡id
|
|
|
|
*/
|
|
|
|
- (void)hdCommitPunchWithPunchId:(NSString *)punchId;
|
|
/**
|
|
/**
|
|
* @brief 直播间解禁(The new method)
|
|
查询打卡信息
|
|
*/
|
|
*/
|
|
- (void)theRoomWasCleared;
|
|
- (void)hdInquirePunchInformation;
|
|
```
|
|
```
|
|
|
|
|
|
#### 4.2.49 双击ppt事件代理方法
|
|
|
|
|
|
|
|
|
|
## 3.13 抽奖功能
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
/**
|
|
/**
|
|
* @brief 双击ppt(The new method)
|
|
* @brief 开始抽奖
|
|
*/
|
|
*/
|
|
- (void)doubleCllickPPTView;
|
|
- (void)start_lottery;
|
|
|
|
/**
|
|
|
|
* @brief 抽奖结果
|
|
|
|
* remainNum 剩余奖品数
|
|
|
|
*/
|
|
|
|
- (void)lottery_resultWithCode:(NSString *)code myself:(BOOL)myself winnerName:(NSString *)winnerName remainNum:(NSInteger)remainNum;
|
|
|
|
/**
|
|
|
|
* @brief 退出抽奖
|
|
|
|
*/
|
|
|
|
- (void)stop_lottery;
|
|
```
|
|
```
|
|
|
|
|
|
### 4.3 播放器监听
|
|
|
|
|
|
|
|
**添加播放器监听事件(监听播放状态改变)**
|
|
|
|
```
|
|
|
|
1. 播放器的监听事件有以下几种
|
|
|
|
1. IJKMPMoviePlayerLoadStateDidChangeNotification 视频加载视频状态发生改变
|
|
|
|
(1)IJKMPMovieLoadStateStalled 正在加载
|
|
|
|
(2)IJKMPMovieLoadStatePlayable 可以播放
|
|
|
|
(3)IJKMPMovieLoadStatePlaythroughOK 已经缓存完成,如果设置了自动播放,这时会自动播放
|
|
|
|
2. IJKMPMoviePlayerPlaybackStateDidChangeNotification 视频播放状态发生改变
|
|
|
|
(1)IJKMPMoviePlaybackStateStopped 播放停止
|
|
|
|
(2)IJKMPMoviePlaybackStatePlaying 播放
|
|
|
|
(3)IJKMPMoviePlaybackStatePaused 暂停
|
|
|
|
(4)IJKMPMoviePlaybackStateInterrupted 打断(停止,中断)
|
|
|
|
(5)IJKMPMoviePlaybackStateSeekingForward 向前拖动
|
|
|
|
(6)IJKMPMoviePlaybackStateSeekingBackward 向后拖动
|
|
|
|
3. IJKMPMoviePlayerPlaybackDidFinishReasonUserInfoKey 视频播放终止播放原因
|
|
|
|
4. IJKMPMoviePlayerPlaybackDidFinishNotification 视频终止播放
|
|
|
|
5. IJKMPMovieNaturalSizeAvailableNotification 视频开始播放时,用这个可以监听到视频的分辨率
|
|
|
|
6. IJKMPMoviePlayerPlaybackDidFinishReasonUserInfoKey 视频播放完成(有可能是加载失败,也有可能是播放结束)
|
|
|
|
7. IJKMPMoviePlayerPlaybackDidFinishNotification 视频播放完成(有可能是加载失败,也有可能是播放结束)
|
|
|
|
```
|
|
|
|
#### 4.4 接收数据格式介绍
|
|
|
|
|
|
|
|
1. 收到提问&回答(RequestDataDelegate和RequestDataPlayBackDelegate 中代理方法)
|
|
## 3.14 修改昵称
|
|
```
|
|
|
|
RequestDataDelegate中代理名称如下:
|
|
代理方法(可选)
|
|
- (void)onQuestionArr:(NSArray *)questionArr onAnswerArr:(NSArray *)answerArr;
|
|
|
|
|
|
|
|
RequestDataPlayBackDelegate中代理名称如下:
|
|
|
|
- (void)onParserQuestionArr:(NSArray *)questionArr onParserAnswerArr:(NSArray *)answerArr;
|
|
|
|
```
|
|
|
|
2. 提问格式,数组
|
|
|
|
```
|
|
|
|
(
|
|
|
|
{
|
|
|
|
content = question;//问题内容
|
|
|
|
encryptId = 2264AF619DD010E9;//问题ID
|
|
|
|
id = 342854;//提问ID,此ID和上面的encryptId无差别,都是提问的唯一标志,且和下面的回答id是一对多对应,一个问题可以有多条回答信息
|
|
|
|
isPublish = 1;//问题是否发布
|
|
|
|
questionUserAvatar = "";//头像
|
|
|
|
questionUserId = 00d30351184d4cbdb0fcbadd9a55ba1c;//提问问题的用户的用户id
|
|
|
|
questionUserName = qwer;//提问问题用户的用户名
|
|
|
|
time = 69006;//提问问题时间点(毫秒)
|
|
|
|
triggerTime = "2017-11-21 13:50:19";//具体时间点
|
|
|
|
}
|
|
|
|
)
|
|
|
|
```
|
|
|
|
3. 收到提问(RequestDataDelegate中代理方法)
|
|
|
|
```
|
|
|
|
- (void)onQuestionDic:(NSDictionary *)questionDic;
|
|
|
|
{
|
|
|
|
action = question;
|
|
|
|
time = 0;//新的提问和回答时间全部为0,历史的提问和回答才有正确时间
|
|
|
|
value = {
|
|
|
|
content = question;
|
|
|
|
id = BC2D248818827729;//如果该用户被禁言后,该用户发出问题的id都为-1,并且该问题只会发送给该用户,不会发送给其他用户
|
|
|
|
triggerTime = "2017-11-21 14:02:54";
|
|
|
|
userAvatar = "";
|
|
|
|
userId = 9c408a9761d74cb9b64587b2776c5327;
|
|
|
|
userName = qwer;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
注:提问者角色默认为学生
|
|
|
|
```
|
|
|
|
4 收到回答(RequestDataDelegate中代理方法)
|
|
|
|
```
|
|
|
|
- (void)onAnswerDic:(NSDictionary *)answerDic;
|
|
|
|
{
|
|
|
|
action = answer;
|
|
|
|
time = 0;//新的提问和回答时间全部为0,历史的提问和回答才有正确时间
|
|
|
|
value = {
|
|
|
|
content = answer;
|
|
|
|
isPrivate = 0;
|
|
|
|
questionId = BC2D248818827729;
|
|
|
|
questionUserId = 9c408a9761d74cb9b64587b2776c5327;
|
|
|
|
triggerTime = "2017-11-21 14:04:17";
|
|
|
|
userAvatar = "";
|
|
|
|
userId = 4c70191006d54d549e43ccff4bc1bfd1;
|
|
|
|
userName = admin;
|
|
|
|
userRole = publisher;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
5 收到30条历史聊天数据信息(RequestDataDelegate中代理方法)
|
|
|
|
```
|
|
```
|
|
- (void)onChatLog:(NSArray *)chatLogArr;
|
|
/**
|
|
(
|
|
* @brief 修改昵称
|
|
{
|
|
*/
|
|
content = message;//聊天内容
|
|
- (void)onChangeNickname:(NSString *)nickNime;
|
|
time = 68996;//聊天时间(毫秒)
|
|
|
|
userAvatar = "";//聊天者头像
|
|
|
|
userCustomMark = "";//个性化信息
|
|
|
|
userId = 00d30351184d4cbdb0fcbadd9a55ba1c;//聊天者id
|
|
|
|
userName = qwer;//聊天者用户名
|
|
|
|
userRole = student;//聊天者用户角色
|
|
|
|
}
|
|
|
|
)
|
|
|
|
```
|
|
```
|
|
6 收到学生发送的公聊信息(RequestDataDelegate中代理方法)
|
|
|
|
|
|
主动方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
- (void)onPublicChatMessage:(NSDictionary *)dic;
|
|
/**
|
|
{
|
|
* @brief 修改昵称
|
|
msg = chat;//内容
|
|
* @param nickName 修改后的昵称
|
|
time = "14:10:16";//时间
|
|
*/
|
|
useravatar = "";//头像
|
|
- (void)changeNickName:(NSString *)nickName;
|
|
usercustommark = "";//个性化信息
|
|
|
|
userid = 9c408a9761d74cb9b64587b2776c5327;//用户id
|
|
|
|
username = qwer;//用户名
|
|
|
|
userrole = student;//用户角色
|
|
|
|
}
|
|
|
|
```
|
|
```
|
|
7 收到学生禁言消息(RequestDataDelegate中代理方法)
|
|
|
|
|
|
|
|
```
|
|
|
|
- (void)onSilenceUserChatMessage:(NSDictionary *)message;
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
msg = asdfghj;
|
|
## 3.15 在线人数
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
time = "14:13:53";
|
|
```
|
|
|
|
/**
|
|
|
|
* @brief 收到在线人数
|
|
|
|
*/
|
|
|
|
- (void)onUserCount:(NSString *)count;
|
|
|
|
/**
|
|
|
|
收到老师列表
|
|
|
|
teachers = (
|
|
|
|
{
|
|
|
|
id = "";//老师id
|
|
|
|
ip = "";//IP地址
|
|
|
|
name = "";老师昵称
|
|
|
|
role = teacher;//角色
|
|
|
|
}
|
|
|
|
);
|
|
|
|
*/
|
|
|
|
-(void)onOnlineTeachers:(NSDictionary *)dic;
|
|
|
|
```
|
|
|
|
|
|
useravatar = "";
|
|
主动放法(可选)
|
|
|
|
|
|
usercustommark = "";
|
|
```
|
|
|
|
/**
|
|
|
|
* @brief 获取在线房间人数,当登录成功后即可调用此接口,登录不成功或者退出登录后就不可以调用了,如果要求实时性比较强的话,可以写一个定时器,不断调用此接口,几秒钟发一次就可以,然后在代理回调函数中,处理返回的数据,15秒响应一次
|
|
|
|
*/
|
|
|
|
- (void)roomUserCount;
|
|
|
|
/**
|
|
|
|
获取老师列表
|
|
|
|
*/
|
|
|
|
- (void)getOnlineTeachers;
|
|
|
|
```
|
|
|
|
|
|
userid = 9c408a9761d74cb9b64587b2776c5327;
|
|
|
|
|
|
|
|
username = qwer;
|
|
|
|
|
|
|
|
userrole = student;
|
|
##3.16 随堂测功能
|
|
|
|
|
|
}
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
|
|
/**
|
|
|
|
* @brief 接收到随堂测(The new method)
|
|
|
|
* rseultDic 随堂测内容
|
|
|
|
resultDic {isExist //1 随堂考存在 0随堂考不存在
|
|
|
|
practice {id //随堂考主键ID
|
|
|
|
isAnswered //false 未回答过 true 回答过
|
|
|
|
options = ({ id //选项主键ID
|
|
|
|
index //选项序号})
|
|
|
|
publishTime //发布时间
|
|
|
|
status //发布状态 1开启 0关闭
|
|
|
|
type //题目类型 0判断 1单选 2多选}
|
|
|
|
serverTime //分发时间}
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
-(void)receivePracticeWithDic:(NSDictionary *) resultDic;
|
|
|
|
/**
|
|
|
|
* @brief 随堂测提交结果(The new method)
|
|
|
|
* rseultDic 提交结果,调用commitPracticeWithPracticeId:(NSString *)practiceId options:(NSArray *)options后执行
|
|
|
|
*
|
|
|
|
resultDic {datas {practice //随堂测
|
|
|
|
{ answerResult //
|
|
|
|
id //随堂测主键ID
|
|
|
|
isRepeatAnswered //是否重置答案
|
|
|
|
options ({ count //参与人数
|
|
|
|
id //选项主键ID
|
|
|
|
index //选项序号
|
|
|
|
isCorrect //是否正确
|
|
|
|
percent //选项占比})
|
|
|
|
submitRecord ({ optionId //提交记录 提交选项ID
|
|
|
|
optionIndex //提交选项序号})
|
|
|
|
type //题型 0 判断 1单选 2多选}}}
|
|
|
|
*/
|
|
|
|
-(void)practiceSubmitResultsWithDic:(NSDictionary *) resultDic;
|
|
|
|
/**
|
|
|
|
* @brief 随堂测统计结果(The new method)
|
|
|
|
* rseultDic 统计结果,调用getPracticeStatisWithPracticeId:(NSString *)practiceId后执行
|
|
|
|
resultDic {practice { //随堂测
|
|
|
|
answerPersonNum //回答人数
|
|
|
|
correctPersonNum //回答正确人数
|
|
|
|
correctRate //正确率
|
|
|
|
id //随堂测主键ID
|
|
|
|
options ({ //选项数组
|
|
|
|
count //选择人数
|
|
|
|
id //选项ID
|
|
|
|
index //选项序号
|
|
|
|
isCorrect //是否正确
|
|
|
|
percent //选项选择率})
|
|
|
|
status //状态
|
|
|
|
type //题型 0判断 1单选 2多选}}
|
|
|
|
*/
|
|
|
|
-(void)practiceStatisResultsWithDic:(NSDictionary *) resultDic;
|
|
|
|
/**
|
|
|
|
* @brief 随堂测排名结果
|
|
|
|
* rseultDic 排名结果,调用getPracticeRankWithPracticeId:(NSString *)practiceId后执行
|
|
|
|
ressult{practice { //随堂测
|
|
|
|
id //随堂测主键ID
|
|
|
|
ranking ({ //排名
|
|
|
|
costTime //回答用时
|
|
|
|
viewerId //用户ID
|
|
|
|
viewerName //用户名})}}
|
|
|
|
*/
|
|
|
|
-(void)practiceRankResultsWithDic:(NSDictionary *) resultDic;
|
|
|
|
/**
|
|
|
|
* @brief 停止随堂测(The new method)
|
|
|
|
* rseultDic 结果
|
|
|
|
* resultDic {practiceId //随堂测主键ID}
|
|
|
|
*/
|
|
|
|
-(void)practiceStopWithDic:(NSDictionary *) resultDic;
|
|
|
|
/**
|
|
|
|
* @brief 关闭随堂测(The new method)
|
|
|
|
* rseultDic 结果
|
|
|
|
* resultDic {practiceId //随堂测主键ID}
|
|
|
|
*/
|
|
|
|
-(void)practiceCloseWithDic:(NSDictionary *) resultDic;
|
|
|
|
/**
|
|
|
|
* @brief 收到奖杯(The new method)
|
|
|
|
* dic 结果
|
|
|
|
* "type": 1 奖杯 2 其他
|
|
|
|
* "viewerName": 获奖用户名
|
|
|
|
* "viewerId": 获奖用户ID
|
|
|
|
*/
|
|
|
|
-(void)prize_sendWithDict:(NSDictionary *)dic;
|
|
|
|
```
|
|
|
|
|
|
|
|
主动方法(可选)
|
|
|
|
|
|
|
|
```
|
|
|
|
/**
|
|
|
|
* @brief 提交随堂测
|
|
|
|
* @param practiceId 随堂测ID
|
|
|
|
* @param options 选项ID
|
|
|
|
*/
|
|
|
|
- (void)commitPracticeWithPracticeId:(NSString *)practiceId options:(NSArray *)options;
|
|
|
|
/**
|
|
|
|
* @brief 获取随堂测统计信息(可多次调用)
|
|
|
|
* @param practiceId 随堂测ID
|
|
|
|
*/
|
|
|
|
-(void)getPracticeStatisWithPracticeId:(NSString *)practiceId;
|
|
|
|
/**
|
|
|
|
* @brief 获取随堂测排名(可多次调用)
|
|
|
|
* @param practiceId 随堂测ID
|
|
|
|
*/
|
|
|
|
-(void)getPracticeRankWithPracticeId:(NSString *)practiceId;
|
|
|
|
/**
|
|
|
|
* @brief 获取随堂测
|
|
|
|
* @param practiceId 随堂测ID(没有传@"")
|
|
|
|
*/
|
|
|
|
-(void)getPracticeInformation:(NSString *)practiceId;
|
|
|
|
```
|
|
|
|
|
|
|
|
## 3.17 公告
|
|
|
|
|
|
8 收到学生私聊(RequestDataDelegate中代理方法)
|
|
代理方法(可选)
|
|
|
|
|
|
```
|
|
```
|
|
- (void)OnPrivateChat:(NSDictionary *)dic;
|
|
/**
|
|
|
|
* @brief 公告
|
|
|
|
*/
|
|
|
|
- (void)announcement:(NSString *)str;
|
|
|
|
/**
|
|
|
|
* @brief 监听到有公告消息
|
|
|
|
* @dict {action //action 返回release 取出公告内容,action 返回remove 删除公告
|
|
|
|
announcement //公告内容}
|
|
|
|
*/
|
|
|
|
- (void)on_announcement:(NSDictionary *)dict;
|
|
|
|
```
|
|
|
|
|
|
{
|
|
## 3.18 跑马灯
|
|
|
|
|
|
|
|
代理方法(可选)
|
|
|
|
|
|
fromuseravatar = "";
|
|
```
|
|
|
|
/**
|
|
|
|
* @brief 跑马灯
|
|
|
|
* @param dic action [{ //事件
|
|
|
|
duration //执行时间
|
|
|
|
end { //结束位置
|
|
|
|
alpha //透明度
|
|
|
|
xpos //x坐标
|
|
|
|
ypos //y坐标 },
|
|
|
|
start { //开始位置
|
|
|
|
alpha //透明度
|
|
|
|
xpos //x坐标
|
|
|
|
ypos //y坐标}]
|
|
|
|
image { //包含图片
|
|
|
|
height //图片高度
|
|
|
|
image_url //地址
|
|
|
|
width //图片宽度}
|
|
|
|
loop //循环次数 -1 无限循环
|
|
|
|
text { //文字信息
|
|
|
|
color //文字颜色
|
|
|
|
content //文字内容
|
|
|
|
font_size //字体大小}
|
|
|
|
type //当前类型 text 文本 image 图片
|
|
|
|
*/
|
|
|
|
-(void)receivedMarqueeInfo:(NSDictionary *)dic;
|
|
|
|
```
|
|
|
|
|
|
fromuserid = 9c408a9761d74cb9b64587b2776c5327;
|
|
|
|
|
|
|
|
fromusername = qwer;
|
|
#4.常见问题
|
|
|
|
|
|
fromuserrole = student;
|
|
##4.1 旋转屏错误
|
|
|
|
|
|
usercustommark = "";
|
|
常用的旋转屏方式
|
|
|
|
|
|
msg = chat;
|
|
第一个方法决定是否支持多方向旋转屏,如果返回NO则后面的两个方法都不会再被调用,而且只会支持默认的UIInterfaceOrientationMaskPortrait方向;
|
|
|
|
|
|
time = "14:11:32";
|
|
第二个方法直接返回支持的旋转方向,该方法在iPad上的默认返回值是UIInterfaceOrientationMaskAll,iPhone上的默认返回值是UIInterfaceOrientationMaskAllButUpsideDown,官方文档有说明
|
|
|
|
|
|
touserid = 00d30351184d4cbdb0fcbadd9a55ba1c;
|
|
第三个方法返回最优先显示的屏幕方向,比如同时支持Portrait和Landscape方向,但想优先显示Landscape方向,那软件启动的时候就会先显示Landscape,在手机切换旋转方向的时候仍然可以在Portrait和Landscape之间切换
|
|
|
|
|
|
}
|
|
HD云直播的页面跳转均是采用模态形式跳转
|
|
|
|
|
|
|
|
```
|
|
|
|
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion NS_AVAILABLE_IOS(5_0);
|
|
```
|
|
```
|
|
|
|
|
|
|
|
在每个控制器或者基类控制器设置旋转选项
|
|
|
|
|
|
|
|
```
|
|
|
|
#pragma mark - 屏幕旋转
|
|
|
|
- (BOOL)shouldAutorotate{
|
|
|
|
return NO;//该旋转的页面自己变量控制
|
|
|
|
}
|
|
|
|
|
|
9 聊天信息数组(RequestDataPlayBackDelegate中代理方法)
|
|
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
|
|
|
|
{
|
|
|
|
return UIInterfaceOrientationPortrait;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
|
|
|
|
{
|
|
|
|
return UIInterfaceOrientationMaskPortrait;
|
|
|
|
}
|
|
```
|
|
```
|
|
- (void)onParserChat:(NSArray *)chatArr;
|
|
|
|
|
|
|
|
(
|
|
## 4.2 Swift实现代理错误
|
|
|
|
|
|
{
|
|
```
|
|
|
|
//初始化
|
|
|
|
let parameter = PlayParameter.init()
|
|
|
|
/**
|
|
|
|
*配置各种参数
|
|
|
|
*/
|
|
|
|
//守护代理
|
|
|
|
guard let player = RequestData else {
|
|
|
|
return}
|
|
|
|
player.delegate = self
|
|
|
|
```
|
|
|
|
|
|
content = aaa;//聊天内容
|
|
## 4.3 查看手机日志
|
|
|
|
|
|
time = 27;//聊天的时间点
|
|
首先: 在AppDelegate中写如下代码(仅限CCSDK);
|
|
|
|
|
|
userAvatar = "";//聊天用户头像
|
|
```
|
|
|
|
[[SaveLogUtil sharedInstance]isNeedToSaveLog:YES];
|
|
|
|
```
|
|
|
|
|
|
userCustomMark = "";//个性化信息
|
|
第一步:选择Windows下面的Devices and Simulators
|
|
|
|
|
|
userId = 00942719153943a4a847d8c9278f030d;//聊天用户id
|
|
第二步:点击Devices and Simulators 会出现手机信息以及测试的INSTALLED APPS, 点击设置(齿轮图标) 会出现三个选项, 选择Download Container...
|
|
|
|
|
|
userName = admin;//聊天用户名
|
|
第三步: 点击Download Container... 下载并保存日志文件,打开文件找到XXLog文件里面就是相关的打印日志
|
|
|
|
|
|
userRole = publisher;//聊天用户角色
|
|
第四步:这里可以看到相关的请求信息和打印日志, 也可以判断错误原因
|
|
|
|
|
|
}
|
|
## 4.4 编译失败和打包上架打包失败
|
|
|
|
|
|
)
|
|
错误大意为
|
|
|
|
|
|
|
|
```
|
|
|
|
Failed to verify bitcode in xxxxx
|
|
|
|
error: Bundle only contains bitcode-marker /var/folders/s5/lnk362pd4cs0lmtn_43ppjzw0000gn/T/XcodeDistPipeline.2TS/Root/Payload/268YK.appxxxxxxxxxx (armv7)
|
|
```
|
|
```
|
|
|
|
|
|
|
|
解决办法:
|
|
|
|
|
|
|
|
第一步: xcode -> file -> Workspace Settings
|
|
|
|
|
|
|
|
第二步: Shared Workspace Settings:
|
|
|
|
|
|
## 5.API查询
|
|
第三步:Build System -> Legacy Build System
|
|
|
|
|
|
Doc目录打开index.html文件
|
|
## 4.5 提交问卷的格式
|
|
|
|
|
|
## 6.Q&A
|
|
主动提交问卷这个方法参数格式
|
|
|
|
|
|
### 6.1如发现 dyld: Library not loaded: @rpath/CCPush.framework/CCPush
|
|
```
|
|
Referenced from: /var/containers/Bundle/Application/3CC41924-7F22-48FC-AAD1-7C2C089EF749/demo.app/demo
|
|
-(void)commitQuestionnaire:(NSDictionary *)dic
|
|
Reason: image not found问题
|
|
```
|
|
将报错的类库添加进入
|
|
|
|
General -> Embedded Binaries 和 General -> Linked Frameworks and Libraries 两处即可
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
{
|
|
|
|
subjectsAnswer = (
|
|
|
|
{
|
|
|
|
//单选
|
|
|
|
selectedOptionId = 6DBB147BC4EF99A7;
|
|
|
|
subjectId = 5DEEA9F9FD1DDFAD;
|
|
|
|
},
|
|
|
|
{
|
|
|
|
//多选
|
|
|
|
selectedOptionIds = "A2F4436135131236,1A8C59C6F3A774F5";
|
|
|
|
subjectId = 658A573395F3E00D;
|
|
|
|
},
|
|
|
|
{
|
|
|
|
//问答
|
|
|
|
answerContent = Qqq;
|
|
|
|
subjectId = 10F9E9D82094F36C;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
``` |