因为最近有使用视频播放的需求,所以自己简单的研究了一下AVPlayer。AVPlayer是一个很好可以自定义播放的框架,基本上可以满足我们大多数的需求。在这里我就不列出详细的方法和属性了,我就粘贴一下我自己写的demo
// // ViewController.m // PlayVideo // // Created by mac on 2016/11/16. // Copyright © 2016年 mac. All rights reserved. // #import "ViewController.h" #import <AVFoundation/AVFoundation.h> #define kScreenWidth [UIScreen mainScreen].bounds.size.width #define kScreenHeight [UIScreen mainScreen].bounds.size.height @interface ViewController () @property (nonatomic,strong) AVPlayer *player;//播放器对象 @property (nonatomic, strong) NSArray *urlPaths; @property (strong, nonatomic) UIImageView *imageView; @property (strong, nonatomic) AVPlayerItem *playerItem; @end @implementation ViewController - (UIImageView *)imageView { if (!_imageView) { _imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds]; _imageView.image = [UIImage imageNamed:@"background"]; _imageView.userInteractionEnabled = YES; [self.view addSubview:_imageView]; } return _imageView; } - (NSArray *)urlPaths { if (!_urlPaths) { NSString *bottomPath = [[NSBundle mainBundle] pathForResource:@"bottom" ofType:@"mp4"]; NSString *allPath = [[NSBundle mainBundle] pathForResource:@"all" ofType:@"mp4"]; NSString *businessPath = [[NSBundle mainBundle] pathForResource:@"business" ofType:@"mp4"]; NSString *contextPath = [[NSBundle mainBundle] pathForResource:@"context" ofType:@"mp4"]; NSString *trafficPath = [[NSBundle mainBundle] pathForResource:@"traffic" ofType:@"mp4"]; _urlPaths = @[bottomPath,allPath,trafficPath,businessPath,contextPath]; } return _urlPaths; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self setupUI]; [self addNotification]; [self.player play]; //获取player的播放进度 [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) { float current = CMTimeGetSeconds(time); NSLog(@"当前已经播放%f",current); }]; } -(void)dealloc{ [self removeNotification]; } #pragma mark - 私有方法 -(void)setupUI{ //创建播放器层 AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; playerLayer.frame = self.imageView.frame; // self.allPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspect;//视频填充模式 [self.imageView.layer addSublayer:playerLayer]; UIButton *mainBtn = [UIButton buttonWithType:UIButtonTypeCustom]; mainBtn.frame = CGRectMake(kScreenWidth - 90, kScreenHeight - 90, 80, 80); [mainBtn setImage:[UIImage imageNamed:@"按钮"] forState:UIControlStateNormal]; [mainBtn addTarget:self action:@selector(clickMainBtn:) forControlEvents:UIControlEventTouchUpInside]; mainBtn.tag = 0; UIButton *allBtn = [UIButton buttonWithType:UIButtonTypeCustom]; allBtn.frame = CGRectMake(kScreenWidth + 100, kScreenHeight - 120, 100, 20); [allBtn setImage:[UIImage imageNamed:@"全部"] forState:UIControlStateNormal]; [allBtn addTarget:self action:@selector(navigationButtonClick:) forControlEvents:UIControlEventTouchUpInside]; allBtn.tag = 1; UIButton *trafficBtn = [UIButton buttonWithType:UIButtonTypeCustom]; trafficBtn.frame = CGRectMake(kScreenWidth + 100, kScreenHeight - 150, 100, 20); [trafficBtn setImage:[UIImage imageNamed:@"交通"] forState:UIControlStateNormal]; [trafficBtn addTarget:self action:@selector(navigationButtonClick:) forControlEvents:UIControlEventTouchUpInside]; trafficBtn.tag = 2; UIButton *businessBtn = [UIButton buttonWithType:UIButtonTypeCustom]; businessBtn.frame = CGRectMake(kScreenWidth + 100, kScreenHeight - 180, 100, 20); [businessBtn setImage:[UIImage imageNamed:@"商圈"] forState:UIControlStateNormal]; [businessBtn addTarget:self action:@selector(navigationButtonClick:) forControlEvents:UIControlEventTouchUpInside]; businessBtn.tag = 3; UIButton *contextBtn = [UIButton buttonWithType:UIButtonTypeCustom]; contextBtn.frame = CGRectMake(kScreenWidth + 100, kScreenHeight - 210, 100, 20); [contextBtn setImage:[UIImage imageNamed:@"文脉"] forState:UIControlStateNormal]; [contextBtn addTarget:self action:@selector(navigationButtonClick:) forControlEvents:UIControlEventTouchUpInside]; contextBtn.tag = 4; [self.imageView addSubview:contextBtn]; [self.imageView addSubview:allBtn]; [self.imageView addSubview:trafficBtn]; [self.imageView addSubview:businessBtn]; [self.imageView addSubview:mainBtn]; } - (void)clickMainBtn:(UIButton *)sender { sender.selected = !sender.selected; UIButton *allbtn = [self.imageView viewWithTag:1]; UIButton *trafficbtn = [self.imageView viewWithTag:2]; UIButton *businessbtn = [self.imageView viewWithTag:3]; UIButton *contextbtn = [self.imageView viewWithTag:4]; if (sender.selected) { [UIView animateWithDuration:1.0f animations:^{ allbtn.frame = CGRectMake(kScreenWidth - 100, kScreenHeight - 120, 100, 20); trafficbtn.frame = CGRectMake(kScreenWidth - 100, kScreenHeight - 150, 100, 20); businessbtn.frame = CGRectMake(kScreenWidth - 100, kScreenHeight - 180, 100, 20); contextbtn.frame = CGRectMake(kScreenWidth - 100, kScreenHeight - 210, 100, 20); }]; } else { [UIView animateWithDuration:1.0f animations:^{ allbtn.frame = CGRectMake(kScreenWidth + 100, kScreenHeight - 120, 100, 20); trafficbtn.frame = CGRectMake(kScreenWidth + 100, kScreenHeight - 150, 100, 20); businessbtn.frame = CGRectMake(kScreenWidth + 100, kScreenHeight - 180, 100, 20); contextbtn.frame = CGRectMake(kScreenWidth + 100, kScreenHeight - 210, 100, 20); }]; [self playWithItem:0]; } } /** * 初始化播放器 * * @return 播放器对象 */ -(AVPlayer *)player{ if (!_player) { self.playerItem = [self getPlayItem:0]; _player=[AVPlayer playerWithPlayerItem:self.playerItem]; [self addObserverToPlayerItem:self.playerItem]; } return _player; } /** * 根据视频索引取得AVPlayerItem对象 * * @param videoIndex 视频顺序索引 * * @return AVPlayerItem对象 */ -(AVPlayerItem *)getPlayItem:(int)videoIndex{ NSURL *url=[NSURL fileURLWithPath:[self.urlPaths objectAtIndex:videoIndex]]; AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url]; return playerItem; } #pragma mark - 通知 /** * 添加播放器通知 */ -(void)addNotification{ //给AVPlayerItem添加播放完成通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; //添加进入后台和前台的通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; } - (void)applicationDidEnterBackground:(NSNotification *)notification { //暂停 [self.player pause]; } - (void)applicationWillEnterForeground:(NSNotification *)notification { //播放 [self.player play]; } -(void)removeNotification{ [[NSNotificationCenter defaultCenter] removeObserver:self]; } /** * 播放完成通知 * * @param notification 通知对象 */ -(void)playbackFinished:(NSNotification *)notification{ NSLog(@"视频播放完成."); AVPlayerItem * playerItem = [notification object]; //重复播放的关键代码(设置时间为0,然后重新播放) [playerItem seekToTime:kCMTimeZero]; [self.player play]; } #pragma mark - 监控 /** * 给AVPlayerItem添加监控 * * @param playerItem AVPlayerItem对象 */ -(void)addObserverToPlayerItem:(AVPlayerItem *)playerItem{ //监控状态属性,注意AVPlayer也有一个status属性,通过监控它的status也可以获得播放状态 [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil]; //监控网络加载情况属性 [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil]; } -(void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem{ [playerItem removeObserver:self forKeyPath:@"status"]; [playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"]; } /** * 通过KVO监控播放器状态 * * @param keyPath 监控属性 * @param object 监视器 * @param change 状态改变 * @param context 上下文 */ -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ AVPlayerItem *playerItem=object; if ([keyPath isEqualToString:@"status"]) { AVPlayerStatus status= [[change objectForKey:@"new"] intValue]; if(status==AVPlayerStatusReadyToPlay){ NSLog(@"正在播放...,视频总长度:%.2f",CMTimeGetSeconds(playerItem.duration)); } } else if ([keyPath isEqualToString:@"loadedTimeRanges"]){ NSArray *array=playerItem.loadedTimeRanges; CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围 float startSeconds = CMTimeGetSeconds(timeRange.start); float durationSeconds = CMTimeGetSeconds(timeRange.duration); NSTimeInterval totalBuffer = startSeconds + durationSeconds;//缓冲总长度 NSLog(@"共缓冲:%.2f",totalBuffer); } } #pragma mark - UI事件 /** * 切换选集,这里使用按钮的tag代表视频名称 * * @param sender 点击按钮对象 */ - (void)navigationButtonClick:(UIButton *)sender { [self playWithItem:sender.tag]; } - (void)playWithItem:(NSInteger)item { [self removeNotification]; [self removeObserverFromPlayerItem:self.player.currentItem]; self.playerItem = [self getPlayItem:(int)item]; [self addObserverToPlayerItem:self.playerItem]; //切换视频 [self.player replaceCurrentItemWithPlayerItem:self.playerItem]; [self addNotification]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
当然,AVFoundation里面还包含了不少类,有兴趣的朋友可以自己去深入研究,我只是个菜鸟,只会很基本的东西,哈哈