[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 日志存储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.0解压方法
/**
* @brief 解压并解密(加密和非加密均能解压)
* @param dst 需要进行解压解密的文件.
* @param dir 解压后输出目录, =NULL则解压到当前目录.
* @return 0-成功
* errcode:
-1 -打开输入文件(dst)失败;
-2 -本地生成(dst)内部目录或文件失败,fopen或mkdir失败,检测是否有权限或者目录名是否正确;
-3 -获取压缩文件中具体文件信息(dst->file)失败;
-4 -获取全局信息(dst)失败;
-5 -打开或读取压缩文件的内部文件失败;
-6 -dst存在但并不是加密文件格式;
*/
- (int)DecompressZipWithDec:(NSString *)dst dir:(NSString *)dir;
3.1 配置参数
3.1.1 调用方法
初始化SDK(旧)( 仅 3.x.x 版本可用 )
方法 | 注释 |
---|---|
(id)initWithParameter:(PlayParameter *) | 初始化 |
示例代码
/**
* @brief 初始化
* @param parameter 配置参数信息
* 必填参数 docFrame;
* 必填参数 docParent;
* 必填参数 playerParent;
* 必填参数 playerFrame;
* 必填参数 scalingMode;
* 必填参数 destination;
* 必填参数 defaultColor;
* 必填参数 PPTScalingMode;
* 必填参数 pauseInBackGround;
*/
- (id)initWithParameter:(PlayParameter *)parameter;
初始化SDK(新)(仅 4.x.x 版本可用)
方法 | 注释 |
---|---|
(id)initSDKWithParameter: succed: player: failed: | 初始化SDK |
示例代码
/// 初始化
/// @param parameter 配置参数信息
/// 必填参数 docFrame;
/// 必填参数 docParent;
/// 必填参数 scalingMode;
/// 必填参数 destination;
/// 必填参数 defaultColor;
/// 必填参数 PPTScalingMode;
/// 必填参数 pauseInBackGround;
- (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 类型),所在 视图区域,视图大小 可根据业务自行调整设置 |
示例代码
_offlinePlayBack = [[OfflinePlayBack alloc] initSDKWithParameter:parameter succed:^(BOOL succed) {
} player:^(UIView * _Nonnull playerView) {
--> ** playerView ** 即为视频流视图
} failed:^(NSError *error, NSString *reason) {
}];
代理方法
/**
* @brief 加载视频失败
*/
- (void)offline_loadVideoFail;
3.1.2 集成
导入头文件
#import "CCSDK/OfflinePlayBack.h"//SDK
声明变量
@property (nonatomic,strong)OfflinePlayBack * offlinePlayBack;//sdk
配置参数:PlayParameter的属性如下
/**
* @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 下载文件解压到的目录路径(离线下载相关)
*/
@property(nonatomic, copy)NSString *destination;//下载文件解压到的目录路径(离线下载相关)
开始配置
第一步:实例化参数类
PlayParameter *parameter = [[PlayParameter alloc] init];
//配置PlayParameter里面的属性,如userId,roomId等!
第二步实例化RequestData类
_offlinePlayBack = [[OfflinePlayBack alloc] initSDKWithParameter:parameter succed:^(BOOL succed) {
} player:^(UIView * _Nonnull playerView) {
--> ** playerView ** 即为视频流视图
} failed:^(NSError *error, NSString *reason) {
}];
_offlinePlayBack.delegate = self;
第三步添加代理
_offlinePlayBack.delegate = self;
第四步开始播放
[_offlinePlayBack startPlayAndDecompress];
添加代理
@interface 您的控制器 ()<OfflinePlayBackDelegate>
实现代理
/**
* @brief 加载视频失败
*/
- (void)offline_loadVideoFail;
代理方法 (可选)
/**
* @brief 播放器时间
* @param currentTime 当前时间
* @param totalTime 总时间
*/
- (void)HDPlayerCurrentTime:(NSTimeInterval)currentTime totalTime:(NSTimeInterval)totalTime;
3.2 观看离线回放
3.2.1 代理方法(可选)
/**
* @brief 加载视频失败
*/
- (void)offline_loadVideoFail;
/**
* @brief 回放的开始时间和结束时间
* @param dic {endTime //结束时间
startTime //开始时间 }
*/
-(void)liveInfo:(NSDictionary *)dic;
/**
* @brief 媒体准备完成
*/
- (void)mediaPrepared;
3.2.2 主动方法(可选)
/**
* @brief 开始解析数据并播放视频
*/
-(void)startPlayAndDecompress;
/**
* @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;
3.3 文档功能
3.3.1 代理方法(可选)
/**
* @brief 获取文档内白板或者文档本身的宽高,来进行屏幕适配用的
*/
- (void)offline_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 文档加载状态(The new method)
* index
* 2 非动画文档加载完成
*/
- (void)docLoadCompleteWithIndex:(NSInteger)index;
/**
* @brief 所有数据准备完成
*
* 数据准备完成后,才能主动获取全量数据
* 获取全量聊天数据:- (void)fetchAllChat:(void (^)(NSArray * results))completion;
* 获取全量问答数据:- (void)fetchAllQA:(void (^)(NSDictionary * results))completion;
* 获取全量广播数据:- (void)fetchAllBroadcast:(void (^)(NSArray * results))completion;
* 获取全量随堂测数据:- (void)fetchAllPractic:(void (^)(NSArray * results))completion;
* 获取全量翻页数据:- (void)fetchAllPageChange:(void (^)(NSArray *results))completion;
*/
- (void)dataPrepared;
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;
/**
* @brief 获取全量翻页数据
* @param completion 数据回调
*/
- (void)fetchAllPageChange:(void (^)(NSArray *results))completion;
3.4 房间信息
代理方法(可选)
/**
* @brief 获取房间信息,主要是要获取直播间模版来类型,根据直播间模版类型来确定界面布局
* 房间简介:dic[@"desc"];
* 房间名称:dic[@"name"];
* 房间模版类型:[dic[@"templateType"] integerValue];
* 模版类型为1: 聊天互动: 无 直播文档: 无 直播问答: 无
* 模版类型为2: 聊天互动: 有 直播文档: 无 直播问答: 有
* 模版类型为3: 聊天互动: 有 直播文档: 无 直播问答: 无
* 模版类型为4: 聊天互动: 有 直播文档: 有 直播问答: 无
* 模版类型为5: 聊天互动: 有 直播文档: 有 直播问答: 有
* 模版类型为6: 聊天互动: 无 直播文档: 无 直播问答: 有
*/
-(void)offline_roomInfo:(NSDictionary *)dic;
房间配置信息(代理方法)
/// 房间配置信息
/// @param dic 配置信息
- (void)offline_roomConfiguration:(NSDictionary *)dic;
3.5 聊天功能
代理方法(可选)
/**
* @brief 解析本房间的历史聊天数据
* @param chatArr [{ chatId //聊天ID
content //聊天内容
groupId //聊天组ID
time //时间
userId //用户ID
userName //用户名
userRole //用户角色}]
*/
-(void)offline_onParserChat:(NSArray *)arr;
获取全量聊天数据(主动方法)
/**
* @brief 获取全量聊天数据
* @param completion 数据回调
*/
- (void)fetchAllChat:(void (^)(NSArray * results))completion;
3.6 问答功能
代理方法(可选)
/**
* @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)offline_onParserQuestionArr:(NSArray *)questionArr onParserAnswerArr:(NSArray *)answerArr;
获取全量问答数据(主动方法)
/**
* @brief 获取全量问答数据
* @param completion 数据回调
*/
- (void)fetchAllQA:(void (^)(NSArray * results))completion;
3.7 广播功能
代理方法(可选)
/**
* @brief 收到本房间历史广播(The new method)
* content 广播内容
* time 发布时间(单位:秒)
*/
- (void)broadcastHistory_msg:(NSArray *)array;
获取全量广播数据(主动方法)
/**
* @brief 获取全量广播数据
* @param completion 数据回调
*/
- (void)fetchAllBroadcast:(void (^)(NSArray * results))completion;
3.8 视频播放状态
播放器状态类型
/**
* 视频播放状态
* 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;
3.9 防录屏
PS:防录屏功能拆分到demo层处理,具体实现参考 4.0.0 demo
3.10 校验文件MD5
/// 校验文件MD5值
/// @param filePath 文件路径
/// @param MD5 源文件MD5值
/// @return YES 文件正常 / NO 文件已损坏
- (BOOL)HDSCheckFileMD5:(NSString *)filePath MD5:(NSString *)MD5;
3.11 获取全量随堂测数据
主动方法
/**
* @brief 获取全量随堂测数据
* @param completion 数据回调
*/
- (void)fetchAllPractic:(void (^)(NSArray * results))completion;
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 = offlinePlayBack 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文件里面就是相关的打印日志
第四步:这里可以看到相关的请求信息和打印日志, 也可以判断错误原因