学习内容

先上项目地址,一个简单的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

最新文章

  1. Java IO7:管道流、对象流
  2. SPM - data analysis
  3. centos中rabbitmq的安装及php支持
  4. Array 原型扩展(快速排序,搅乱顺序)
  5. COCOS2D-X 精灵创建随笔
  6. linux共享内存简析
  7. nyoj 592 spiral grid(广搜)
  8. kmp next数组的理解(挺好的一篇文章 ,原来kmp最初的next是这样的啊,很好理解)
  9. 在java中如何使用etcd的v2 和v3 api获取配置,并且对配置的变化进行监控
  10. 服务器http://localhost:8080要求用户输入用户名和密码
  11. 你不知道的 requestIdleCallback
  12. laravel 黑名单功能实现
  13. php无限极分类方法
  14. MDK编译器内存分配
  15. python编程的简洁代码
  16. next_permutation(start,end)
  17. 8.css内容移出与精灵图
  18. vue--子组件主动获取父组件的数据和方法
  19. elasticsearch文档学习
  20. PHP数组函数的使用

热门文章

  1. 双系统情况下,ubuntu开机挂载Windows分区
  2. 使用Idea当中的快捷键快速查看继承关系或其图表的两种方法
  3. js 一个或多个一维数组,算出元素之间相互组合的所有情况
  4. 吕建文 20199303《Linux内核原理与分析》第十二周作业
  5. Scala教程之:Either
  6. Java5-7作业总结(第八次作业)19201421-吴志越
  7. 这个linux命令能让时光倒流!你不知道的date隐藏用法
  8. 什么是.pyc文件
  9. Git 常见问题汇总
  10. iterm2终端manpage高亮显示