1.x.x 迁移指南

概述

本项目是点播 SDK 2.x.x 的示例 Demo,其 1.x.x 项目为 polyv-ios-client-demo,由于 2.x.x 并不是在 1.x.x 的继承上开发的,因此没有放在同一个项目中,也因为这样,2.x.x 接口也会与 1.x.x 不一样。

本文档通过常用的使用方式介绍如何快速从点播 1.x.x SDK 迁移到 2.x.x 中。

配置播放器

类名变化:

1.x.x2.x.x

SkinVideoViewController

PLVVodSkinPlayerController

其详细配置可参考 PLVSimpleDetailControllerPLVCourseDetailControllerPLVVodVidTestController 中的配置。

部署

1.x.x 部署:

// 初始化
_videoPlayer = [[SkinVideoViewController alloc] initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, width, width*(9.0/16.0))];
[_videoPlayer configObserver];

// 添加到视图
[self.view addSubview:self.videoPlayer.view];
[self.videoPlayer setParentViewController:self];

// 需要保留导航栏
[self.videoPlayer keepNavigationBar:YES];
[self.videoPlayer setNavigationController:self.navigationController];

2.x.x 不再使用 frame 布局,而是采用 Auto Layout 的方式布局。2.x.x 为方便开发者使用 Auto Layout,免去了自动布局的代码,取而代之的是需要事先布局一个在竖屏状态或半屏状态时的占位视图:

2.x.x 播放器部署代码如下:

PLVVodSkinPlayerController *player = [[PLVVodSkinPlayerController alloc] initWithNibName:nil bundle:nil];
[player addPlayerOnPlaceholderView:self.playerPlaceholder rootViewController:self];
self.player = player;

2.x.x 播放器部署不需要主动调用配置方法实现配置,其 SDK 内部会在恰当的时刻完成配置。

若需要实现像 Demo 那样由播放器控制状态栏(statu bar)样式,还需实现两个 UIViewController 方法。

- (BOOL)prefersStatusBarHidden {
	return self.player.prefersStatusBarHidden;
}
- (UIStatusBarStyle)preferredStatusBarStyle {
	return self.player.preferredStatusBarStyle;
}

由于 PLVVodPlayerViewController 基类播放器基类是 UIViewController 的子类,因此你甚至可以像使用普通 UIViewController 对象一样操作播放器。

设置播放视频

1.x.x 设置播放视频:

[self.videoPlayer setVid:self.video.vid];

2.x.x 设置播放视频:

_weak typeof(self) weakSelf = self;
[PLVVodVideo requestVideoWithVid:vid completion:^(PLVVodVideo *video, NSError *error) {
	if (!video.available) return;
	weakSelf.player.video = video;
}];

2.x.x 播放给定 vid 的视频是通过获取一个 PLVVodVideo 对象,并传递给播发器实现播放视频的。虽说操作比以前复杂了,但这大大提高了数据的统一性,其体现在 SDK 的下载视频接口也是通过传递 PLVVodVideo 对象来添加下载。另一方面,也提高了视频数据的可复用性,用户根据获取的 PLVVodVideo 对象,通过访问其属性,可获得该视频的所有可用信息。

播放器功能配置与状态回调

2.x.x 播放器功能配置及其状态获取与回调可参考 播放器配置

配置下载器

类名变化:

1.x.x2.x.x

PvUrlSessionDownload

PLVVodDownloadManager PLVVodDownloadInfo

创建下载器

1.x.x 下载器创建:

PvUrlSessionDownload *downloader = [[PvUrlSessionDownload alloc] initWithVid:video.vid level:video.level];
//设置下载代理为自身,需要实现四个代理方法download delegate
[downloader setDownloadDelegate:self];
[downloader start];

2.x.x 不需要开发者主动创建并管理下载器,取而代之的是使用 PLVVodDownloadManager 统一管理一个下载队列,开发者只需要操作队列的开始和停止即可。因而,添加下载器的操作也变成了加入队列下载:

PLVVodDownloadManager *downloadManager = [PLVVodDownloadManager sharedManager];
PLVVodDownloadInfo *info = [downloadManager downloadVideo:self.video];
[downloadManager startDownload];

状态监听

1.x.x 状态监听:

// 下载失败回调
- (void)dataDownloadFailed:(PvUrlSessionDownload *)downloader withVid:(NSString *)vid reason:(NSString *)reason {
	[[FMDBHelper sharedInstance] updateDownloadStatic:vid status:-1];
	NSLog(@"dataDownloadFailed %@ - %@", vid, reason);
}

// 实时获取下载进度百分比回调
- (void)dataDownloadAtPercent:(PvUrlSessionDownload *)downloader withVid:(NSString *)vid percent:(NSNumber *)aPercent {
	// !!!: 频繁写入数据库会造成UI卡顿风险,因此此处是隔3秒更新一次数据库
	NSTimeInterval timeDiff = [[NSDate date] timeIntervalSinceDate:self.lastTime];
	if (timeDiff > 3) {
		[[FMDBHelper sharedInstance] updateDownloadPercent:vid percent:aPercent];
		self.lastTime = [NSDate date];
	}
	
	Video *video = self.videoDic[vid];
	video.percent = aPercent.floatValue;
	[self updateCellWithVid:vid];
}

// 实时下载速率回调
- (void)dataDownloadAtRate:(PvUrlSessionDownload *)downloader withVid:(NSString *)vid rate:(NSNumber *)aRate {
	Video *video = self.videoDic[vid];
	video.rate = aRate.floatValue;
	[self updateCellWithVid:vid];
}

// 下载状态回调
- (void)downloader:(PvUrlSessionDownload *)downloader withVid:(NSString *)vid didChangeDownloadState:(PLVDownloadState)state {
    switch (state) {
        case PLVDownloadStatePreparing:{
            
        }break;
        case PLVDownloadStateReady:{
            NSLog(@"%@ 任务创建", vid);
        }break;
        case PLVDownloadStateRunning:{
            NSLog(@"%@ 任务开始", vid);
        }break;
        case PLVDownloadStateStopping:{
            NSLog(@"%@ 正在停止", vid);
        }break;
        case PLVDownloadStateStopped:{
            NSLog(@"%@ 任务停止", vid);
        }break;
        case PLVDownloadStateSuccess:{
            NSLog(@"%@ 任务完成", vid);
            
            [[FMDBHelper sharedInstance] updateDownloadPercent:vid percent:[NSNumber numberWithInt:100]];
            [[FMDBHelper sharedInstance] updateDownloadStatic:vid status:1];
        }break;
        case PLVDownloadStateFailed:{
            
        }break;
        default:{}break;
    }
}

1.x.x 使用 PvUrlSessionDownload 下载器对象的代理方法实现状态回调与监听,开发者需要管理维护每个下载器对象,且也无法主动获取其下载状态。

2.x.x 则使用了通过 PLVVodDownloadInfo 下载信息对象把下载信息回调出来,该对象可在添加下载时候从其返回值获取。

/**
 添加至下载队列
 
 添加下载器,仅当 video 错误时,才会报错,quality 错误时,只会警告,并切换到最近的质量进行下载。

 @param video PLVVodVideo 视频对象
 @param quality 视频画质
 @return 下载信息
 */
- (PLVVodDownloadInfo *)downloadVideo:(PLVVodVideo *)video quality:(PLVVodQuality)quality;
/**
 使用后台设置的默认画质添加至下载队列

 @param video PLVVodVideo 视频对象
 @return 下载信息
 */
- (PLVVodDownloadInfo *)downloadVideo:(PLVVodVideo *)video;

开发者可通过 PLVVodDownloadInfo 对象属性获取其状态,并通过实现其对应的 Block 实现回调处理:

/// 下载状态
@property (nonatomic, assign, readonly) PLVVodDownloadState state;
@property (nonatomic, copy) void (^stateDidChangeBlock)(PLVVodDownloadInfo *info);

/// 下载速率(单位:byte/s)
@property (nonatomic, assign, readonly) double bytesPerSeconds;
@property (nonatomic, copy) void (^bytesPerSecondsDidChangeBlock)(PLVVodDownloadInfo *info);

/// 下载进度(0-1)
@property (nonatomic, assign, readonly) double progress;
@property (nonatomic, copy) void (^progressDidChangeBlock)(PLVVodDownloadInfo *info);

例如获取下载进度:

// 获取 `PLVVodDownloadInfo` 对象
PLVVodDownloadInfo *info;
info.progressDidChangeBlock = ^(PLVVodDownloadInfo *info) {
	NSLog(@"downlaod %@ progress: %@", info.vid, [NSNumberFormatter localizedStringFromNumber:@(info.progress) numberStyle:NSNumberFormatterPercentStyle]);
};

错误处理

1.x.x 的下载错误信息通过 PvUrlSessionDownload 的代理方法 ataDownloadFailed:withVid:reason: 回调,错误信息只包含一个字符串,比较困难定位错误的原因。

2.x.x 的下载中产生的错误信息统一通过 PLVVodDownloadManager 的回调属性把错误信息呈现给用户:

/// 下载错误回调
@property (nonatomic, copy) void (^downloadErrorHandler)(PLVVodVideo *video, NSError *error);

2.x.x 使用标准的 NSError 对象把错误的详细信息进行封装,开发者通过 NSError 对象可更轻松地理解、定位与解决错误。

Last updated