1.如何获取画中画的暂停和播放状态。
在AVPlayer中监听timeControlStatus
self->player = [[AVPlayer alloc] initWithPlayerItem:item];
[self->player addObserver:self forKeyPath:@"timeControlStatus" options:NSKeyValueObservingOptionNew context:nil];//监听 timeControlStatus(为了监听画中画模式的暂停播放)
/**
* kVC监听播放状态
*
* @param keyPath
* @param object
* @param change
* @param context
*/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([player isEqual:object] && [@"timeControlStatus" isEqualToString:keyPath]){
if (IS_IOS10_OR_LATER && pipController.isPictureInPictureActive) {//画中画启动状态
switch (player.timeControlStatus) {
case AVPlayerTimeControlStatusPaused:
//暂停
break;
case AVPlayerTimeControlStatusPlaying:
//播放
}
break;
default:
break;
}
}
}
}
2.视频全屏的时候按HOME键退到后台,自动启动画中画功能。
经查明:
重要:苹果想让画中画功能一直能被用户操控,只有用户明确请求画中画功能才响应。尤其是退到后台时不能立即响应用户唤起画中画功能,这样的App会被App Store拒绝。
当用户按压Home键或触发一个把他们带入其他App的通知时,iOS 9自动将一个全屏播放的视频转到PiP播放。视频播放使用该功能的要求如下:
按照本章之前的描述那样让App支持画中画功能。
使用视图的视图填充窗口的边界来全屏播放视频。
提示:用户可以在禁用画中画自动唤起,通过设置 Settings > General > Multitasking > Persistent Video Overlay。如果你认为一切已设置妥当,但当你按下Home键时,发现你的视频不会进入画中画,请检查此项设置。
当App播放的视频转到画中画播放时,系统将管理视频内容的呈现,而你的App会继续在后台运行。当你的应用程序在后台运行,请确保丢弃不需要的资源,如视图控制器、视图、图像和数据缓存。在这种情况下,你期望执行适当且必须的操作,如视频合成、音频处理、下载接下来播放的内容等操作,但你必须注意尽可能少地消耗资源。如果你的应用程序在后台消耗太多的资源,系统将终止它。
参考资料:https://www.jianshu.com/p/27ce4ada48da iOS 9 分屏多任务:画中画(PiP)快速入门
3.播放一个错误的视频地址,没有fail、没有end。
目前没有好的解决办法,具体原因也没有查明。(难道是AVPictureInPictureController的问题?)
解决办法是,记一个标记:
BOOL isLoadedTimeEmpty;
然后监听 AVPlayerItem的status和loadedTimeRanges
AVPlayerItem *item = [[AVPlayerItem alloc] initWithAsset:self->asset];
item.canUseNetworkResourcesForLiveStreamingWhilePaused = YES;
//添加观察者
[item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
[item addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
/**
* kVC监听播放状态
*
* @param keyPath
* @param object
* @param change
* @param context
*/
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([player.currentItem isEqual:object] && [@"status" isEqualToString:keyPath]){
switch (player.status) {
case AVPlayerStatusReadyToPlay:
{
if (isPlaying) {
NSArray *loadedTimeRanges = [[player currentItem] loadedTimeRanges];
if (loadedTimeRanges.count==0) {
isLoadedTimeEmpty = YES;
//此处应走停止播放回调/代理
return;
}
//此处应走播放的回调/代理
}
}
break;
case AVPlayerStatusFailed:
{
DDLogDebug(@"AVPlayerStatusFailed");
}
break;
case AVPlayerStatusUnknown:
{
DDLogDebug(@"AVPlayerStatusUnknown");
}
break;
default:
break;
}
}
else if ([player.currentItem isEqual:object] && [@"loadedTimeRanges" isEqualToString:keyPath]){
NSArray *loadedTimeRanges = [[player currentItem] loadedTimeRanges];
if (isLoadedTimeEmpty && loadedTimeRanges.count>=0) {
//此处应走播放的回调/代理(防止其实能播,但是因为回来的先后顺序不能播的情况)
}
}
}
网友评论