关于AVPlayer的使用,我看绝大多数的博客上介绍的用法基本如下:
AVPlayerItem * playerItem = [AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:item.localPath]];
AVPlayer * player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer * playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame = view.bounds;
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
[view.layer addSublayer:playerLayer];
[player play]
这样写简单粗暴,确实能正常播放,但是细细研究就发现不太亲和。
1.如果多次重复使用,就会多次调用:
[view.layer addSublayer:playerLayer];
view.layer.sublayers会持续增多,内存会慢慢递增,如果加载资源的内存过大,会有潜在风险,甚至导致奔溃。
sublayers.png
所以最好在addSublayer前移除已存在的AVPlayerLayer:
for (CALayer *layer in view.layer.sublayers) {
if ([layer class] == [AVPlayerLayer class]) {
[layer removeFromSuperlayer];
}
}
2.如果再细节处理到位点,可以利用KVO监控playerItem的状态
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"status"]) {
//取出status的新值
AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey]intValue];
switch (status) {
case AVPlayerItemStatusFailed:
NSLog(@"视频资源有误,加载失败");
break;
case AVPlayerItemStatusReadyToPlay:
NSLog(@"视频资源加载成功,准备好播放了");
break;
case AVPlayerItemStatusUnknown:
NSLog(@"视频资源出现未知错误");
break;
default:
break;
}
}
//移除监听(观察者)
[object removeObserver:self forKeyPath:@"status"];}
当状态为AVPlayerItemStatusReadyToPlay时,说明资源已经准备到位,这时再使用[player play]更为合理
网友评论