iOS中使用AVPLayer自定义视频播放器
必须知道:
AVPlayer本身无法播放视频,必须要把视频加到AVPlayerLayer中,才能显示。
个人感觉:必须要用到2个KVO,1个定时器,一个通知。
//观察playerItem的状态变化
/**观察playerItem的播放状态
* AVPlayerItemStatusUnknown,播放源未知
* AVPlayerItemStatusReadyToPlay,播放源已经准备好
* AVPlayerItemStatusFailed播放源失败
*/
[self.playerItemaddObserver:selfforKeyPath:@"status"options:NSKeyValueObservingOptionNewcontext:nil];
//加载缓存
[self.playerItemaddObserver:selfforKeyPath:@"loadedTimeRanges"options:NSKeyValueObservingOptionNewcontext:nil];
//添加定时器,更新当前的播放进度
[self.playeraddPeriodicTimeObserverForInterval:CMTimeMake(1.0,1.0)queue:dispatch_get_main_queue()usingBlock:^(CMTimetime) {
}];
//播放完成通知
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(playbackFinished:)name:AVPlayerItemDidPlayToEndTimeNotificationobject:nil];
用法:
前瞻:控件说明
@property(nonatomic,strong)UIView*viewContainer;//最底层的视图,把所有的播放视图都放在它的上面
@property(nonatomic,strong)UIView*viewPlay;//播放视图
@property(nonatomic,strong)UIView*viewBack;//返回视图
@property(nonatomic,strong)UIButton*buttonPlay;//播放按钮
@property(nonatomic,strong)UIProgressView*progress;//缓存进度
@property(nonatomic,strong)UISlider*slider;//播放进度
@property(nonatomic,strong)UILabel*labelTime;//视频的时间
@property(nonatomic,strong)AVPlayer*player;//播放器对象
@property(nonatomic,strong)AVPlayerItem*playerItem;// item
@property(nonatomic,assign)CGFloattotalMovieDuration;//当前视频的总时长
1.创建AVPlayerLayer,必须把视频添加到AVPlayerLayer层,才能播放
//创建播放器层
AVPlayerLayer*playerLayer=[AVPlayerLayerplayerLayerWithPlayer:self.player];
playerLayer.frame=CGRectMake(0,0,kWidth,kHeight);
playerLayer.videoGravity=AVLayerVideoGravityResize;
[self.view.layeraddSublayer:playerLayer];
2. 创建一个透明的View,用于创建播放器的播放视图,把所有的按钮控件,都放在它上边
self.viewContainer= [[UIViewalloc]initWithFrame:CGRectMake(0,0,kWidth,kHeight)];
self.viewContainer.backgroundColor= [UIColorclearColor];
[self.viewaddSubview:self.viewContainer];
UITapGestureRecognizer*tap = [[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(handlePresent:)];
[self.viewContaineraddGestureRecognizer:tap];
3. 创建播放器的播放视图和播放器的返回视图,以及上面的各个子控件
//创建播放视图和播放返回视图
self.viewPlay= [[UIViewalloc]initWithFrame:CGRectMake(0,kHeight-40,kWidth,kHeight)];
self.viewPlay.backgroundColor= [UIColorclearColor];
[self.viewContaineraddSubview:self.viewPlay];
self.viewBack= [[UIViewalloc]initWithFrame:CGRectMake(0,0,kWidth,kHeight)];
self.viewPlay.backgroundColor= [UIColorclearColor];
[self.viewContaineraddSubview:self.viewPlay];
//播放暂停按钮事件
self.buttonPlay= [UIButtonbuttonWithType:UIButtonTypeCustom];
self.buttonPlay.frame=CGRectMake(10,0,40,40);
[self.buttonPlaysetBackgroundImage:[UIImageimageNamed:@"iconfont-bofang"]forState:UIControlStateNormal];//暂停
[self.buttonPlaysetBackgroundImage:[UIImageimageNamed:@"iconfont-bofang1"]forState:UIControlStateSelected];//播放
self.buttonPlay.layer.masksToBounds=YES;
self.buttonPlay.layer.cornerRadius=20;
self.buttonPlay.selected=YES;//默认为播放
[self.viewPlayaddSubview:self.buttonPlay];
[self.buttonPlayaddTarget:selfaction:@selector(handlePlay:)forControlEvents:UIControlEventTouchUpInside];
//进度条按钮
self.progress= [[UIProgressViewalloc]initWithFrame:CGRectMake(82,20,550-5,10)];
self.progress.progress=0;
self.progress.progressTintColor= [UIColorcolorWithRed:1.000green:0.599blue:0.345alpha:1.000];
[self.viewPlayaddSubview:self.progress];
// slider滑条事件
self.slider= [[UISlideralloc]initWithFrame:CGRectMake(80,16,550,10)];
self.slider.minimumValue=0;
self.slider.maximumValue=0;
self.slider.maximumTrackTintColor= [UIColorclearColor];
[self.slidersetThumbImage:[UIImageimageNamed:@"iconfont-yuan"]forState:UIControlStateNormal];
[self.viewPlayaddSubview:self.slider];
[self.slideraddTarget:selfaction:@selector(handleSlider:)forControlEvents:UIControlEventValueChanged];
// labelTime显示
self.labelTime= [[UILabelalloc]initWithFrame:CGRectMake(640,5,60,30)];
self.labelTime.textColor= [UIColorwhiteColor];
self.labelTime.text=@"Time";
[self.viewPlayaddSubview:self.labelTime];
4.创建player和playerItem对象
#pragma mark -懒加载,创建播放器对象
- (AVPlayer*)player{
if(!_player) {
_player=[AVPlayerplayerWithPlayerItem:self.playerItem];
//添加定时器,更新slider的进度
[selfrefreshSliderPlan];
//给AVPlayerItem添加播放完成通知
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(playbackFinished:)name:AVPlayerItemDidPlayToEndTimeNotificationobject:nil];
}
return_player;
}
#pragma mark -懒加载,创建AVPlayerItem对象
- (AVPlayerItem*)playerItem
{
if(!_playerItem) {
NSURL*url=[NSURLURLWithString:@"http://v.jxvdy.com/sendfile/w5bgP3A8JgiQQo5l0hvoNGE2H16WbN09X-ONHPq3P3C1BISgf7C-qVs6_c8oaw3zKScO78I--b0BGFBRxlpw13sf2e54QA"];
self.playerItem= [AVPlayerItemplayerItemWithURL:url];
//观察playerItem的状态变化
[self.playerItemaddObserver:selfforKeyPath:@"status"options:NSKeyValueObservingOptionNewcontext:nil];
//加载缓存
[self.playerItemaddObserver:selfforKeyPath:@"loadedTimeRanges"options:NSKeyValueObservingOptionNewcontext:nil];
}
return_playerItem;
}
5.监控播放器状态
/**
*通过KVO监控播放器状态
*
* @param keyPath监控属性
* @param object监视器
* @param change状态改变
* @param context上下文
*/
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context{
AVPlayerItem*playerItem = object;
/**
* AVPlayerItemStatusUnknown,播放源未知
* AVPlayerItemStatusReadyToPlay,播放源准备好
* AVPlayerItemStatusFailed播放源失败
*/
if([keyPathisEqualToString:@"status"]) {
AVPlayerStatusstatus= [[changeobjectForKey:@"new"]intValue];
if(status ==AVPlayerStatusReadyToPlay){
NSLog(@"正在播放...,视频总长度:%.2f",CMTimeGetSeconds(playerItem.duration));
//计算视频总时间
CMTimetotalTime = playerItem.duration;
self.totalMovieDuration= (CGFloat)totalTime.value/ totalTime.timescale;
//给slider赋值
self.slider.maximumValue=self.totalMovieDuration+1;
//设置按钮状态为播放
self.buttonPlay.selected=YES;
//转化时间的格式
NSDate*d = [NSDatedateWithTimeIntervalSince1970:self.totalMovieDuration];
NSDateFormatter*formatter = [[NSDateFormatteralloc]init];
if(self.totalMovieDuration/3600>=1) {
[formattersetDateFormat:@"HH:mm:ss"];
}else{
[formattersetDateFormat:@"mm:ss"];
}
NSString*showtimeNew = [formatterstringFromDate:d];
//给labelTime赋值
self.labelTime.text= showtimeNew;
}
}elseif([keyPathisEqualToString:@"loadedTimeRanges"]){
NSArray*array = playerItem.loadedTimeRanges;
NSLog(@"array = %@", array);
//本次缓冲时间范围
CMTimeRangetimeRange = [array.firstObjectCMTimeRangeValue];
floatstartSeconds =CMTimeGetSeconds(timeRange.start);
floatdurationSeconds =CMTimeGetSeconds(timeRange.duration);
//缓冲总长度
NSTimeIntervaltotalBuffer = startSeconds + durationSeconds;
NSLog(@"共缓冲:%.2f",totalBuffer);
//更新进度条
[self.progresssetProgress:totalBuffer *1.0/self.totalMovieDuration];
}
}