因为最近有使用视频播放的需求,所以自己简单的研究了一下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里面还包含了不少类,有兴趣的朋友可以自己去深入研究,我只是个菜鸟,只会很基本的东西,哈哈