AVFoundation 框架中的AVPlayer 也可以完成视频的播放,相较于强大及简单的MPMoviePlayerController,AVPlayer使用起来更加灵活,且偏近于底层。
AVPlayer本身不能显示视频,它需要通过播放器层AVPlayerLayer来展示视频,使用时将AVPlayerLayer添加到视图控制器的layer中。
AVPlayer播放视频的使用步骤
1.添加AVFoundation框架,引入头文件#import <AVFoundation/AVFoundation.h>
2.获取设置播放源AVPlayerItem对象
NSString*strURL=[NSString stringWithFormat:@“视频源地址(网络)”];
strURL=[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL*strFinalUrl=[NSURL URLWithString:strURL];
AVPlayerItem* playerItem=[AVPlayerItem playerItemWithURL:strFinalUrl];
3.初始化AVPlayer对象,顺便添加对于AVPlayerItem对象变化的通知
AVPlayer* player=[AVPlayer playerWithPlayerItem:playerItem];
//监控状态属性,监控播放状态
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
//监控网络加载情况属性
[playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
//停止监控
[playerItem removeObserver:self forKeyPath:@“监控属性”];
通过KVO监控播放器状态,在-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context中做相 应操作,变量含义如下:
@param keyPath 监控属性 @param object 监视器 @param change 状态改变 @param context 上下文
首先判断监控属性是否是自己想要的属性:播放状态(status)和加载视频时间长度变化(loadedTimeRanges)
AVPlayer的播放状态有三种,如下
typedef NS_ENUM(NSInteger, AVPlayerStatus) {
AVPlayerStatusUnknown,//未知
AVPlayerStatusReadyToPlay,//播放
AVPlayerStatusFailed//失败
};
加载视频长度变化从AVPlayerItem的loadedTimeRanges属性中得到,示例如下:
NSArray *array=playerItem.loadedTimeRanges;
CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围
float startSeconds = CMTimeGetSeconds(timeRange.start);//缓冲起始时间
float durationSeconds = CMTimeGetSeconds(timeRange.duration);//本次加载的长度
NSTimeInterval totalBuffer = startSeconds + durationSeconds;//总共加载的长度
4.初始化AVPlayerLayer对象,并添加到控制器视图层中
AVPlayerLayer *playerLayer=[AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame=self.container.frame;
playerLayer.videoGravity=AVLayerVideoGravityResizeAspect;//视频填充模式
[self.view.layer addSublayer:playerLayer];
5.进度条的变化,同样需要依靠AVPlayer的- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block方法获得播放进度,这个方法会在设定的时间间隔内定时更新播放进度,通过time参数通知客户端。
float current=CMTimeGetSeconds(time);//从播放开始获取播放时间(单位:秒)
float total=CMTimeGetSeconds([playerItem duration]);//获取视频播放总时间
[progress setProgress:(current/total) animated:YES];//设置进度条