4 视频播放

4.1 播放前准备

4.1.1 部署播放器

点播 SDK 中的播放器类为 PLVVodPlayerViewController,而开源组件中提供的带有默认皮肤的播放器类 PLVVodSkinPlayerControllerPLVVodPlayerViewController 的子类,这里以 SDK 中的基类为例。想要进行视频播放,首先,在页面上创建一个 PLVVodPlayerViewController 对象,以及放置播放器的 UIView 对象。代码示例如下:

#import “PLVVodPlayerViewController.h”

@interface UIViewController ()
@property (nonatomic, strong) PLVVodPlayerViewController *player;
@property (nonatomic, weak) UIView *playerPlaceholder;
@end

@implementation UIViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  PLVVodPlayerViewController *player = [[PLVVodPlayerViewController alloc] init];
  [player addPlayerOnPlaceholderView:self.playerPlaceholder rootViewController:self];
  self.player = player;
}

@end

播放器 player 可自动在 playerPlaceholder 中实现自动布局,以及半屏/全屏的切换。

4.1.2 外部传入播放凭证

自iOS点播2.17.0版本开始,支持通过外部传入播放凭证的方式进行加密视频的播放,以避免非法盗版者利用漏洞创建无身份信息的播放凭证。

  • Token是用于解密播放保利威平台加密视频的,本地传入Token将更好地提升视频安全性。

  • 客户在使用此功能的时候,务必要保证传入的Token在自家api传输中的安全性,如接口加密。

播放加密视频实践全流程可参考 播放加密视频最佳实践

首先,您需要集成iOS点播SDK在2.17.0以上版本

修改podfile文件,引入点播sdk:

其次,使用本地传入Token的API,在点播头文件PLVVodPlayerViewController.h中查看api如下:

在初始化播放器后,设置requestCustomKeyTokenBlock;后续每当SDK需要keytoken的时候,将会通过执行该block进行获取,示例如下:

4.2 视频播放

点播 SDK 将视频数据封装类 PLVVodVideo 中,通过 PLVVodVideo 对象将视频数据传递给播放器。PLVVodVideo 包含视频ID、视频标题、视频时长等数据。

注意,为播放器设置 video 属性后,会马上应用播放器的属性值,因此播放器的属性配置应在赋值 PLVVodVideo 对象之前进行。

直接设置 video 属性时,会使用后台设置的“默认清晰度”。播放视频的示例代码如下:

其中,self.player 为 4.1 代码示例提到的播放器 PLVVodPlayerViewController

4.2.1 设置清晰度

若希望设置自定义的清晰度,则需使用 -setVideo:quality: 方法。通过只读属性 quality 可获得当前视频的播放清晰度。

播放过程中也支持切换来自点播后台所提供的清晰度。切换清晰度,只需调用 -switchQuality: 方法。若需要知道视频支持哪些清晰度,可读取 PLVVodVideo 对象的 qualityCount 属性获取可用的清晰度。

4.2.2 切换线路

切换线路指切换视频所访问的 CDN 服务商,保利威为加密的点播的视频提供了多种线路切换,设置该属性即可完成线路的切换。线路来源可从 PLVVodVideo 对象的 availableRouteLines 选取。

4.2.3 设置播放速度

播放器支持倍速播放,正常播放速度为 1.0。开发者可以通过修改该值改变播放器的播放速度,也可以通过该值获取播放器当前的播放速度。

4.2.4 设置播放音量

播放器的播放音量通过属性 playbackVolume 设置。该音量区别于系统音量,值为 0~系统当前音量。开发者可以通过该值获取播放器当前的播放音量。

4.2.5 播放进度跳转

播放器通过设置 currentPlaybackTime 属性来进行 seek 操作。同样,开发者可以通过该值获取当前播放时间。

通过对 currentPlaybackTimeduration (媒体时长)进行计算,可得出当前的播放进度。

4.2.6 全屏与半屏切换

全屏分为竖向全屏和横向全屏,用户可调用播放器提供的方法 -setPlayerFullScreen: 设置播放器是否全屏。枚举值属性 fullScreenOrientation 用于设置全屏的方向,可根据视频宽高比自动选择横竖屏,也可固定一个方向,默认为根据视频宽高比自动选择横/竖屏。

以下只读属性 fullscreen 可用于获取播放器当前的全屏状态,以及对应的全屏状态变更回调。

以上方法的使用示例可参考 PLVVodPlayerSkin。建议直接使用我们提供的带播放器皮肤 PLVVodPlayerSkin 的播放器 PLVVodSkinPlayerController 去集成。

4.2.7 设置视频画面拉伸模式

视频画面拉伸模式与 UIViewcontentMode 定义类似,可参照其定义。

4.3 播放状态

4.3.1 用户播放/停留时间

只读属性 viewerWatchDuration 为 App 使用者播放当前视频的时间,该时长仅当用户播放中的时候才会统计,暂停时停留的时间并不会计算。

只读属性 viewerStayDuration 为 App 使用者打开播放器,在该视频停留的时间。

注意,切换视频时上面两个属性值都归零。

4.3.2 媒体时长与缓冲进度

通过只读属性 duration 可获取当前视频的媒体时长,只读属性 playableDuration 为已缓存(可播放)视频时长。将 playableDuration 除以 duration 可得出当前缓存进度。

4.3.3 获取当前时刻截图

播放器可通过 -snapshot 方法获得当前时刻的视频截图。方法声明如下:

4.3.4 手势类型与回调

播放器支持识别多种手势,并把识别的手势类型与响应事件回调开放出来。开发者可根据实际需求实现手势事件。具体使用方式,可参考 PLVVodSkinPlayerController。若不希望某些视图响应播放器的手势,可设置 doNotReceiveGestureViews 数组,添加忽略手势事件响应的视图。

播放器 PLVVodSkinPlayerController 实现了以上所有手势的响应事件:

  • 单击:显示播放器皮肤

  • 双击:播放或暂停

  • 左滑/右滑:拖动播放进度

  • 左侧上滑/下滑:调节亮度

  • 右侧上滑/下滑:调节音量

  • 长按/取消:快进/取消快进

如果想屏蔽长按手势,可将属性 disableLongPressGesture 设置为 YES,长按时快进的倍速可通过属性 longPressPlaybackRate 修改,默认为 2.0。

4.3.5 播放状态与回调

以下所列的只读属性可用于获取播放器当前的播放状态,包括视频是否就绪可以播放、当前播放状态、当前视频加载状态、播放是否结束。每一个属性值都有各自的变更回调,开发者可实现不同播放状态的变更回调。

播放状态、播放模式、加载状态这三个枚举值的定义如下:

4.3.6 其他回调

为了简化开发者的工作,播放器还提供了以下几个回调。

回调 loadingHandler 的回调参数 isLoading 表示播放器当时是否在载入中,开发者可直接在该回调中,进行 UI 的变更。

playerErrorHandler 回调了播放器在播放过程中所有错误,并以标准的 NSError 回调错误信息。开发者可以在该回调中做错误处理和错误信息的展示。

注意,若是按照 PLVVodPlayerSkinProtocol 实现皮肤或使用带有默认皮肤设置的播放器 PLVVodSkinPlayerController,则不需要实现这两个回调,其实现已在播放器内部实现。

4.4 自定义皮肤

PLVVodPlayerViewController 是播放器基类,不带任何播放控件,用户需要带皮肤控件的播放器,可直接使用 PLVVodSkinPlayerController。若需要自定义皮肤,可实现 PLVVodPlayerSkinProtocol 协议,创建皮肤,并设置到 PLVVodPlayerViewControllerplayerControl 属性。自定义皮肤的具体设置可参考 demo 中的 PLVVodPlayerSkin 类。

4.4.1 对播放器的弱引用

播放器皮肤对播放器有弱引用,皮肤可通过该弱引用获取播放器的属性,以及方法调用。譬如获取播放器的播放模式、当前播放时长、获取播放器当前播放截图等。

4.4.2 根据播放属性设置皮肤

PLVVodPlayerSkinProtocol 协议还规定了播放器皮肤必须包含以下属性,播放器皮肤可根据这些属性、属性改变回调来设置皮肤、改变皮肤样式。

4.4.3 自定义导航栏/状态栏

实现属性 shouldHideNavigationBar,播放器会根据其值隐藏或显示播放器所在控制器的导航栏。实现属性 shouldHideStatusBar,播放器所在页面可根据该值实现 -prefersStatusBarHidden-preferredStatusBarStyle 方法,达到设置播放器状态栏的目的。

4.4.4 设置播放器控件

播放器皮肤还必须包含以下控件:

4.5 播放器配置

在使用播放器播放视频之前,我们需要先对播放器的属性进行配置。

4.5.1 设置自定义 viewlog 参数

播放器在播放过程中,会按照其管理的心跳机制进行 viewlog 日志发送,该日志为用户播放信息。除了播放器记录的维度,开发者还可自定义部分参数。具体参数含义与用法,还需联系保利威技术支持获得帮助。

4.5.2 开启|关闭本地视频优先播放

PLVVodLocalVideo 是继承于 PLVVodVideo 的子类,表示本地的视频数据模型。PLVVodVideo 对象下载之后,也可以转化为 PLVVodLocalVideo 对象,即在线视频转为离线视频。播放器支持传入 PLVVodVideo 对象,也支持 PLVVodLocalVideo 对象。

当把一个 PLVVodVideo 对象传入播放器时,如果该视频已下载,播放器会根据属性 localPrior 的值来决定是否播放本地视频。

当该属性为 YES,播放器会自动检索对应的 PLVVodVideo 对象的离线视频,存在则播放离线视频,不存在则播放在线视频;当该属性为 NO,则根据传入 video 属性的对象播放视频,若传入 PLVVodVideo 对象则播放在线视频,若传入 PLVVodLocalVideo 对象则播本地离线视频,找不到资源则播放失败。

开发者可以根据播放器的 localPlayback 属性判断当前播放的到底是在线视频还是离线视频。

4.5.3 开启|关闭后台播放

后台播放指允许 App 返回到桌面或锁屏后,播放器依然能够播放音频。要实现后台播放,首先,需在 App 所在项目 “Capability” 中开启 “Background Modes” 中的 “Audio, AirPlay, and Picture in Picture”。如下图所示:

视频播放_图1

其次,播放器中有一个设置是否开启后台播放功能的属性,属性值默认为 YES,属性声明如下:

4.5.4 开启|关闭循环播放

如果希望打开循环播放,可以将播放器的 enablePlayRecycle 属性设为 YES,默认为 NO。注意,该功能不支持 hls 视频。

4.5.5 开启|关闭播放片头

开启"播放片头"后,将根据播放器逻辑应用点播后台设置的视频、图片片头,播放完片头后会自动播放正片。注意,此时不会应用自动播放(autoplay)的设置。

播放片头设置默认为 NO。开发者可根据播放器的 teaserState 属性获取片头的播放状态。

4.5.6 开启|关闭广告

开启广告后,将根据播放逻辑应用点播后台设置的视频、图片广告。在片头播放之前播放片头广告,暂停播放暂停广告,播放结束播放片尾广告。

注意,广告播放完成后,自动播放片头,若没有片头,或关闭了片头,则自动播放正片。此时不会应用自动播放(autoplay)的设置。

开启广告属性为 enableAd,默认为 NO。广告播放器 adPlayer 为只读属性。

4.5.7 开启|关闭记忆播放位置

记忆播放位置,顾名思义启用后会记录该视频上一次最后的播放位置。这里的“上一次”指上一次销毁播放器或切换视频的时机。仅当该属性为 YES 时,才会记录并更新上一次播放位置。

注意,视频播放完成后,会清除该视频记录的播放位置。

4.5.8 设置跑马灯

使用跑马灯功能需要 CocoaPods 引入 PLVMarquee 项目,并创建 PLVMarquee 跑马灯模型对象,并传入播放器的属性 marquee 中。

PLVMarquee 具体接口参照其头文件代码注释。使用示例:

注意,跑马灯功能目前并无与点播后台跑马灯接口接入,因此所有数据都是本地数据。

4.5.9 开启|关闭防录屏功能

开启防录屏功能后,一旦捕捉到录屏行为,会立即停止播放,并出现提示“停止录屏或投屏操作才能继续播放视频”的弹窗。防录屏功能默认关闭。

注意,播放过程中不能关闭防录屏功能。

4.5.10 开启|关闭自动播放

开启该属性,则视频载入后会立即播放。否则,需要开发者调用 -play 方法,播放器才会播放视频。

4.5.11 设置开始播放时间

开发者设置了开始播放时间 startPlaybackTime 后,播放器开始播放时会跳转到该时间。播放器中的“记忆播放位置”功能也是通过设置该属性来实现。

Last updated

Was this helpful?