1.清除KVO;
2.暂停;
3.清空缓存区;
4.从父视图移除播放器;
5.移除播放器的全部视图;
6.把播放器置为nil。
具体代码:
-(void)hiddenPlayer { if(self.isPlay && self.player) { [self.player.currentItem removeObserver:self forKeyPath:@"status"]; [self.player.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"]; [self.player pause]; self.currentPlayerItem = nil; [self.player replaceCurrentItemWithPlayerItem:nil];//清除播放缓存 for (CALayer *layer in self.photoImageView.layer.sublayers) { if ([layer class] == [AVPlayerLayer class]) { [layer removeFromSuperlayer]; } } [self.player removeAllSubView]; self.photoImageView.hidden = YES; self.isPlay = NO; self.player = nil; // [self.playButton setImage:[UIImage imageNamed:@"播放"] forState:UIControlStateNormal]; [self updatePlayBtn]; } }
相关声明:
#import <AVFoundation/AVFoundation.h> @interface PPChooseSongHeadView()<SDCycleScrollViewDelegate> @property (nonatomic, strong) UILabel *describeTitleLabel; @property (nonatomic, strong) UILabel *idLabel; @property (nonatomic, strong) SDCycleScrollView *imagesScrollView; @property (nonatomic, strong) UIView *backgroundView; @property (nonatomic, strong) UIImageView *photoImageView; @property (nonatomic, strong) UIButton *playButton; @property (nonatomic, assign) BOOL isPlay; @property (nonatomic, strong) JCTBannerEntity *entity; @property (nonatomic,strong)AVPlayer *player;//播放器对象 @property (nonatomic,strong)AVPlayerItem *currentPlayerItem; @end
@interface PPChooseSongHeadView : BGBaseView //@property (nonatomic, strong) UILabel *backLabel; @property (nonatomic, strong) JCTProjectListEntity *model; @property (nonatomic, strong) PPRoomCateListEntity *roomCateListEntity; @property (nonatomic, copy) void(^endEditingBlock)(void); - (instancetype)initWithFrame:(CGRect)frame; -(void)hiddenPlayer; @end
视频建立与播放,按钮显示相关代码:
//2.添加属性观察 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { // AVPlayerItem *playerItem = (AVPlayerItem *)object; if ([keyPath isEqualToString:@"status"]) { //获取playerItem的status属性最新的状态 AVPlayerStatus status = [[change objectForKey:@"new"] intValue]; switch (status) { case AVPlayerStatusReadyToPlay:{ // //获取视频长度 // CMTime duration = playerItem.duration; // //更新显示:视频总时长(自定义方法显示时间的格式) // self.totalNeedPlayTimeLabel.text = [self formatTimeWithTimeInterVal:CMTimeGetSeconds(duration)]; // //开启滑块的滑动功能 // self.sliderView.enabled = YES; // //关闭加载Loading提示 // [self showaAtivityInDicatorView:NO]; //开始播放视频 [self.player play]; break; } case AVPlayerStatusFailed:{//视频加载失败,点击重新加载 // [self showaAtivityInDicatorView:NO];//关闭Loading视图 // self.playerInfoButton.hidden = NO; //显示错误提示按钮,点击后重新加载视频 // [self.playerInfoButton setTitle:@"资源加载失败,点击继续尝试加载" forState: UIControlStateNormal]; [[BITNoticeView currentNotice] showErrorNotice:@"资源加载失败,请继续尝试加载"]; [self hiddenPlayer]; break; } case AVPlayerStatusUnknown:{ NSLog(@"加载遇到未知问题:AVPlayerStatusUnknown"); [self hiddenPlayer]; break; } default: break; } } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) { // //获取视频缓冲进度数组,这些缓冲的数组可能不是连续的 // NSArray *loadedTimeRanges = playerItem.loadedTimeRanges; // //获取最新的缓冲区间 // CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue]; // //缓冲区间的开始的时间 // NSTimeInterval loadStartSeconds = CMTimeGetSeconds(timeRange.start); // //缓冲区间的时长 // NSTimeInterval loadDurationSeconds = CMTimeGetSeconds(timeRange.duration); // //当前视频缓冲时间总长度 // NSTimeInterval currentLoadTotalTime = loadStartSeconds + loadDurationSeconds; // //NSLog(@"开始缓冲:%f,缓冲时长:%f,总时间:%f", loadStartSeconds, loadDurationSeconds, currentLoadTotalTime); // //更新显示:当前缓冲总时长 // _currentLoadTimeLabel.text = [self formatTimeWithTimeInterVal:currentLoadTotalTime]; // //更新显示:视频的总时长 // _totalNeedLoadTimeLabel.text = [self formatTimeWithTimeInterVal:CMTimeGetSeconds(self.player.currentItem.duration)]; // //更新显示:缓冲进度条的值 // _progressView.progress = currentLoadTotalTime/CMTimeGetSeconds(self.player.currentItem.duration); } } -(void)updatePlayBtn { if([[FFSingleObject sharedInstance] achiveStringWithWeb:self.entity.file]) { self.playButton.hidden = NO; self.photoImageView.hidden = YES; [self.playButton setImage:[UIImage imageNamed:@"播放"] forState:UIControlStateNormal]; // [self.photoImageView sd_setImageWithURL:[NSURL URLWithString:self.entity.pic]]; } else { self.playButton.hidden = YES; self.photoImageView.hidden = YES; } } - (UIImageView *)photoImageView { if(!_photoImageView) { _photoImageView = [self createImageView]; [_photoImageView.layer setMasksToBounds:YES]; _photoImageView.contentMode = UIViewContentModeScaleAspectFill;//等比缩放图片把整个ImageView填充满,所以可能会出现图片部分显示不出来 _photoImageView.hidden = YES; _photoImageView.backgroundColor = [UIColor whiteColor]; _photoImageView.userInteractionEnabled = YES; } return _photoImageView; } - (UIButton *)playButton { if (!_playButton) { _playButton = [[UIButton alloc] init]; [_playButton setTitle:@"" forState:UIControlStateNormal]; [_playButton setImage:[UIImage imageNamed:@"播放"] forState:UIControlStateNormal]; _playButton.backgroundColor = [UIColor clearColor]; _playButton.userInteractionEnabled = YES; _playButton.hidden = YES; @weakify(self); [[_playButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) { @strongify(self); if(self.isPlay) { [self hiddenPlayer]; } else { [self.playButton setImage:[UIImage imageNamed:@"暂停"] forState:UIControlStateNormal]; self.isPlay = YES; self.photoImageView.hidden = NO; self.playButton.hidden = NO; if([[FFSingleObject sharedInstance] achiveStringWithWeb:self.entity.pic]) { [self.photoImageView sd_setImageWithURL:[NSURL URLWithString:self.entity.pic]]; } //网络视频路径 NSString *webVideoPath = self.entity.file;//@"http://api.junqingguanchashi.net/yunpan/bd/c.php?vid=/junqing/1129.mp4"; NSURL *webVideoUrl = [NSURL URLWithString:webVideoPath]; AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:webVideoUrl]; self.currentPlayerItem = playerItem; self.player = [[AVPlayer alloc] initWithPlayerItem:playerItem]; AVPlayerLayer *avLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; avLayer.videoGravity = AVLayerVideoGravityResizeAspect; avLayer.frame = self.photoImageView.bounds; [self.photoImageView.layer addSublayer:avLayer]; //1.注册观察者,监测播放器属性 //观察Status属性,可以在加载成功之后得到视频的长度 [self.player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil]; //观察loadedTimeRanges,可以获取缓存进度,实现缓冲进度条 [self.player.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil]; } }]; } return _playButton; }
页面离开处理:
-(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:NO]; [self.view endEditing:YES]; [self.collectionView.refreshView endAnimating]; [self.chooseSongHeadView hiddenPlayer]; }
点击按钮进行播放和暂停,进入后台停止播放:
@weakify(self); self.imagesScrollView.displayBlock = ^(JCTBannerEntity *entity) { @strongify(self); self.entity = entity; if(!self.isPlay) { [self updatePlayBtn]; } }; [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIApplicationDidEnterBackgroundNotification object:nil] subscribeNext:^(id x) { @strongify(self); [self hiddenPlayer]; }];