[TOC]
云直播回放观看端SDK开发指南
1.概述
1.1 阅读对象
本文档为技术文档,需要阅读者:
- 具备基本的iOS开发能力
- 准备接入CC视频的直播SDK相关功能
- 对CC云直播产品使用方法有基础的了解,使用帮助地址
1.2 功能特性
功能 | 描述 |
---|---|
直播视频 | 观看直播视频 |
视频倍速 | 观看直播回放倍速播放 |
文档展示 | 能够观看当前直播文档 |
聊天 | 所有直播时的聊天 |
简介 | 支持对直播间的信息展示 |
广播 | 支持历史全体消息 |
问答 | 支持历史问答 |
2.开发准备
2.1 开发环境
- Xcode 10.0 或以上版本
- 支持 iOS 9.0 或以上版本的 iOS 设备
- 有效的 获得场景视频 云直播账号
2.2 SDK配置
2.2.1 CocoaPods集成
已安装CocoaPods
如果是有连麦的SDK:
pod 'CCLivePlaySDK', '~> 3.8.0'
如果是无连麦的SDK:
v3.11.2 之前的版本请用如下链接:
pod 'CCLivePlaySDK', :podspec => 'https://raw.githubusercontent.com/CCVideo/Live_iOS_Play_SDK/3.8.0/CCLivePlaySDK.podspec'
v3.11.2 之后的版本请用如下链接:
pod 'CCLivePlaySDK', :podspec => 'https://hdgit.bokecc.com/ccvideo/Live_iOS_Play_SDK/raw/3.11.2/CCLivePlaySDK.podspec'
PS:其中3.8.0与3.11.2为SDK版本号可自行更改。
未安装CocoaPods
-
安装CocoaPods
打开终端:>_ 1、查看当前Ruby版本
ruby -v
2、升级Ruby环境,首先需要安装rvm(第一步要下载一些东西等两分钟左右)
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 .....
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、更换源
sudo gem update --system gem sources --remove https://rubygems.org/ gem sources --add https://gems.ruby-china.com/
8、为了验证你的Ruby镜像是并且仅是ruby-china,执行以下命令查看
gem sources -l 如果是以下结果说明正确,如果有其他的请自行百度解决 *** CURRENT SOURCES *** https://gems.ruby-china.com/
9、这时候才正式开始安装CocoaPods
sudo gem install -n /usr/local/bin cocoapods
10、如果安装了多个Xcode使用下面的命令选择(一般需要选择最近的Xcode版本)
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
11、安装本地库
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/ 然后就是漫长的等待,当然,网络好的情况下会更快
-
在Podfile文件中添加
如果是有连麦的SDK: pod 'CCLivePlaySDK', '~> 3.8.0' 如果是无连麦的SDK: v3.11.2 之前的版本请用如下链接: pod 'CCLivePlaySDK', :podspec => 'https://raw.githubusercontent.com/CCVideo/Live_iOS_Play_SDK/3.8.0/CCLivePlaySDK.podspec' v3.11.2 之后的版本请用如下链接: pod 'CCLivePlaySDK', :podspec => 'https://hdgit.bokecc.com/ccvideo/Live_iOS_Play_SDK/raw/3.11.2/CCLivePlaySDK.podspec' PS:其中3.8.0与3.11.2为SDK版本号可自行更改。
-
在终端中执行
pod install
ps:目前CocoaPods集成仅支持3.8.0及以后的版本,旧版本暂不支持CocoaPods集成
2.2.2 手动集成
1.将SDK文件夹内的所有文件拖到项目中
command + b 编译,如果报错" file '...xxx/IJKMediaFramework.framework/IJKMediaFramework' for architecture arm64 "
解决方案:
Targets -> Build Settings -> 搜索 "Enable Bitcode" 设置为 "NO"
2.command + r 运行
如果报错" dyld: Library not loaded: @rpath/XXX.framework "
解决方案:
Targets -> Build Phases ->
点击左上角 "+" 按钮 ->
选择 "New Copy Files Phase" ->
点击新添加的 Copy Files 前面的下拉箭头 ->
Destination 选择 "Frameworks" ->
点击当前目录下的 "+" 将SDK包含的.framework 包添加即可
2.3 日志存储
在AppDelegate.m文件导入头文件
#import "CCSDK/SaveLogUtil.h"
在启动方法中添加日志存储
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
/**
* @brief 是否存储日志
*/
[[SaveLogUtil sharedInstance]isNeedToSaveLog:YES];
return YES;
}
2.4 错误码
服务错误类型
ERROR_SERVICE_TYPE
ERROR_ROOM_STATE = 1001 直播间状态不可用,可能没有开始推流
ERROR_USELESS_INFO = 1002 没有获取到有用的视频信息
ERROR_PASSWORD = 1003 密码错误
系统错误类型
ERROR_SYSTEM_TYPE
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 获取加密地址失败
3.快速集成
3.1 配置参数
3.1.1 调用方法
/**
* @brief 登录房间
* @param parameter 配置参数信息
* 必填参数 userId //用户ID
* 必填参数 roomId //房间ID
* 必填参数 viewerName //用户名称
* 必填参数 token //房间密码
*/
- (id)initLoginWithParameter:(PlayParameter *)parameter;
/// 初始化SDK
/// @param parameter 参数
/// @param succed 初始化成功回调
/// @param player 播放视图回调
/// @param failed 初始化失败回调
- (id)initSDKWithParameter:(PlayParameter *)parameter
succed:(initSuccedClosure)succed
player:(HDSPlayerViewClosure)player
failed:(initFailedClosure)failed;
代理方法
/**
* @brief 媒体准备完成
*/
- (void)mediaPrepared;
/**
* @brief 请求回放地址失败
*/
-(void)requestFailed:(NSError *)error reason:(NSString *)reason;
/**
* @brief 登录成功
*/
- (void)loginSucceedPlayBack;
/**
* @brief 登录失败
*/
-(void)loginFailed:(NSError *)error reason:(NSString *)reason;
3.1.2 集成
导入头文件
#import "CCSDK/RequestDataPlayBack.h"//SDK
声明变量
@property (nonatomic,strong)RequestData * requestDataPlayBack;//sdk
配置参数:PlayParameter的属性如下
/**
* @brief 用户ID
*/
@property(nonatomic, copy)NSString *userId;//用户ID
/**
* @brief 房间ID
*/
@property(nonatomic, copy)NSString *roomId;//房间ID
/**
* @brief 用户名称
*/
@property(nonatomic, copy)NSString *viewerName;//用户名称
/**
* @brief 房间密码
*/
@property(nonatomic, copy)NSString *token;//房间密码
/**
* @brief 回放ID
*/
@property(nonatomic, copy)NSString *recordId;//回放ID
/**
* @brief 用户自定义参数,需和后台协商,没有定制传@""
*/
@property(nonatomic, copy)NSString *viewerCustomua;//用户自定义参数,需和后台协商,没有定制传@"" 长度不能超过40个字符
/**
* json格式字符串,可选,自定义用户信息,该信息会记录在用户访问记录中,用于统计分析使用(长度不能超过200个字符,若直播间启用接口验证则该参数无效)如果不需要的话就不要传值
* 格式如下:
* viewercustominfo: '{"exportInfos": [ {"key": "城市", "value": "北京"}, {"key": "姓名", "value": "哈哈"}]}'
*/
@property(nonatomic, copy)NSString *viewercustominfo;
/**
* @brief 文档父类窗口
*/
@property(nonatomic,strong)UIView *docParent;//文档父类窗口
/**
* @brief 文档区域
*/
@property(nonatomic,assign)CGRect docFrame;//文档区域
/**
* @brief 屏幕适配方式
* 0:HDSMediaScalingModeNone
* 1:HDSMediaScalingModeAspectFit
* 2:HDSMediaScalingModeAspectFill
* 3:HDSMediaScalingModeFill
*/
@property(assign, nonatomic)NSInteger scalingMode;//屏幕适配方式,含义见上面
/**
* @brief ppt默认底色,不写默认为白色(@"#FFFFFF")
*/
@property(nonatomic, copy) NSString *defaultColor;//ppt默认底色,不写默认为白色(@"#FFFFFF")
/**
* @brief /后台是否继续播放,注意:如果开启后台播放需要打开 xcode->Capabilities->Background Modes->on->Audio,AirPlay,and Picture in Picture
*/
@property(nonatomic,assign)BOOL pauseInBackGround;//后台是否继续播放,注意:如果开启后台播放需要打开 xcode->Capabilities->Background Modes->on->Audio,AirPlay,and Picture in Picture
/**
* @brief PPT适配模式分为四种
* PPT适配模式分为四种,
* 1.拉伸填充,PPT内容全部展示在显示区域,会被拉伸或压缩,不会存在黑边
* 2.等比居中,PPT内容保持原始比例,适应窗口展示在显示区域,会存在黑边
* 3.等比填充,PPT内容保持原始比例,以横向或纵向适应显示区域,另一方向将会超出显示区域,超出部分会被裁减,不会存在黑边
* 4.根据直播间文档显示模式的返回值进行设置(推荐)
*/
@property(assign, nonatomic)NSInteger PPTScalingMode;//PPT适配方式,含义见上面
/**
* @brief PPT是否允许滚动
*/
@property(nonatomic, assign)BOOL pptInteractionEnabled;
/**
* @brief 设置当前的文档模式,
* 1.切换至跟随模式(默认值)值为0,
* 2.切换至自由模式;值为1,
*/
@property(assign, nonatomic)NSInteger DocModeType;//设置当前的文档模式
新增 HDQualityModel 类 (切换线路清晰度)
@interface HDQualityModel : NSObject
/** 清晰度 */
@property (nonatomic, copy) NSString * _Nonnull quality;
/** 描述 */
@property (nonatomic, copy) NSString * _Nonnull desc;
@end
新增枚举类型
/**
* 音视频模式
* PLAY_MODE_TYEP_VIDEO 视频
* PLAY_MODE_TYEP_AUDIO 音频
*/
typedef NS_ENUM(NSUInteger, PLAY_MODE_TYEP) {
PLAY_MODE_TYEP_VIDEO,//视频
PLAY_MODE_TYEP_AUDIO,//音频
};
/**
* 是否有音频线路
* HAVE_AUDIO_LINE_TURE 有音频线路
* HAVE_AUDIO_LINE_FALSE 无音频线路
*/
typedef NS_ENUM(NSUInteger, HAVE_AUDIO_LINE) {
HAVE_AUDIO_LINE_TURE,//有音频线路
HAVE_AUDIO_LINE_FALSE,//无音频线路
};
新增 HDReplayDotModel 类
/** 打点时间:单位:S */
@property (nonatomic, assign) NSInteger time;
/** 打点描述 */
@property (nonatomic, copy) NSString * _Nullable desc;
开始配置
//第一步:实例化参数类
PlayParameter *parameter = [[PlayParameter alloc] init];
//配置PlayParameter里面的属性,如userId,roomId等!
//第二步实例化RequestData类
_requestDataPlayBack = [[RequestDataPlayBack alloc] initSDKWithParameter:parameter succed:^(BOOL succed) {
} player:^(UIView * _Nonnull playerView) {
--> **playerView** 即为视频流视图
} failed:^(NSError *error, NSString *reason) {
}];
_requestDataPlayBack.delegate = self;
//第三步添加代理
_requestDataPlayBack.delegate = self;
初始化SDK(新)
方法 | 注释 |
---|---|
(id)initSDKWithParameter: succed: player: failed: | 初始化SDK |
示例代码
/// 初始化SDK
/// @param parameter 参数
/// @param succed 初始化成功回调
/// @param player 播放视图回调
/// @param failed 初始化失败回调
- (id)initSDKWithParameter:(PlayParameter *)parameter
succed:(initSuccedClosure)succed
player:(HDSPlayerViewClosure)player
failed:(initFailedClosure)failed;
参数 | 注释 |
---|---|
parameter | 初始化SDK参数,其中 "playerParent","playerFrame" 已废弃删除,新的流视图由 HDSPlayerViewClosure 异步回调,自行处理 |
succed | 初始化SDK成功回调 |
player | 流视图异步回调,存在回调多次。 |
failed | 初始化SDK失败回调 |
流视图(callback回调)
注意 |
---|
“新的流视图” 通过 初始化SDK(initSDKWithParameter:)方法中的 player:,通过 callback 返回 “流视图” |
“流视图”(属于UIView 类型),所在 视图区域,视图大小 可根据业务自行调整设置 |
添加代理
@interface 您的控制器 ()<RequestDataPlayBackDelegate>
实现代理
/**
* @brief 媒体准备完成
*/
- (void)mediaPrepared;
/**
* @brief 请求回放地址失败
*/
-(void)requestFailed:(NSError *)error reason:(NSString *)reason;
代理方法 (可选)
/**
* @brief 播放器时间
* @param currentTime 当前时间
* @param totalTime 总时间
*/
- (void)HDPlayerCurrentTime:(NSTimeInterval)currentTime totalTime:(NSTimeInterval)totalTime;
3.2 观看回放
3.2.1 代理方法(可选)
/**
* @brief 加载视频失败
*/
- (void)playback_loadVideoFail;
/**
* @brief 回放的开始时间和结束时间
* @param dic {endTime //结束时间
startTime //开始时间 }
*/
-(void)liveInfo:(NSDictionary *)dic;
/**
* @brief 视频状态
* rseult playing/paused/loading
*/
-(void)videoStateChangeWithString:(NSString *) result;
/**
* @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;
/**
* The New Method (3.13.0)
* @brief 是否开启音频模式
* @param hasAudio HAVE_AUDIO_LINE_TURE 有音频 HAVE_AUDIO_LINE_FALSE 无音频
*
* 触发回调条件 1.初始化SDK登录成功后
*/
- (void)HDAudioMode:(HAVE_AUDIO_LINE)hasAudio;
/**
* The New Method (3.13.0)
* @brief 房间所包含的清晰度 (会多次回调)
* @param dict 清晰度数据
* 清晰度数据 key(包含的键值) type(数据类型) description(描述)
* qualityList(清晰度列表) array @[HDQualityModel(清晰度详情),HDQualityModel(清晰度详情)]
* currentQuality(当前清晰度) object HDQualityModel(清晰度详情)
*
* 触发回调条件 1.初始化SDK登录成功后
* 2.主动调用切换清晰度方法
* 3.主动调用切换视频模式回调
*/
- (void)HDReceivedVideoQuality:(NSDictionary *)dict;
/**
* The New Method (3.13.0)
* @brief 房间包含的音视频线路 (会多次回调)
* @param dict 线路数据
* 线路数据 key(包含的键值) type(数据类型) description(描述)
* lineList(线路列表) array @[@"line1",@"line2"]
* indexNum(当前线路下标) integer 0
*
* 触发回调条件 1.初始化SDK登录成功后
* 2.主动调用切换清晰度方法
* 3.主动调用切换线路方法
* 4.主动调用切换音视频模式回调
*/
- (void)HDReceivedVideoAudioLines:(NSDictionary *)dict;
3.2.2 主动方法(可选)
/**
* @brief 销毁文档和视频,清除视频和文档的时候需要调用,推出播放页面的时候也需要调用
*/
- (void)requestCancel;
/**
* @brief 播放器暂停
*/
- (void)pausePlayer;
/**
* @brief 播放器播放
*/
- (void)startPlayer;
/**
* @brief 播放器关闭
*/
- (void)shutdownPlayer;
/**
* @brief 播放器停止
*/
- (void)stopPlayer;
/**
* @brief 从头重新播放
*/
- (void)replayPlayer;
/**
* @brief 播放器是否播放
*/
- (BOOL)isPlaying;
/**
* @brief 播放器当前播放时间
*/
- (NSTimeInterval)currentPlaybackTime;
/**
* @brief 设置播放器当前播放时间(用于拖拽进度条时掉用的)
*/
- (void)setCurrentPlaybackTime:(NSTimeInterval)time;
/**
* @brief 回放视频总时长
*/
- (NSTimeInterval)playerDuration;
/**
* @brief 设置后台是否可播放
*/
- (void)setpauseInBackGround:(BOOL)pauseInBackGround;
/**
* @brief 改变文档背景颜色
@param hexColor 字符串,传颜色的HEXColor 如:#000000
*/
- (void)changeDocWebColor:(NSString *)hexColor;
/**
* @brief 获取随堂测信息
*/
-(void)getPracticeInformation;
/**
* The New Method (3.13.0)
* @brief 切换播放类型
* @param mode PLAY_MODE_TYEP_VIDEO 视频模式(默认)
* PLAY_MODE_TYEP_AUDIO 音频模式(当前回放包含音频线路)
* @param completion 切换结果
* { success 0 切换成功 -1切换失败 -2 切换频繁
* reason 错误原因 }
*
* 切换播放器类型 切换为音频,回调 - (void)HDReceivedVideoAudioLines:(NSDictionary *)dict;
* 切换为视频,回调 - (void)HDReceivedVideoQuality:(NSDictionary *)dict;
* - (void)HDReceivedVideoAudioLines:(NSDictionary *)dict;
*
*/
- (void)changePlayMode:(PLAY_MODE_TYEP)mode completion:(void (^)(NSDictionary * results))completion;
/**
* The New Method (3.13.0)
* @brief 切换清晰度
* @param quality 清晰度
* @param completion 切换结果
* { success 0 切换成功 -1切换失败 -2 切换频繁
* reason 错误原因 }
*
* 切换清晰度回调 - (void)HDReceivedVideoQuality:(NSDictionary *)dict;
* - (void)HDReceivedVideoAudioLines:(NSDictionary *)dict;
*/
- (void)changeQuality:(NSString *)quality completion:(void (^)(NSDictionary * results))completion;
/**
* The New Method (3.13.0)
* @brief 切换线路
* @param index 选择线路下标
* @param completion 切换结果
* { success 0 切换成功 -1切换失败 -2 切换频繁
* reason 错误原因 }
*
* 切换线路回调方法 - (void)HDReceivedVideoAudioLines:(NSDictionary *)dict;
*/
- (void)changeLine:(NSInteger)index completion:(void (^)(NSDictionary * results))completion;
3.3 文档功能
3.3.1 代理方法(可选)
/**
* @brief 获取文档内白板或者文档本身的宽高,来进行屏幕适配用的
*/
- (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 回放翻页数据列表
* @param array[{ docName //文档名
pageTitle //页标题
time //时间
url //地址 }]
*/
- (void)pageChangeList:(NSMutableArray *)array;
/**
* @brief 双击ppt
*/
- (void)doubleCllickPPTView;
/**
* @brief 文档加载状态(The new method)
* index
* 0 文档组件初始化完成
* 1 动画文档加载完成
* 2 非动画文档加载完成
*/
- (void)docLoadCompleteWithIndex:(NSInteger)index;
/**
* @brief 回放打点数据
* @param dotList 打点信息
* @[HDReplayDotModel,HDReplayDotModel]
*/
- (void)HDReplayDotList:(NSArray *)dotList;
3.3.2 主动方法(可选)
/**
* @brief 获取文档区域内白板或者文档本身的宽高比,返回值即为宽高比,做屏幕适配用
*/
- (CGFloat)getDocAspectRatio;
/**
* @brief 改变文档区域大小,主要用在文档生成后改变文档窗口的frame
*/
- (void)changeDocFrame:(CGRect) docFrame;
/**
* @brief 改变文档父窗口
*/
- (void)changeDocParent:(UIView *) docParent;
/**
* @brief 主动调用方法 用于调整PPT缩放模式
* @param pptScalingMode PPT缩放模式
* 1 = 拉伸填充:PPT内容全部展示在显示区域,会被拉伸或压缩,不会存在黑边
* 2 = 等比居中:PPT内容保持原始比例,适应窗口展示在显示区域,会存在黑边
* 3 = 等比填充:PPT内容保持原始比例,以横向或纵向适应显示区域,另一方向将会超出显示区域,超出部分会被裁减,不会存在黑边
*/
- (void)changeDocPPTScalingMode:(NSInteger)pptScalingMode;
3.4 房间信息
代理方法(可选)
/**
* @brief 获取房间信息,主要是要获取直播间模版来类型,根据直播间模版类型来确定界面布局
* 房间信息
* baseRecordInfo = {
description = "简介";
title = "标题";
};
* 房间模版类型:[dic[@"templateType"] integerValue];
* 模版类型为1: 聊天互动: 无 直播文档: 无 直播问答: 无
* 模版类型为2: 聊天互动: 有 直播文档: 无 直播问答: 有
* 模版类型为3: 聊天互动: 有 直播文档: 无 直播问答: 无
* 模版类型为4: 聊天互动: 有 直播文档: 有 直播问答: 无
* 模版类型为5: 聊天互动: 有 直播文档: 有 直播问答: 有
* 模版类型为6: 聊天互动: 无 直播文档: 无 直播问答: 有
*/
-(void)roomInfo:(NSDictionary *)dic;
/**
* @brief 服务器端给自己设置的信息(The new method)
* viewerId 服务器端给自己设置的UserId
* groupId 分组id
* name 用户名
*/
-(void)setMyViewerInfo:(NSDictionary *) infoDic;
3.5 聊天功能
聊天功能的方法回调,相关类RequestDataPlayBack,相关方法如下:
方法 | 说明 | 备注 |
---|---|---|
onParserChat | 解析本房间的历史聊天数据 | RequestDataPlayBack 代理方法(可选) |
示例代码
/**
* @brief 解析本房间的历史聊天数据
* @param arr 聊天数组
*/
- (void)onParserChat:(NSArray *)arr;
其中聊天数组包含字段信息如下:
字段 | 类型 | 注释 |
---|---|---|
chatId | String | 聊天消息ID |
content | String | 聊天消息内容 |
groupId | String | 组ID |
time | int | 聊天消息时间 秒 |
userId | String | 发送人userId |
userName | String | 发送人昵称 |
userRole | String | 发送人角色 (具体参考 回放用到的 “角色” 字段含义) |
userAvatar | String | 发送人头像 |
userCustomMark | String | 发送人自定义标记 |
role | int | 发送人角色 (具体参考 回放用到的 “角色” 字段含义) |
status | String | 是否显示此条消息(0: 不显示 1:显示) |
3.6 问答功能
问答功能的方法回调,相关类RequestDataPlayBack,相关方法如下:
方法 | 说明 | 备注 |
---|---|---|
onParserQuestionArr onParserAnswerArr | 解析本房间的历史问答数据 | RequestDataPlayBack 代理方法(可选) |
示例代码
/**
* @brief 收到本房间的历史提问&回答
*/
- (void)onParserQuestionArr:(NSArray *)questionArr onParserAnswerArr:(NSArray *)answerArr;
其中 questionArr 数据中包含的字段信息如下:
字段 | 类型 | 注释 |
---|---|---|
id | String | 问答ID |
content | String | 问答内容 |
groupId | String | 组ID |
time | int | 问答发布时间 秒 (相对时间) |
questionUserId | String | 发送人ID |
questionUserName | String | 发送人昵称 |
questionUserAvatar | String | 发送人头像 |
encryptId | String | 加密ID |
isPublish | int | 是否发布此条问答 |
ttriggerTime | String | 问答发布时间 秒 (绝对时间)例:"2012-09-03 00:09:43" |
answerArr 数组中包含的字段信息如下:
字段 | 类型 | 注释 |
---|---|---|
content | Sting | 回复内容 |
groupId | String | 组ID |
id | String | 回复ID |
isPrivate | int | 是否是私密回复 |
time | int | 发布回复的时间 秒 (相对时间) |
triggerTime | String | 发布回复的时间 秒 (角色时间)例:"2012-09-03 00:09:43" |
answerUserAvatar | String | 发送人头像 |
answerUserId | String | 发送人ID |
answerUserName | String | 发送人昵称 |
answerUserRole | String | 发送人角色 (具体参考 回放用到的 “角色” 字段含义) |
encryptId | String | 加密ID |
3.7 广播功能
广播功能的方法回调,相关类RequestDataPlayBack,相关方法如下:
方法 | 说明 | 备注 |
---|---|---|
broadcastHistory_msg | 解析本房间的广播数据 | RequestDataPlayBack 代理方法(可选) |
示例代码
/**
* @brief 收到本房间历史广播
* content 广播内容
* time 发布时间(单位:秒)
*/
- (void)broadcastHistory_msg:(NSArray *)array;
其中聊天数组包含字段信息如下:
字段 | 类型 | 注释 |
---|---|---|
content | String | 广播内容 |
time | int | 发送广播时间 秒 |
publisherId | String | 发送人ID |
publisherName | String | 发送人昵称 |
publisherRole | String | 发送人角色 (具体参考 回放用到的 “角色” 字段含义) |
3.8 随堂测
主动方法(可选)
/**
* 3.16.0 new
* @brief 获取全量随堂测数据
* @param completion 数据回调
*/
- (void)fetchAllPractic:(void (^)(NSArray * results))completion;
3.9 视频播放状态
播放器状态类型
/**
* 视频播放状态
* HDSMediaPlaybackStateStopped 播放停止
* HDSMediaPlaybackStatePlaying 开始播放
* HDSMediaPlaybackStatePaused 暂停播放
* HDSMediaPlaybackStateInterrupted 播放间断
* HDSMediaPlaybackStateSeekingForward 播放快进
* HDSMediaPlaybackStateSeekingBackward 播放后退
*/
typedef NS_ENUM(NSUInteger, HDSMediaPlaybackState) {
HDSMediaPlaybackStateStopped,
HDSMediaPlaybackStatePlaying,
HDSMediaPlaybackStatePaused,
HDSMediaPlaybackStateInterrupted,
HDSMediaPlaybackStateSeekingForward,
HDSMediaPlaybackStateSeekingBackward,
};
/**
* 视频加载状态
* HDSMediaLoadStateUnknown 未知状态
* HDSMediaLoadStatePlayable 视频未完成全部缓存,但已缓存的数据可以进行播放
* HDSMediaLoadStatePlaythroughOK 缓冲已经完成
* HDSMediaLoadStateStalled 缓冲已经开始
*/
typedef NS_ENUM(NSUInteger, HDSMediaLoadState) {
HDSMediaLoadStateUnknown,
HDSMediaLoadStatePlayable,
HDSMediaLoadStatePlaythroughOK,
HDSMediaLoadStateStalled,
};
/**
* 视频播放完成原因
* HDSMediaFinishReasonPlaybackEnded 自然播放结束
* HDSMediaFinishReasonUserExited 用户人为结束
* HDSMediaFinishReasonPlaybackError 发生错误崩溃结束
*/
typedef NS_ENUM(NSUInteger, HDSMediaFinishReason) {
HDSMediaFinishReasonPlaybackEnded,
HDSMediaFinishReasonUserExited,
HDSMediaFinishReasonPlaybackError,
};
代理方法(可选)
/**
* @brief 视频状态改变
* @param state
* HDSMediaPlaybackStateStopped 播放停止
* HDSMediaPlaybackStatePlaying 开始播放
* HDSMediaPlaybackStatePaused 暂停播放
* HDSMediaPlaybackStateInterrupted 播放间断
* HDSMediaPlaybackStateSeekingForward 播放快进
* HDSMediaPlaybackStateSeekingBackward 播放后退
*/
- (void)HDSMediaPlayBackStateDidChange:(HDSMediaPlaybackState)state;
/**
* @brief 视频加载状态
* @param state 播放状态
* HDSMediaLoadStateUnknown 未知状态
* HDSMediaLoadStatePlayable 视频未完成全部缓存,但已缓存的数据可以进行播放
* HDSMediaLoadStatePlaythroughOK 缓冲已经完成
* HDSMediaLoadStateStalled 缓冲已经开始
*/
- (void)HDSMediaLoadStateDidChange:(HDSMediaLoadState)state;
/**
* @brief 视频播放完成原因
* @param reason 原因
* HDSMediaFinishReasonPlaybackEnded 自然播放结束
* HDSMediaFinishReasonUserExited 用户人为结束
* HDSMediaFinishReasonPlaybackError 发生错误崩溃结束
*/
- (void)HDSMediaPlayerPlaybackDidFinish:(HDSMediaFinishReason)reason;
/**
* @brief 播放器初始化完成 (会多次回调)
* @param dict 数据
*/
- (void)HDMediaPlaybackIsPreparedToPlayDidChange;
3.10 视频缓存速度
代理方法(可选)
/**
* @brief 视频加载速度
* @param speed 视频加载速度字符串
*/
- (void)onBufferSpeed:(NSString *)speed;
3.11 防录屏
防录屏功能拆分到demo层处理,具体实现参考 4.0.0 demo
4.常见问题
4.1 旋转屏错误
常用的旋转屏方式
第一个方法决定是否支持多方向旋转屏,如果返回NO则后面的两个方法都不会再被调用,而且只会支持默认的UIInterfaceOrientationMaskPortrait方向;
第二个方法直接返回支持的旋转方向,该方法在iPad上的默认返回值是UIInterfaceOrientationMaskAll,iPhone上的默认返回值是UIInterfaceOrientationMaskAllButUpsideDown,官方文档有说明
第三个方法返回最优先显示的屏幕方向,比如同时支持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;//该旋转的页面自己变量控制
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
4.2 Swift实现代理错误
//初始化
let parameter = PlayParameter.init()
/**
*配置各种参数
*/
//守护代理
guard let player = requestDataPlayBack else {
return}
player.delegate = self
4.3 查看手机日志
首先: 在AppDelegate中写如下代码(仅限CCSDK);
[[SaveLogUtil sharedInstance]isNeedToSaveLog:YES];
第一步:选择Windows下面的Devices and Simulators
第二步:点击Devices and Simulators 会出现手机信息以及测试的INSTALLED APPS, 点击设置(齿轮图标) 会出现三个选项, 选择Download Container...
第三步: 点击Download Container... 下载并保存日志文件,打开文件找到XXLog文件里面就是相关的打印日志
第四步:这里可以看到相关的请求信息和打印日志, 也可以判断错误原因
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:
第三步:Build System -> Legacy Build System
4.5 关于api回调所在线程问题
/**
* @brief 回放翻页数据列表 (会在子线程回调)
*/
- (void)pageChangeList:(NSMutableArray *)array;
/**
* @brief 获取ppt当前页数和总页数 (会在子线程回调)
*
* 回调当前翻页的页数信息
* 白板docTotalPage一直为0, pageNum从1开始
* 其他文档docTotalPage为正常页数,pageNum从0开始
* @param dictionary 翻页信息
*/
- (void)onPageChange:(NSDictionary *) dictionary;
/**
* @brief 文档加载状态 (会在子线程回调)
* index
* 0 文档组件初始化完成
* 1 动画文档加载完成
* 2 非动画文档加载完成
*/
- (void)docLoadCompleteWithIndex:(NSInteger)index;
PS:直播、在线回放只有上述api会在子线程回调,其余的api均在主线程进行回调。
4.6 回放用到的 “角色” 字段含义
字段 | 注释 | int值参考 |
---|---|---|
云直播角色 | ||
publisher | 主讲 | 1 |
teacher | 助教 | 2 |
host | 主持人 | 3 |
student | 学生 | 4 |
other | 其他 | 0 |
云课堂角色 | ||
presenter | 讲师 | 10 |
talker | 学生 | 11 |
audience | 旁听 | 12 |
inspector | 隐身者 | 13 |
assistant | 助教 | 14 |