产品文档 点播技术文档 iOS 点播 Core SDK

iOS 点播Core SDK(不含UI)

SDK 地址

最新版 change log

适用于iOS8.0+。

功能简介

iOS 点播核心 SDK 提供对点播播放器的播放管理操作(不含UI),功能包括:

  • 视频播放功能:提供视频ID、请求url的token等参数开始播放,也支持视频加密播放
  • 播放控制方法:播放、暂停、停止、跳转至指定时间、变换视频清晰度和倍速播放
  • 视频播放代理:提供响应播放事件的代理方法,用于捕获和处理播放中的错误
  • 获取视频信息:当前播放状态、视频时长、视频缓存时长
  • 视频下载功能:需要视频ID、请求url的token等参数

SDK 集成

  • Podfile 中设置 source
source 'https://github.com/CocoaPods/Specs.git'
source 'http://git.baijiashilian.com/open-ios/specs.git'
  • Podfile 中引入 BJPlayerManagerCore
  pod 'BJPlayerManagerCore'
  • 配置ATS. 需要在info.plist里面增加 NSAllowsArbitraryLoads = true

1. 引入头文件

#import <BJPlayerManagerCore/BJPlayerManagerCore.h>

2. 全局设置

  • 使用下载功能和播放下载的时候, 需要在使用前设置下载的rootPath, 或者可以在下面的方法中设置下载的rootpath
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

SDK 使用

1. 播放管理类初始化

播放器管理建议使用BJPlayerManager,不建议使用BJPlayerManager中的player

  • 1.3.x 版本
    BJPlayerManager *playManger = [[BJPlayerManager alloc] init]; 
    playManager.delegate = self; // 设置代理
  • 1.4.x 版本开始提供视频加密播放
    BJPlayerManagerType playType = BJPlayerManagerType_AVPlayer;
    BJPlayerManager *playManger = [[BJPlayerManager managerWithType: playType];
    playManager.delegate = self; // 设置代理
  • 设置第三方用户名
 [self.playerManager setUserName:userName userNumber:userNumber];

2. 视频播放

1.设置视频播放源

  • 获取视频信息, 设置视频播放源都会清空 BJPlayerManager 的视频信息.
//在线点播播放
    [self.playerManager setVideoID:vid token:token completion:^BOOL(PMVideoInfoModel * _Nonnull result, NSError * _Nonnull error) {
        return shouldAutoPlay; // block的返回值设置是否自动播放
    }];

 //本地视频播放
    [self.playerManager setVideoPath:path definition:definitionType completion:^BOOL(PMVideoInfoModel * _Nonnull result, NSError * _Nonnull error) {
        return shouldAutoPlay; // block的返回值设置是否自动播放
    }];

2.获取视频播放View, 设置frame

    playerManager.player.view.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_WIDTH*9/16);
    [self.view addSubview:playerManager.player.view];//添加到目标视图

3.视频播放流程控制 BJPMControlProtocol

    [playerManager play];           // 播放 
    [playerManager plause];         // 暂停  
    [playerManager stop];           // 停止播放 
    [playerManager seek:time];      // 进度跳转 

  /* 播放倍率 支持 [0.5, 2.0] 范围内的倍速设置, 该范围之外的倍速将不做任何响应 */
    [playerManager changeRate:rate]; // 切换倍速 
    [playerManager changeDefinition:(PMVideoDefinitionType)ddefineType]; // 切换淸晰度

4.视频播放代理方法 BJPMProtocol

@required
// 播放过程中出错(具体错误码参考下节)
- (void)videoplayer:(BJPlayerManager *)playerManager throwPlayError:(NSError *)error;

@optional

// 视频播放完成的回调方法
- (void)videoDidFinishPlayInVideoPlayer:(BJPlayerManager *)playerManager;

// 播放器暂停的回调方法
- (void)videoPlayPauseInVideoPlayer:(BJPlayerManager *)playerManager;

5.视频信息获取


[self.playerManager getVideoInfoWithVid:vid token:token completion:(void(^)(PMVideoInfoModel * _Nullable videoInfo, NSError * _Nullable error))completion { // PMVideoInfoModel 为视频信息 }];

6.播放中的视频属性提供

  • 具体使用方法可以参考UI SDK的使用
// 存放用户自定义消息
@property (nonatomic, strong, nullable) NSString *userInfo;

// 是否开启记忆播放
@property (nonatomic, assign) BOOL playTimeRecordEnabled;

// 设置初始化播放时间, 如果设置了开启记忆播放, 再设置这个值无效
@property (nonatomic, assign) NSTimeInterval initialPlaybackTime;

// 当前播放状态
@property (nonatomic, readonly) PMPlayState playState;

// 视频的时长
@property (nonatomic, readonly) NSTimeInterval duration;

// 视频缓存时长
@property (nonatomic, readonly) NSTimeInterval cacheDuration;

// 当前播放倍速
@property (nonatomic, readonly) CGFloat playRate;

// 正片的当前的播放时间
@property (nonatomic, readonly) NSTimeInterval currentTime;

// 播放器实例, 建议只读取属性, 不改变属性以及调用方法 
@property (readonly, nullable) PKMoviePlayerController *player;

// 播放信息
@property (nonatomic, readonly, nullable) PMVideoInfoModel *videoInfoModel;

// 当前播放清晰度
@property (nonatomic, readonly, nullable) PMVideoDefinitionInfoModel *currDefinitionInfoModel;

// 当前播放的CDN
@property (nonatomic, readonly, nullable) PMVideoCDNInfoModel *currCDNInfoModel;

7.播放通知

PMPlayStateChangeNotification;            // 播放状态改变通知
PMPlayerCreateNotification;                   // 播放器实例被创建,即将播放视频
PMPlayerWillPlayNotification;             // 获取到播放信息后的通知
PMPlayerFileInvalidNotification;              // 本地播放地址无效的通知
PMPlayerFileNotExistNotification;             // 本地播放文件不存在的播通知
PMPlayerWillSeekNotification;             // 即将跳转到某一时刻
PMPlayerWillChangeDefinitionNotification; // 即将切换清晰度
PMPlayerGetPlayInfoFailedNotification;    // 获取播放信息失败

3. 错误码(状态码)

    BJPMErrorCodeLoading           = 1000,    // 视频加载中
    BJPMErrorCodeLoadingEnd        = 1001,    // 视频加载完成
    BJPMErrorCodeParse             = 1002,    // 视频播放错误
    BJPMErrorCodeNetwork           = 1003,    // 网络错误, 没有网络或是未知网络
    BJPMErrorCodeWWAN              = 1004,    // 非WIFI环境
    BJPMErrorCodeWIFI              = 1005,    // wifi
    BJPMErrorCodeServer            = 1006,    // 请求服务端返回错误
    BJPMErrorCodeApp               = 1007,    // app端调用错误
    BJPMErrorCodeDownloadInvalid   = 1010,    // 视频的url失效
    BJPMErrorCodeMissFile          = 1011,    // 下载的文件丢失

4. 记忆播放

  • 设置 BJPlayerManager 的 playTimeRecordEnabled 属性开关记忆播放。开启后记录 vid 对应的播放进度,每 5 秒【更新】一次播放进度,seek 时、停止播放时立即【更新】一次;
  • 如果 视频总时长 减去 当前进度 小于 N 秒,则视为播放结束,只移除记录、不添加,N 默认 5 秒,可自定义,参考 BJPlayerManager 的 ignorableRemainingTimeInterval 属性;
  • 调用 clearPlayTimeRecords 方法清除播放纪录;
  • 最多存 100 条,超过 100 条时顶掉最早的;
  • 打开了记忆播放,再设置视频初始播放时间无效。

5. 视频下载 PMDownloadManager

1.初始设置

  • 注意:下载前需要先设置根路径, 然后调用单例方法, 否则代码抛出异常
  • 文件保存目录参考iOS官方文件存储文档.
  /* 下载根路径, folder需要是一个 存在的 文件夹, 如果不存在, 需要上层创建 */
  NSString *path = @"xxx/folder";
    [PMDownloadManager downloadManagerWithRootPath:path];

2.下载方法

参考头文件:PMDownloadManager.h

//点播下载
    [[PMDownloadManager downloadManager] addDownloadWithVid:vid token:token definionArray:definitionArray showFileName:showFileName];

//回放下载
    [[PMDownloadManager downloadManager] addDownloadWithClass:classID seesionID:sessionID token:token definionArray:defiArr showFileName:showname creatTime:@"creatTime"];

需要注意的是,由于我们使用了ID+token的视频下载方式, 因此是存在token过期的现象, 发生token失效或者下载url失效的问题时, 会向上层抛出BJPMErrorCodeDownloadInvalid (1010)的错误码,此时需要上层重新获取token,并调用下面的方法来重新设置token

/**
  下载中的任务发生了下载的url失效的错误,需要调用此方法,内部重新请求下载地址

 @param downloader 下载的任务
 @param token 新的token
 */
- (void)resetDownloadWithDownloader:(PMDownloader *)downloader token:(NSString *)token;

3.主要属性

/** 下载事件相关的代理 */
@property (nonatomic, weak  ) id<PMDownloadDelegate> downloadDelegate;

//下载过程中的数据 和 已经完成的数据
@property (nonatomic, readonly) NSArray <PMDownloader *> *downloadingList;
@property (nonatomic, readonly) NSArray <PMDownloadModel *> *finishedList;

4.下载代理方法

  • 下载代理请使用 PMDownloadManager 的代理方法, 不能直接使用单个下载 PMDownloader 的代理方法.
代理方法:
- (void)startDownload:(PMDownloader *)downloader;//开始下载
- (void)updateProgress:(PMDownloader *)downloader;//获取下载进度
- (void)finishedDownload:(PMDownloader *)downloader;//下载完成

/**
 下载时的错误回调, 包括开始下载之前和下载过程中的错误

 @param downloader 下载过程中的下载器实例, 可能为空
 @param beforeDownloadModel 下载开始前的错误model, 可能为空
 */
- (void)downloadFail:(nullable PMDownloader *)downloader beforeDownloadError:(nullable PMBeforeDownloadModel *)beforeDownloadModel;

5.分账户下载

  • 设置rootpath时, 需要传入绝对路径, 文件保存目录参考iOS官方文件存储文档.
  • 由于rootpath为绝对路径, 所以就需要在APP每次使用前设置, 在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 里面更新路径.
  • 分账户下载的rootpath是需要跟账户的唯一id(或者其他ID)相关联. 每次登陆一个新账户也需要清除上个账户的信息, 或者在退出账户时清理.

    [PMDownloadManager downloadManagerDestory];
    
  • 登录新账户时,也需要重新设置新账户的rootpath.

6.下载中的错误回调方法处理

1. 错误回调:
-(void)downloadFail:(nullable PMDownloader *)downloader beforeDownloadError:(nullable PMBeforeDownloadModel *)beforeDownloadModel;

2. 触发该回调的case:
- 下载需要2个步骤: 
  1.由vid/(或者classid/sessionid)和token去服务端获取下载地址
  2.开始下载

- 有2种情况的error, 
    a. beforeDownloadModel是开始下载之前的信息, 具体打印beforeDownloadModel.error;
    b. 下载过程中的错误信息, 打印downloader.downloadModel.error

- beforeDownloadModel
    1. rootPath为空 
    2. 获取下载地址时服务端返回的错误信息
    3. 文件已经下载完成 
    4. 正在下载 
    5. resume的时候, 会先检测当前下载的url是否有效, 具体打印beforeDownloadModel.urlCheckState
    6. 检测url, 发现下载的url已经失效
- downloader.downloadModel.error
    1. 下载过程中出现的错误

6. 片头片尾以及广告播放

  • 可以在后台设置片头片尾广告以及片头片尾, 片头片尾广告是图片广告, 片头片尾可以上传视频, 目前ijk播放器不支持。
// 设置是否需要片头片尾, 默认不需要
[PMAppConfig sharedInstance].isNeedAD = isNeedAD;
// 设置是否自动播放图片广告, 默认自动播放
[PMAppConfig sharedInstance].notAutoStartImageAD = notAutoStartImageAD;
// 播放图片广告
[self.playerManager startAD];
// 暂停图片广告
[self.playerManager pauseAD];

7. 视频加密

  • 视频加密需要使用1.4.x之后的SDK版本

  • 只有ijk播放器支持播放加密视频

  • 播放, 下载加密视频

self.playerManager = [BJPlayerManager managerWithType:BJPlayerManagerType_IJKPlayer];

// 在线视频
BOOL needEncrypt = YES;
@YPWeakObj(self);
[self.playerManager setVideoID:vid token:token encrypted:needEncrypt completion:^BOOL(PMVideoInfoModel * _Nonnull result, NSError * _Nonnull error) {
        @YPStrongObj(self);
        // 视频的详细信息
        self.videoInfoModel = result;
        return shouldAutoPlay;
    }];

// 本地视频
@YPWeakObj(self);
[self.playerManager setVideoPath:path definition:definitionType completion:^BOOL(PMVideoInfoModel * _Nonnull result, NSError * _Nonnull error) {
         @YPStrongObj(self);
        // 视频的详细信息
        self.videoInfoModel = result;
        return shouldAutoPlay;
    }];

// 下载加密视频
[[PMDownloadManager downloadManager] addDownloadWithVid:vid token:token definionArray:array showFileName:showFileName need_encrypt:needEncrypt];

8. 纯音频

  • 目前纯音频需要使用1.4.5之后的SDK版本

  • 点播需要在后台配置转码纯音频才有纯音频

  • 点播在线播放的默认清晰度可以在后台配置清晰度列表, SDK根据配置的清晰度优先级列表来匹配第一个清晰度, 如果后台配置了纯音频最高优先级, 就可以进入回放和点播的时候直接播放纯音频, 否则就通过改变清晰度的方式播放纯音频。

  • 视频清晰度 PMVideoDefinitionType 增加纯音频枚举


typedef NS_ENUM(NSInteger, PMVideoDefinitionType){ DT_Audio = -2, // 音频 DT_Unknown = -1, // 未知 DT_LOW = 0, // 标清 DT_HIGH = 1, // 高清 DT_SUPPERHD = 2, // 超清 DT_720p = 3, // 720p DT_1080p = 4, // 1080p };
  • 播放纯音频
// 播放音频
[self.playerManager changeDefinition:DT_Audio];
  • 下载纯音频, 同一个视频只能下载纯音频或其他的一种清晰度, 按照传入的清晰度列表匹配第一个满足条件的清晰度
 self.preferredDefinitionList = @[@(-2),@(0),@(1),@(2),@(3),@(4)];

[[PMDownloadManager downloadManager] addDownloadWithVid:vid token:token definionArray:self.preferredDefinitionList showFileName:showFileName];

9.专属子域名

  • 1.4.5之后的版本支持设置专属子域名, 需要在创建 BJPlayerManager 实例之前设置
NSString *exclusiveDomain = @"yourExclusiveName";
[[PMAppConfig sharedInstance] setExclusiveSubdomain:exclusiveDomain];

点播Core git 地址

常见问题

1. app每次杀死重启之后,就找不到下载的finishedlist和downinglist?

  • 确认设置下载目录rootpath时,需要在 -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中设置的.

2.下载时经常提示下载失败

  • SDK提供的下载方法是需要传递视频id+token,或者回放ID+sessionID+token 的, 用户可以在百家云的后台设置token的有效期,所以是存在token失效的问题的.

  • 在downloadManager的delegate回调方法中监听到BJPMErrorCodeDownloadInvalid错误码时,代表当前url失效了,需要再次获取新的token,然后调用我们提供的resetDownload...方法重新设置token.

3. 对于下载和播放的回调方法中抛出来的error的具体信息?

  • 通过 NSString *errMsg = [error.userInfo objectForKey:NSLocalizedDescriptionKey]; 一般都可以获取到详细的错误信息,可以帮助进一步定位错误.

4. 播放在线视频/下载视频时偶现提示1006错误码,提示服务端的错误

  • 出现1006的错误码时,大部分是token失效/token校验不通过 的情况,建议播放视频下载时总是获取最新的token. 另外下载过程中也需要注意BJPMErrorCodeDownloadInvalid的错误码,及时更新token.

5. token验证失败,或者返回1010的错误码

  • 除了以上原因,传token参数的时候,请务必确认一下token里面不能包含空格,否则播放或者下载视频的时候,将有可能提示token验证失败.

6. 集成sdk后, 发现与项目中原有的ijk.framework有冲突

  • 原因: 因为两个ijk底层的ffmpeg的版本不一致导致的冲突

  • 解决办法:

    1. 第1步: 修改podfile里面的依赖
      • 如果集成的的是pod BJPlaybackUI 改为 pod BJPlaybackUI/weak
      • 同理, 如果集成的的是 pod BJPlaybackCore /pod BJPlayerManagerCore / pod BJPlayerManagerUI, 分别改为 pod BJPlaybackCore/weak /pod BJPlayerManagerCore/weak / pod BJPlayerManagerUI/weak
    2. 第2步, 修改podfile里面的依赖之后执行 pod install
    3. 第3步, 获取百家云sdk的 IJKMediaFramework.framework, 步骤:
    4. 第4步, 将IJKMediaFramework.framework手动拖入工程, 然后:
      • 进入项目的target -> General -> Linked Frameworks and Libraries, 删除 Linked Frameworks and Libraries 下的 IJKMediaFramework.framework.
      • 进入项目的target -> General -> Embedded Binaries (注意: 不是Embedded Frameworks), 添加 IJKMediaFramework.framework, 步骤:
        1. 点击 Embedded Binaries 下的 "+" 号
        2. 点击 "Add Other..."
        3. 找到本地IJKMediaFramework.framework, 添加即可