iOS 直播离线回放 SDK 开发指南

发布于 2021-02-18 21:52:54 字数 16024 浏览 1214 评论 0

1.概述

1.1 阅读对象

本文档为技术文档,需要阅读者:

  • 具备基本的iOS开发能力
  • 准备接入CC视频的直播SDK相关功能
  • 对CC云直播产品使用方法有基础的了解,使用帮助地址

1.2 功能特性

功能描述
直播视频离线观看直播回放视频
文档展示能够观看直播时文档
聊天所有直播时的聊天
简介支持对直播间的信息展示
广播支持历史全体消息
问答支持历史问答

2.开发准备

2.1 开发环境

  • 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
    

    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/
      然后就是漫长的等待,当然,网络好的情况下会更快
    
  2. 在Podfile文件中添加
    如果是有连麦的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. 在终端中执行
    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.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 调用方法

/**
 *	@brief	初始化
 *	@param 	parameter   配置参数信息
 *  必填参数 docFrame;  //文档区域
 *  必填参数 docParent;  //文档父类窗口
 *  必填参数 playerParent; //视频父类窗口
 *  必填参数 playerFrame; //视频区域
 *  必填参数 scalingMode; //屏幕适配方式
 *  必填参数 destination; //下载文件解压到的目录路径(离线下载相关)
 *  必填参数 defaultColor; //ppt默认底色,不写默认为白色
 *  必填参数 PPTScalingMode; //PPT适配方式  PPT适配模式分为四种,1.一种是全部填充屏幕,可拉伸变形,2.第二种是等比缩放,横向或竖向贴住边缘,另一方向可以留黑边,3.第三种是等比缩放,横向或竖向贴住边缘,另一方向出边界,裁剪PPT,不可以留黑边,4.根据直播间文档显示模式的返回值进行设置(推荐)(The New Method)
 *  必填参数 pauseInBackGround; //后台是否继续播放,注意:如果开启后台播放需要打开 xcode->Capabilities->Background Modes->on->Audio,AirPlay,and Picture in Picture
 */
- (id)initWithParameter:(PlayParameter *)parameter;

代理方法

/**
 *    @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 视频父类窗口
 */
@property(nonatomic,strong)UIView                       *playerParent;//视频父类窗口
/**
 *  @brief 视频区域
 */
@property(nonatomic,assign)CGRect                       playerFrame;//视频区域
/**
 *  @brief
 * 0:IJKMPMovieScalingModeNone
 * 1:IJKMPMovieScalingModeAspectFit
 * 2:IJKMPMovieScalingModeAspectFill
 * 3:IJKMPMovieScalingModeFill
 */
@property(assign, nonatomic)NSInteger                   scalingMode;//屏幕适配方式,含义见上面
/**
 *  @brief ppt默认底色,不写默认为白色
 */
@property(nonatomic,strong)UIColor                      *defaultColor;//ppt默认底色,不写默认为白色
/**
 *  @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适配模式分为四种,
 * 1.一种是全部填充屏幕,可拉伸变形,
 * 2.第二种是等比缩放,横向或竖向贴住边缘,另一方向可以留黑边,
 * 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] initWithParameter:parameter];
 _offlinePlayBack.delegate = self; 
 第三步添加代理
 _offlinePlayBack.delegate = self;
 第四步开始播放
 [_offlinePlayBack startPlayAndDecompress];

添加代理

@interface 您的控制器 ()<OfflinePlayBackDelegate>

实现代理

/**
 *    @brief   加载视频失败
 */
- (void)offline_loadVideoFail;

至此您的项目已经可以运行了,并且已经集成好了视频基本功能;如果不需要文档功能则不配置文档相关属性即可,另外添加文档功能写一个定时器在视频开始播放时调用下面的方法即可

/**
 *	@brief	time:从直播开始到现在的秒数,SDK会在画板上绘画出来相应的图形
 */
- (void)continueFromTheTime:(NSInteger)time;

3.2 观看离线回放

3.2.1 代理方法(可选)

/**
 *    @brief   加载视频失败
 */
- (void)offline_loadVideoFail;
/**
 *  @brief 回放的开始时间和结束时间
 *  @param dic {endTime     //结束时间
                startTime   //开始时间 }
 */
-(void)liveInfo:(NSDictionary *)dic;

3.2.2 主动方法(可选)

/**
 *  @brief	开始解析数据并播放视频
 */
-(void)startPlayAndDecompress;

/**
 *	@brief	销毁文档和视频,清除视频和文档的时候需要调用,推出播放页面的时候也需要调用
 */
- (void)requestCancel;
/**
 *	@brief	time:从直播开始到现在的秒数,SDK会在画板上绘画出来相应的图形
 */
- (void)continueFromTheTime:(NSInteger)time;
/**
 *	@brief  改变播放器frame
 */
- (void)changePlayerFrame:(CGRect) playerFrame;
/**
 *    @brief  改变播放器父窗口
 */
- (void)changePlayerParent:(UIView *) playerParent;
/**
 *	@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;

3.3.2 主动方法(可选)

/**
 *	@brief	time:从直播开始到现在的秒数,SDK会在画板上绘画出来相应的图形
 */
- (void)continueFromTheTime:(NSInteger)time;

/**
 *	@brief  获取文档区域内白板或者文档本身的宽高比,返回值即为宽高比,做屏幕适配用
 */
- (CGFloat)getDocAspectRatio;

/**
 *	@brief  改变文档区域大小,主要用在文档生成后改变文档窗口的frame
 */
- (void)changeDocFrame:(CGRect) docFrame;
/**
 *    @brief  改变文档父窗口
 */
- (void)changeDocParent:(UIView *) docParent;

3.4 房间信息

代理方法(可选)

/**
 *	@brief  获取房间信息,主要是要获取直播间模版来类型,根据直播间模版类型来确定界面布局
 *	房间简介:dic[@"desc"];
 *	房间名称:dic[@"name"];
 *	房间模版类型:[dic[@"templateType"] integerValue];
 *	模版类型为1: 聊天互动: 无 直播文档: 无 直播问答: 无
 *	模版类型为2: 聊天互动: 有 直播文档: 无 直播问答: 有
 *	模版类型为3: 聊天互动: 有 直播文档: 无 直播问答: 无
 *	模版类型为4: 聊天互动: 有 直播文档: 有 直播问答: 无
 *	模版类型为5: 聊天互动: 有 直播文档: 有 直播问答: 有
 *	模版类型为6: 聊天互动: 无 直播文档: 无 直播问答: 有
 */
-(void)offline_roomInfo:(NSDictionary *)dic;

3.5 聊天功能

代理方法(可选)

/**
 *    @brief    解析本房间的历史聊天数据
 *    @param    chatArr [{  chatId          //聊天ID
                            content         //聊天内容
                            groupId         //聊天组ID
                            time            //时间
                            userId          //用户ID
                            userName        //用户名
                            userRole        //用户角色}]
 */
-(void)offline_onParserChat:(NSArray *)arr;

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;

3.7 广播功能

代理方法(可选)

/**
 *  @brief  收到本房间历史广播(The new method)
 *  content 广播内容
 *  time 发布时间(单位:秒)
 */
- (void)broadcastHistory_msg:(NSArray *)array;

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文件里面就是相关的打印日志

第四步:这里可以看到相关的请求信息和打印日志, 也可以判断错误原因

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

遂心如意

文章 0 评论 0

5513090242

文章 0 评论 0

巷雨优美回忆

文章 0 评论 0

junpengz2000

文章 0 评论 0

13郎

文章 0 评论 0

qq_xU4RDg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文