AVPlayer的使用+简单的播放器Demo
学习内容
先上项目地址,一个简单的AVPlayerDemo: https://github.com/practiceqian/QCAVPlayerDemo
AVPlayer学习
-
几个播放器相关的类
-
AVPlayer、AVURLAsset、AVPlayerItem、AVPlayerLayer
//控制播放器的播放、暂停、播放速度 @property (nonatomic,strong) AVPlayer * player; //管理资源对象,提供播放数据源 @property (nonatomic,strong) AVPlayerItem* playItem; //负责显示视频,如果没有添加该类,只有声音没有画面 @property (nonatomic,strong) AVPlayerLayer* playerLayer;
-
-
构建一个简单的播放器
-
//一个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的容器中看到画面,但是此时依然不能控制播放的进度等
-
-
使用AVPlayer控制播放行为
-
//播放 [self.player play]; //暂停 [self.player pause]; //控制播放速度 self.player.rate = 2.0
-
-
使用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
posted on 2020-05-18 23:30 pricechen 阅读(1271) 评论(0) 编辑 收藏 举报