AVPlayer

AVPlayer是AVFoundation.Framework提供的偏向于底层的视频播放控件,用起来复杂,但功能强大。单独使用AVPlayer是无法显示视频的,要把它添加到AVPlayerLayer里才行。另外它需要配合AVPlayerItem使用,AVPlayerItem类似于MVC里的Model层,负责资源加载、视频播放设置及播放状态管理(通过KVO方式来观察状态)。

首先创建一个AVPlayerItem对象:

NSURL* videoUrl = [NSURLfileURLWithPath:m_path isDirectory:NO];m_playItem = [AVPlayerItem playerItemWithURL:videoUrl];

// 监听playItem的status属性

[m_playItem addObserver:selfforKeyPath:@"status"

options:NSKeyValueObservingOptionNew context:nil];

接下来是创建AVPlayer和AVPlayerLayerView对象。AVPlayerLayerView是自定义的UIView,用于AVPlayer播放,其layerClass是AVPlayerLayer:

// AVPlayer

m_player = [AVPlayer playerWithPlayerItem:m_playItem];m_player.actionAtItemEnd= AVPlayerActionAtItemEndNone;

// AVPlayerLayerView

m_playerView = [[AVPlayerLayerView alloc] initWithFrame:self.bounds];[selfaddSubview:m_playerView];

// 把AVPlayer添加到AVPlayerLayer

[(AVPlayerLayer*)[m_playerView layer] setPlayer:m_player];

// 观察AVPlayerItem播放结束的通知

[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(itemPlayEnded:)

name:AVPlayerItemDidPlayToEndTimeNotification object:m_playItem];

AVPlayerItem的status属性有三种状态:AVPlayerStatusUnknown、AVPlayerStatusReadyToPlay及AVPlayerStatusFailed。当status=AVPlayerStatusReadyToPlay时,就代表视频能播放了,此时调用AVPlayer的play方法就能播放视频了。

相比MPMoviePlayerController,AVPlayer有最多可以同时播放16个视频。另外AVPlayer在使用时会占用AudioSession,这个会影响用到AudioSession的地方,如聊天窗口开启小视频功能。还有AVPlayer释放时最好先把AVPlayerItem置空,否则会有解码线程残留着。最后是性能问题,如果聊天窗口连续播放几个小视频,列表滑动时会非常卡。通过Instrument测试性能,看不出哪里耗时,怀疑是视频播放互相抢锁引起的。

推荐阅读更多精彩内容