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