zoukankan      html  css  js  c++  java
  • AVPlayer的使用+简单的播放器Demo

    学习内容

    先上项目地址,一个简单的AVPlayerDemo: https://github.com/practiceqian/QCAVPlayerDemo

    AVPlayer学习

    1. 几个播放器相关的类

      • AVPlayer、AVURLAsset、AVPlayerItem、AVPlayerLayer

        //控制播放器的播放、暂停、播放速度
        @property (nonatomic,strong) AVPlayer * player;
        //管理资源对象,提供播放数据源
        @property (nonatomic,strong) AVPlayerItem* playItem;
        //负责显示视频,如果没有添加该类,只有声音没有画面
        @property (nonatomic,strong) AVPlayerLayer* playerLayer;
        
    2. 构建一个简单的播放器

      • //一个UIImageView,构建播放器的显示区域
        self.playerView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height/3)];
        [self.view addSubview:self.playerView];
        
        //播放资源
        NSURL* playUrl = [NSURL URLWithString:@"http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"];
        self.playItem = [AVPlayerItem playerItemWithURL:playUrl];
        //播放器实例
        self.player = [AVPlayer playerWithPlayerItem:self.playItem];
        //显示区域
        self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
        self.playerLayer.frame = self.playerView.bounds;
        //将显示区域添加到UIImageView上
        [self.playerView.layer addSublayer:self.playerLayer];
        //开始播放
        [self.player play];
        
      • 效果如图

        • 可以在UIImageView的容器中看到画面,但是此时依然不能控制播放的进度等
    3. 使用AVPlayer控制播放行为

      • //播放
        [self.player play];
        //暂停
        [self.player pause];
        //控制播放速度
        self.player.rate = 2.0
        
    4. 使用AVPlayerItem控制播放状态

      • //三种播放状态
        typedef NS_ENUM(NSInteger, AVPlayerItemStatus) {
        	AVPlayerItemStatusUnknown = 0,	//未知
        	AVPlayerItemStatusReadyToPlay = 1,	//准备播放
        	AVPlayerItemStatusFailed = 2	//播放失败
        };
        
        
      • 使用KVO进行监听播放状态

        //对status进行监听
        [self.playItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
        //监听的回调
        - (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 (self.playItem.status) {
                        case AVPlayerItemStatusUnknown:
                            NSLog(@"播放状态未知");
                            break;
                        case AVPlayerItemStatusReadyToPlay:
                            NSLog(@"准备播放");
                            break;
                        case AVPlayerItemStatusFailed:
                            NSLog(@"播放失败");
                            break;;
                        default:
                            break;
                    }
                }
            }
        }
        
      • 获取播放时间

        • //CMTime是以分数的形式表示时间,value表示分子,timescale表示分母,flags是位掩码,表示时间的指定状态。
          typedef struct{
              CMTimeValue    value;     // 帧数
              CMTimeScale    timescale;  // 帧率(影片每秒有几帧)
              CMTimeFlags    flags;        
              CMTimeEpoch    epoch;    
          } CMTime;
          
        • //获取当前的播放时间
          float currentTime = self.playItem.currentTime.value/self.playItem.currentTime.timescale;
          //获取视频的总时间(一般在准备播放状态时获取)
          float totalTime = CMTimeGetSeconds(self.playItem.duration);
          
      • 监听播放的进度

        • __weak typeof(self) weakSelf = self;
          //CMTimeMake(1,1),一秒钟监听一次
          [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:nil usingBlock:^(CMTime time) {
            AVPlayerItem* item = weakSelf.playItem;
            float curTime = item.currentTime.value/item.currentTime.timescale;
            NSLog(@"当前时间:%.0f",curTime);
          }];
          
      • 监听缓冲的进度

        [self.playItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
        ---------------------------------------------------------------
          if ([keyPath isEqualToString:@"loadedTimeRanges"]){
          NSArray *array = self.playItem.loadedTimeRanges;
          CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次缓冲时间范围
          float startSeconds = CMTimeGetSeconds(timeRange.start);
          float durationSeconds = CMTimeGetSeconds(timeRange.duration); NSTimeInterval totalBuffer = startSeconds + durationSeconds;//缓冲总长度
          NSLog(@"当前已缓冲时间:%f",totalBuffer);
        }
        
      • 监听已缓存时间充足/不足

        [self.playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
        ---------------------------------------------------------------------
        [self.playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
        
      • 最后的demo


    最后欢迎关注我的iOS学习总结——每天学一点iOS:https://github.com/practiceqian/one-day-one-iOS-summary

  • 相关阅读:
    CSS3中新增的对文本和字体的设置
    PAT1107:Social Clusters
    Git的一些操作
    PAT1029:Median
    PAT1024:Palindromic Number
    PAT1028:List Sorting
    PAT1035: Password
    PAT1133:Splitting A Linked List
    PAT1017:Queueing at Bank
    PAT1105:Spiral Matrix
  • 原文地址:https://www.cnblogs.com/chenprice/p/12913819.html
Copyright © 2011-2022 走看看