我写信AVPlayer视频播放自定义播放器。 据苹果文档设置视频层:
self.player = [IPLPlayer new];
self.player.playerLayer = (AVPlayerLayer *)self.playerView.layer;
其中self.playerView是从这些文档通常类:
@implementation PlayerView
+ (Class) layerClass {
return [AVPlayerLayer class];
}
- (AVPlayer *)player {
return [(AVPlayerLayer *)[self layer] player];
}
- (void)setPlayer:(AVPlayer *) player {
[(AVPlayerLayer *) [self layer] setPlayer:player];
}
问题是:当关闭App(Home键),或块屏幕,视频播放停止,而当简历只有音频播放恢复,屏幕上的影像仍然是那些是块屏幕前 - 这是完全静态和辅币帧。
如何恢复视频播放画面被堵塞后?
看来我必须要注册通知,并且应用程序后,变为有效简历视频层:
-(void)registerNotification
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(willEnterBackground)
name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didEnterForeground)
name:UIApplicationDidBecomeActiveNotification object:nil];
}
-(void)unregisterNotification
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)willEnterBackground
{
NSLog(@"willEnterBackground");
[self.playerView willEnterBackground];
}
-(void)didEnterForeground
{
NSLog(@"didEnterForeground");
[self.playerView didEnterForeground];
}
而一个解决方案结合在一起,所有这些信息。
也许球员状态应该为不同的处理,但我喜欢的递归的方式。
注意:如果你不需要精确的查找时间,你可以使用[_player seekToTime:<#(CMTime)#> completionHandler:<#^(BOOL finished)completionHandler#>]
它的速度更快,但它试图到最近的关键帧。
- (void)viewDidLoad
{
[super viewDidLoad];
....
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnteredForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appEnteredBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}
....
-(void) appEnteredForeground {
AVPlayerLayer *player = (AVPlayerLayer *)[playerView layer];
[player setPlayer:NULL];
[player setPlayer:_player];
[self playAt:currentTime];
}
-(void) appEnteredBackground {
[_player pause];
currentTime = [_player currentTime];
}
-(void)playAt: (CMTime)time {
if(_player.status == AVPlayerStatusReadyToPlay && _player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
[_player seekToTime:time toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
[_player play];
}];
} else {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self playAt:time];
});
}
}
这对我的作品的斯威夫特3
添加的地方而设置的观点:
NotificationCenter.default.addObserver(self,
selector: #selector(appWillEnterForegroundNotification),
name: .UIApplicationWillEnterForeground, object: nil)
抓住你的播放器,并迫使它发挥:
func appWillEnterForegroundNotification() {
myPlayer.play()
}
不要忘记删除观察员,当你不需要他们:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
使用UIApplicationWillEnterForegroundNotification
为好。 你知道你的应用程序将是积极和明显的给用户的方法:
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(appEnteredForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
经过一番研究,我发现,同一个袋子中的iOS播放器(web浏览器,的MPMoviePlayerController)。 可能是因为内容分发类型是渐进式下载。
所以,解决办法是:
- 使用下面的通知,并保存当前时间。
- 应用恢复后,重新AVPlayer,并开始从保存的时间玩。
在所有其他情况下的图像被阻挡,或者视图变成黑色。
关键是要卸下所有视频层从他们的球员,当应用程序确实进入的背景和他们重新连接时,应用程序也变得活跃起来。
因此,在您-applicationDidEnterBackground:
你有触发导致的机制
avPlayerLayer.player = nil;
并在-applicationDidBecomeActive:
您重新安装播放器一样
avPlayerLayer.player = self.avPlayer;
也看看这个技术说明( QA1668苹果)。