美文网首页
AVPlayer使用详解

AVPlayer使用详解

作者: OwenWong | 来源:发表于2020-01-13 16:28 被阅读0次

    iOS平台播放视频,系统提供了下面三种方式:MPMoviePlayerController、AVPlayerViewController、AVPlayer。前两种简单易用,但不可定制。最后一种AVPlayer:功能强大,可定制度高,唯一美中不足的是需要将视频层添加至AVPlayerLayer中,这样才能将视频显示出来。

    开发时这样做

    在ViewController的@interface中添加以下属性:

    @property (nonatomic ,strong) AVPlayer *player;
    @property (nonatomic ,strong) AVPlayerItem *playerItem;
    @property (nonatomic , strong) PlayerView *playerView;
    

    PlayerView继承自UIView,不过重写了set和get方法,用于将player添加至playerView的AVPlayerLayer中,这样视频画面才能显示出来。在PlayerView.h中声明一个AVPlayer对象,由于默认的layer是CALayer,而AVPlayer只能添加至AVPlayerLayer中,所以我们改变一下layerClass,这样PlayerView的默认layer就变了,之后我们可以把在viewController中初始化的AVPlayer对象赋给AVPlayerLayer的player属性。

    ////PlayerView.h 
    @property (nonatomic ,strong) AVPlayer *player;
     
    ////PlayerView.m
    + (Class)layerClass {
        return [AVPlayerLayer class];
    }
    - (AVPlayer *)player {
        return [(AVPlayerLayer *)[self layer] player];
    }
    - (void)setPlayer:(AVPlayer *)player {
        [(AVPlayerLayer *)[self layer] setPlayer:player];
    }
    

    然后执行下面代码,即可播放视频:

    NSURL *videoUrl = [NSURL URLWithString:@"http://www.jxvdy.com/file/upload/201405/05/18-24-58-42-627.mp4"];
    self.playerItem = [AVPlayerItem playerItemWithURL:videoUrl];
    // status 播放状态
    [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    // loadedTimeRanges 缓存时间
    [self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    // playbackBufferEmpty 缓存不足
    [self.playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
    // playbackLikelyToKeepUp 缓存充足
    [self.playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    
    self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
    [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotificationobject:self.playerItem];
    

    AVPlayerItem监听的几个对象:

    1. status 播放状态
    typedef NS_ENUM(NSInteger, AVPlayerItemStatus) {
        AVPlayerItemStatusUnknown,//未知
        AVPlayerItemStatusReadyToPlay,//准备播放
        AVPlayerItemStatusFailed//播放失败
    };
    

    使用KVO监测playItem.status,可以获取播放状态的变化

    1. loadedTimeRanges 缓存时间
      监测它可以知道视频的缓存情况,必要时可在缓存完成后将视频存入本地。
    2. playbackBufferEmpty与playbackLikelyToKeepUp,这两个是一对,即通常配对使用
      playbackBufferEmpty可以让我们在缓存不够(视频加载不出来)时,暂停播放显示loading;
      playbackLikelyToKeepUp则告诉我们缓存足够播放,此时重启播放。
      KVO监听:
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        
        if ([object isKindOfClass:[AVPlayerItem class]]) {
            if ([keyPath isEqualToString:@"status"]) {
                switch (_playerItem.status) {
                    case AVPlayerItemStatusReadyToPlay:
                        //推荐将视频播放放在这里
                        [self play];
                        break;
                    case AVPlayerItemStatusUnknown:
                        NSLog(@"AVPlayerItemStatusUnknown");
                        break;
                    case AVPlayerItemStatusFailed:
                        NSLog(@"AVPlayerItemStatusFailed")
                        break;
                    default:
                        break;
                }
            }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(@"当前缓冲时间:%f",totalBuffer);
            }else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
              //some code show loading   
            }else if([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {    
              //由于 AVPlayer 缓存不足就会自动暂停,所以缓存充足了需要手动播放,才能继续播放  
              [_player play];      
          }
        }
    }
    
    

    AVPlayerItem的几个常用通知:

    //播放完成
    AVPlayerItemDidPlayToEndTimeNotification
    //播放失败
    AVPlayerItemFailedToPlayToEndTimeNotification
    //异常中断
    AVPlayerItemPlaybackStalledNotification
    
    // 使用
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerMovieFinish:) name:AVPlayerItemDidPlayToEndTimeNotification object:[self.player currentItem]];
    

    参考:
    1、AVPlayer的基本使用
    2、AVPlayer详解系列(一)参数设置

    相关文章

      网友评论

          本文标题:AVPlayer使用详解

          本文链接:https://www.haomeiwen.com/subject/cemgactx.html