AVPlayerItem
一.基本概念
AVPlayerItem models the timing and presentation state of an asset played by an AVPlayer object. It provides the interface to seek to various times in the media, determine its presentation size, identify its current time, and much more.
简单点说,AVPlayerItem提供了AVPlayer播放需要的媒体文件,时间、状态、文件大小等信息,是AVPlayer媒体文件的载体。
二.基本使用方法
2.1初始化播放器
NSURL *assetUrl = [NSURL URLWithString:@"http://flv2.bn.netease.com/videolib3/1606/23/RiTxE9164/SD/RiTxE9164-mobile.mp4"];
AVAsset *asset = [AVAsset assetWithURL:assetUrl];
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
self.player = [AVPlayer playerWithPlayerItem:item];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = CGRectMake(0, 50, 320, 180);
[self.view.layer addSublayer:playerLayer];
2.2监听AVPlayerItem的相关属性
- 2.2.1 AVPlayerItem的status属性
typedef NS_ENUM(NSInteger, AVPlayerItemStatus) {
AVPlayerItemStatusUnknown,//未知状态,刚初始化状态
AVPlayerItemStatusReadyToPlay,//准备就绪
AVPlayerItemStatusFailed//失败状态
};
监听AVPlayerItem状态
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"status"]) {
AVPlayerItem * item = (AVPlayerItem *)object;
if (item.status == AVPlayerItemStatusReadyToPlay) {
[self.player play];
}else if (item.status == AVPlayerItemStatusFailed){
NSLog(@"failed");
}
}
}
- 2.2.2 loadedTimeRanges状态
通常情况下,在加载网络视频时,我们需要获取视频的缓冲进度,这时候,我们可以通过监听AVPlayerItem的loadedTimeRanges状态,获取缓冲进度
为AVPlayerItem添加一个监听
[self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
NSArray *timeRanges = (NSArray *)[change objectForKey:NSKeyValueChangeNewKey];
[self updateLoadedTimeRanges:timeRanges];
}
}
- (void)updateLoadedTimeRanges:(NSArray *)timeRanges {
if (timeRanges && [timeRanges count]) {
CMTimeRange timerange = [[timeRanges firstObject] CMTimeRangeValue];
CMTime bufferDuration = CMTimeAdd(timerange.start, timerange.duration);
// 获取到缓冲的时间,然后除以总时间,得到缓冲的进度
NSLog(@"%f",CMTimeGetSeconds(bufferDuration));
}
}
- 2.2.3 playbackBufferEmpty状态
监听playbackBufferEmpty我们可以获取当缓存不够,视频加载不出来的情况:
// 缓冲区空了,需要等待数据
[self.playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
//缓冲区空了,所需做的处理操作
}
}
- 2.2.4playbackLikelyToKeepUp状态
playbackLikelyToKeepUp和playbackBufferEmpty是一对,用于监听缓存足够播放的状态:
[self.playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
//缓冲就绪,所需做的处理操作
}
}
2.3播放相关通知
- 2.3.1播放状态
//播放完成
AVPlayerItemDidPlayToEndTimeNotification
//播放失败
AVPlayerItemFailedToPlayToEndTimeNotification
//异常中断
AVPlayerItemPlaybackStalledNotification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem];
- (void)moviePlayDidEnd:(NSNotification *)notification{
//视频播放完毕操作
}
- 2.3.2声音类通知
//声音被打断的通知(电话打来)
AVAudioSessionInterruptionNotification
//耳机插入和拔出的通知
AVAudioSessionRouteChangeNotification
- 2.3.4 系统状态
//进入后台
UIApplicationWillResignActiveNotification
//返回前台
UIApplicationDidBecomeActiveNotification
2.4 跳转到指定时间点
- (void)seekToTime:(CMTime)time;
- (void)seekToTime:(CMTime)time completionHandler:(void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);
- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter;
//此方法包含回调事件
- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter completionHandler:(void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);
网友评论