[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 集成云直播 (推荐)
4.x.x 系列集成方式
**必须 ** 需在 Podfile 文件中添加以下代码(最新)
pod 'CCLivePlaySDK', '4.9.0'
pod 'HDVideoClass_BSDK', '6.25.0'
pod 'HDSSZip'
pod 'HDSCocoaLumberjack', '4.9.0'
pod 'AgoraRtcEngine_iOS', '3.7.2'
pod 'HDSAliyunPlayer', '4.9.0'
pod 'HDStreamLib'
可选(互动组件)
pod 'HDSInteractionEngine', '4.9.0'
pod 'HDSLikeModule', '4.9.0'
pod 'HDSGiftModule', '4.9.0'
pod 'HDSVoteModule', '4.9.0'
pod 'HDSRedEnvelopeModule', '4.9.0'
pod 'HDSInvitationCardModule', '4.9.0'
pod 'HDSQuestionnaireModule', '4.9.0'
pod 'HDSLiveStoreModule', '4.9.0'
3.21.0 及后续版本
pod 'CCLivePlaySDK'
pod 'HDSCCFuncTool', '~> 6.10.10'
pod 'HDSSZip'
pod 'HDSCocoaLumberjack'
pod 'AgoraRtcEngine_iOS', '3.7.2'
3.17.7 至 3.19.0 版本集成方式
pod 'CCLivePlaySDK'
pod 'HDSCCFuncTool', '~> 6.10.10'
pod 'HDSSZip'
pod 'HDSCocoaLumberjack'
3.17.6 及以前系列版本集成方式
如果是 “有连麦” 的 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'
v3.17.8 之后版本可使用:
pod 'CCLivePlaySDK_NoMediaCall'
pod 'HDSCCFuncTool', '~> 6.10.10'
pod 'HDSSZip'
pod 'HDSCocoaLumberjack'
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 日志存储 *( 3.17.7 升级须知,必须添加该方法)
注:日志收集功能为 必选项 ,本地接入需要使用最新的 CCBundle 资源文件
新增依赖库 | Cocoapods 接入 | 本地接入 | 签名选择 |
---|---|---|---|
CCFuncTool.framework (动态库) | pod 'HDSCCFuncTool' | 下载zip包中 CCFuncTool 文件夹下,拖入项目中 | Embed & Sign |
SSZipArchive.framework (动态库) | pod 'HDSSZip' | 下载zip包中 CCFuncTool 文件夹下,拖入项目中 | Embed & Sign |
CocoaLumberjack.framework (动态库) | pod 'HDSCocoaLumberjack' | 下载zip包中 HDSCocoaLumberjack 文件夹下,拖入项目中 | Embed & Sign |
在AppDelegate.m文件导入头文件
#import "CCSDK/HDSPreserve.h"
在启动方法中添加日志存储
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 日志收集
[[HDSPreserve shared] HDSApplicationDidFinishLaunching];
return YES;
}
- (void)applicationWillTerminate:(UIApplication *)application {
// 日志收集
[[HDSPreserve shared] HDSApplicationWillTerminate];
}
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;
初始化SDK(旧)( 仅 3.x.x 版本可用 )
方法 | 注释 |
---|---|
(id)initWithParameter:(PlayParameter *) | 初始化 |
示例代码
/**
* @brief 进入房间,并请求画图聊天数据并播放视频(可以不登陆,直接从此接口进入直播间)
* @param parameter 配置参数信息
* 必填参数 userId;
* 必填参数 roomId;
* 非必填参数 liveid;(已废弃)
* 必填参数 viewerName;
* 必填参数 token;
* 必填参数 docParent;
* 必填参数 docFrame;
* 必填参数 playerParent;
* 必填参数 playerFrame;
* 非必填参数 security;
* 必填参数 pauseInBackGround;
* 必填参数 defaultColor;
* 必填参数 PPTScalingMode;
* 必填参数 scalingMode;
* 非必填参数 playbackCoreType; 默认:PlaybackCoreTypeDefualt
*/
- (id)initWithParameter:(PlayParameter *)parameter;
初始化SDK(新)(仅 4.x.x 版本可用)
方法 | 注释 |
---|---|
(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 类型),所在 视图区域,视图大小 可根据业务自行调整设置示例代码 |
_requestDataPlayBack = [[RequestDataPlayBack alloc] initSDKWithParameter:parameter succed:^(BOOL succed) {
} player:^(UIView * _Nonnull playerView) {
--> ** playerView ** 即为视频流视图
} failed:^(NSError *error, NSString *reason) {
}];
代理方法
/**
* @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;
设置播放器核心(属性)
参数 | 类型 | 说明 | 所在类 |
---|---|---|---|
playbackCoreType | Enum | 在线回放播放核心(默认:PlaybackCoreTypeDefualt) | CCSDK/PlayParameter.h |
示例代码
/// 在线回放播放器核心
typedef NS_ENUM(NSUInteger, PlaybackCoreType) {
///使用HDSMedia播放器(默认)
PlaybackCoreTypeDefualt,
///使用系统AVPlayer播放器
PlaybackCoreTypeOrigin,
};
/// 在线回放播放核心(默认:PlaybackCoreTypeDefualt)
@property (nonatomic, assign) PlaybackCoreType playbackCoreType;
开始配置
//第一步:实例化参数类
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 DEPRECATED_MSG_ATTRIBUTE("该方法已废弃");
/**
* @brief 文档加载状态
* index
* 0 文档组件加载成功
* 1 动态文档翻页成功
* 2 非动画文档(白板 图片)文档翻页完成
* 3 文档组件加载失败
* 4 静态文档翻页失败
* 5 动态文档翻页失败
* 6 画板翻页失败
* 7 极速动画翻页加载成功
* 8 极速动画翻页加载失败
* 9 文档组件重载失败
* 10 静态文档翻页超时
* 11 动态文档动画执行成功
* 12 动态文档动画执行超时
* 13 动态文档加载成功
* 14 动态文档加载失败
*/
- (void)docLoadCompleteWithIndex:(NSInteger)index;
/**
* @brief 回放打点数据
* @param dotList 打点信息
* @[HDReplayDotModel,HDReplayDotModel]
*/
- (void)HDReplayDotList:(NSArray *)dotList;
/// 翻页数据获取失败,请使用 "-(void)reloadPageData;" 重新获取
- (void)onPageDataError;
文档状态说明及操作
-(void)docLoadCompleteWithIndex:(NSInteger)index;
参数 | 说明 | 操作 |
---|---|---|
0 | 文档组件加载成功 | 无 |
1 | 动态文档翻页成功 | 无 |
2 | 非动画文档(白板 图片)文档翻页完成 | 无 |
3 | 文档组件加载失败(SDK内部已做重试逻辑,但仍失败需要退出重新进入房间) | 退出重进 |
4 | 静态文档翻页失败(展示文档刷新按钮,用户可手动出发文档重载) | 重载翻页 |
5 | 动态文档翻页失败(展示文档刷新按钮,用户可手动出发文档重载) | 重载翻页 |
6 | 画板翻页失败(展示文档刷新按钮,用户可手动出发文档重载) | 重载翻页 |
7 | 极速动画翻页加载成功 | 无 |
8 | 极速动画翻页加载失败(展示文档刷新按钮,用户可手动出发文档重载) | 重载翻页 |
9 | 文档组件重载失败(展示文档刷新按钮,用户可手动出发文档重载) | 重载翻页 |
10 | 静态文档翻页超时(展示文档刷新按钮,用户可手动出发文档重载) | 重载翻页 |
11 | 动态文档动画执行成功 | 无 |
12 | 动态文档动画执行超时(展示文档刷新按钮,用户可手动出发文档重载) | 重载翻页 |
13 | 动态文档加载成功 | 无 |
14 | 动态文档加载失败(展示文档刷新按钮,用户可手动出发文档重载) | 重载翻页 |
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;
/// 重载翻页数据
- (void)reloadPageData;
/// 重载翻页
- (void)reloadPageChange;
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:显示) |
回调单个聊天文件数据 (会多次回调)(代理方法)
方法 | 说明 | 所在类 |
---|---|---|
(void)didReceiveChatMessage: | 回调单个聊天文件数据 (会多次回调) | CCSDK/RequestDataPlayBack.h |
示例代码
/// 回调单个聊天文件数据 (会多次回调)
/// @param chats 聊天数组
- (void)didReceiveChatMessage:(NSArray *)chats;
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" |
extra | Dictionary | (新增字段) 文件 |
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 |
extra | Dictionary | (新增字段) 文件 |
示例代码
/**
* @brief 收到本房间的历史提问&回答
*/
- (void)onParserQuestionArr:(NSArray *)questionArr onParserAnswerArr:(NSArray *)answerArr {
questionArr = [{
"content" = "";
"encryptId" = "";
"groupId" = "";
"id" = "";
"isPublish" = (0);
"questionUserAvatar" = "";
"questionUserId" = "";
"questionUserName" = "";
"time" = (0);
"triggerTime" = "";
新增字段 --> "extra" = {"img":[{
"order":0,
"url":""
}]
};
}]
answerArr = [{
"content" = "";
"encryptId"= "";
"groupId" = "";
"id" = "";
"isPrivate" = (0);
"answerUserAvatar" = "";
"answerUserId" = "";
"answerUserName" = "";
"time" = (0);
"triggerTime" = "";
"answerUserRole" = "";
新增字段 --> "extra" = {"img":[{
"order":0,
"url":""
}]
};
}]
}
获取全量问答数据(主动)(改动)
方法 | 说明 |
---|---|
(void)fetchAllQA: | 获取全量问答数据 |
示例代码
/**
* 3.16.0 new
* @brief 获取全量问答数据
* @param completion 数据回调
*/
- (void)fetchAllQA:(void (^)(NSArray * results))completion {
results = [{
"content" = "";
"encryptId" = "";
"groupId" = "";
"id" = "";
"isPublish" = (0);
"userAvatar" = "";
"userId" = "";
"userName" = "";
"time" = (0);
"triggerTime" = "";
新增字段 --> "extra" = {"img":[{
"order":0,
"url":""
}]
};
"answers" = [{
"content" = "";
"encryptId"= "";
"groupId" = "";
"id" = "";
"isPrivate" = (0);
"userAvatar" = "";
"userId" = "";
"userName" = "";
"time" = (0);
"triggerTime" = "";
"userRole" = "";
新增字段 --> "extra" = {"img":[{
"order":0,
"url":""
}]
};
}]
}]
}
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
3.12 在线回放试看
方法 | 注释 |
---|---|
(void)onTrialDuration: | 试看时长 |
示例代码
/// 试看时长
/// @param trialDuration 时长 trialDuration >= 1 代表有 试看时长 < 1 表示没有试看时长
- (void)onTrialDuration:(NSTimeInterval)trialDuration;
3.13 获取文档截图
方法 | 说明 | 支持版本 |
---|---|---|
(UIImage *)getDocThumber | 获取文档截图 | v3.22.0 |
示例代码
/// 3.22.0 new
/// 获取文档截图
- (UIImage *)getDocThumber;
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 |