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];
}];