本来有AVPlayer和MPPlayerviewcontrller的。后者现在被弃用了,所以就用AVplayerviewcontrller原生的开发
#import@interface ViewController : UIViewController @property(nonatomic,retain)AVPlayerViewController * avc; @property(nonatomic,retain)avplayerSetView * setview; @interface ViewController () { AVPlayer * player; CGFloat _viewLength; float currenttime; BOOL isFullscreen; NSURL * videlurl; } @property(nonatomic,retain)AVPlayerItem * playItem; @end 首先。上面有一个setview,这个是我用来放置AVplayerviewcontrller的view,相当于替代他的AVplaylayer,这个setview里面用懒加载写了一个UIprogressview和UIslider,两个label和一个uibutton, ![左边的button是暂停按钮,靠右的是progress和UIslider用来显示网络加载视频的缓冲进度和滑动条,两个label用来显示当前播放时间和总时长](http://img.blog.csdn.net/20160808174043119) 首先,要定义好avplayer这个播放器的显示范围,他是由AVplayerviewcontrller实例化生成的,那么对应的他就有自己的view,我们让这个view=自己写的view就可以了,还有当屏幕旋转时要设置好setview的各个控件的方向大小,别弄错了就行, 这里关于setview的控件初始化懒加载部分我就不写了,直接来主要的 -(void)initSomething{ [self.avc.view setFrame:CGRectMake(0, 0, self.view.bounds.size.width, 300)]; [self.setview setFrame:self.avc.view.frame]; [self.avc.view addSubview:self.setview]; [self.setview.progress addTarget:self action:@selector(changeprogress:) forControlEvents:UIControlEventValueChanged]; [self.setview.pause addTarget:self action:@selector(pausevideo:) forControlEvents:UIControlEventTouchUpInside]; videlurl=[NSURL URLWithString:@"http://ys-l.ys168.com/566310237/ULVJgkn3K3N1K75HGO5L/music.mp4"]; NSString * url1=[[NSBundle mainBundle]pathForResource:@"duanpian" ofType:@"mp4"]; //确定视频资源 一个视频用一个item self.playItem=[AVPlayerItem playerItemWithURL:[NSURL videlurl]]; //确定视频视频框架 player = [AVPlayer playerWithPlayerItem: self.playItem]; [self addObserver]; self.avc.player=player; // 隐藏系统自带的进度条播放界面 self.avc.showsPlaybackControls = NO; [self.view addSubview:self.avc.view]; player.externalPlaybackVideoGravity=AVLayerVideoGravityResizeAspectFill; } -(void)addObserver{ //获取视频信息,要用item添加kvo,编程的时候最好使用item 的status,会准确点。 [ self.playItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil]; [self.playItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil]; } -(void)removeVideokvo{ [self.playItem removeObserver:self forKeyPath:@"status"]; [self.playItem removeObserver:self forKeyPath:@"loadedTimeRanges"]; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if ([keyPath isEqualToString:@"status"]) { switch (self.playItem.status) { case AVPlayerItemStatusReadyToPlay: { //视频总长度 _viewLength=self.playItem.duration.value*1/ self.playItem.duration.timescale; // 设置播放进度UI [self showPlayeritemInformation:self.playItem]; [player play]; } break; case AVPlayerItemStatusFailed: break; default: break; } } if ([keyPath isEqualToString:@"loadedTimeRanges"]) { if (videlurl) { NSTimeInterval timeInterval = [self availableDuration];// 计算缓冲进度 NSLog(@"Time Interval:%f",timeInterval); CMTime duration = self.playItem.duration; CGFloat totalDuration = CMTimeGetSeconds(duration); self.setview.schedule.trackTintColor=[UIColor grayColor]; self.setview.schedule.progress=timeInterval/totalDuration; } } } -(void)showPlayeritemInformation:(AVPlayerItem *)item{ __weak typeof(self) weakSelf = self; //设置检查频率,1s更新一次这个block CMTime time = CMTimeMake(1.0, 1.0); [self.avc.player addPeriodicTimeObserverForInterval:time queue:dispatch_get_main_queue() usingBlock:^(CMTime time) { //当前播放时间 currenttime =item.currentTime.value/item.currentTime.timescale; weakSelf.setview.progress.value=currenttime/_viewLength; //显示时间的俩label weakSelf.setview.goForward.text=[NSString stringWithFormat:@"%@",[weakSelf getVideoLengthFromTimeLength:item.duration.value*1/ item.duration.timescale]]; weakSelf.setview.backForward.text=[NSString stringWithFormat:@"%@",[weakSelf getStringFromCMTime:item.currentTime.value/item.currentTime.timescale]]; }]; } -(void)changeprogress:(UISlider *)sender{ CGFloat currt= sender.value * _viewLength; [self.avc.player seekToTime:CMTimeMake(currt, 1)]; } //点击按钮暂停播放,再点击继续播放 bool ispause=NO; -(void)pausevideo:(UIButton *)sender{ ispause=!ispause; if (ispause) { [self.avc.player pause]; }else{ [self.avc.player play]; } } #pragma mark 工具方法 //计算缓冲进度 - (NSTimeInterval)availableDuration { NSArray *loadedTimeRanges = [[self.avc.player currentItem] loadedTimeRanges]; CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域 float startSeconds = CMTimeGetSeconds(timeRange.start); float durationSeconds = CMTimeGetSeconds(timeRange.duration); NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度 return result; } //将当前进度转换成分秒 - (NSString *)getStringFromCMTime:(CGFloat)time { // float currentTimeValue = (CGFloat)time.value/time.timescale;//得到当前的播放时 NSDate * currentDate = [NSDate dateWithTimeIntervalSince1970:time]; NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; NSInteger unitFlags = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond ; NSDateComponents *components = [calendar components:unitFlags fromDate:currentDate]; if (time >= 3600 ) { return [NSString stringWithFormat:@"%02ld:%02ld:%02ld",components.hour,components.minute,components.second]; } else { return [NSString stringWithFormat:@"%02ld:%02ld",components.minute,components.second]; }} //将总时长转换成时分秒 - (NSString *)getVideoLengthFromTimeLength:(float)timeLength { NSDate * date = [NSDate dateWithTimeIntervalSince1970:timeLength]; NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; NSInteger unitFlags = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond ; NSDateComponents *components = [calendar components:unitFlags fromDate:date]; if (timeLength >= 3600 ) { return [NSString stringWithFormat:@"%02ld时:%02ld分:%02ld秒",components.hour,components.minute,components.second]; } else { return [NSString stringWithFormat:@"%02ld分:%02ld秒",components.minute,components.second]; } } //判断设备是否支持旋转 -(void)lisenDeviceRotated{ [[UIDevice currentDevice]beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(onDeviceOrientationChange) name:UIDeviceOrientationDidChangeNotification object:nil]; } - (void)onDeviceOrientationChange { UIDeviceOrientation oriention = [UIDevice currentDevice].orientation; UIInterfaceOrientation interfaceOriention = (UIInterfaceOrientation)oriention; switch (interfaceOriention) { case UIInterfaceOrientationUnknown: NSLog(@"位置方向"); break; case UIInterfaceOrientationPortrait: NSLog(@"第0个旋转方向---电池栏在上"); [self backOrientationPortrait]; break; case UIInterfaceOrientationPortraitUpsideDown: NSLog(@"第3个旋转方向---电池栏在下"); [self backOrientationPortrait]; break; case UIInterfaceOrientationLandscapeLeft: [self setDeviceOrientationLandscapeLeft]; NSLog(@"第2个旋转方向---电池栏在右"); break; case UIInterfaceOrientationLandscapeRight: [self setDeviceOrientationLandscapeRight]; NSLog(@"第1个旋转方向---电池栏在左"); break; default: break; } } //隐藏navigation tabbar 电池栏 -(BOOL)prefersStatusBarHidden{ return YES; } //返回小屏幕 -(void)backOrientationPortrait{ [UIView animateWithDuration:.5f animations:^{ [self.avc.view setFrame:CGRectMake(0, 0, self.view.bounds.size.width, 300)]; [self.setview setFrame:self.avc.view.frame]; [self.avc.view setTransform:CGAffineTransformIdentity]; }completion:^(BOOL finished) { }]; } -(void)setDeviceOrientationLandscapeRight{ //全屏(横屏frame计算) CGFloat height = [[UIScreen mainScreen] bounds].size.width; CGFloat width = [[UIScreen mainScreen] bounds].size.height; CGRect frame = CGRectMake(0, 0, height, width); [UIView animateWithDuration:0.3f animations:^{ self.avc.view.frame = frame; self.setview.frame=frame; // [self.avc.view setTransform:CGAffineTransformMakeRotation(M_PI)]; } completion:^(BOOL finished) { }]; } - (void)setDeviceOrientationLandscapeLeft { //全屏(横屏frame计算) CGFloat height = [[UIScreen mainScreen] bounds].size.width; CGFloat width = [[UIScreen mainScreen] bounds].size.height; CGRect frame = CGRectMake(0, 0, height, width); [UIView animateWithDuration:0.3f animations:^{ self.avc.view.frame = frame; self.setview.frame=frame; // [self.avc.view setTransform:CGAffineTransformMakeRotation(-M_PI)]; } completion:^(BOOL finished) { }]; } 到这里 就可以播放了,没怎么太完善功能,只是初学用的,其中[self.avc.player addPeriodicTimeObserverForInterval:time queue:dispatch_get_main_queue() usingBlock:^(CMTime time) { //当前播放时间 currenttime =item.currentTime.value/item.currentTime.timescale; weakSelf.setview.progress.value=currenttime/_viewLength; //显示时间的俩label weakSelf.setview.goForward.text=[NSString stringWithFormat:@"%@",[weakSelf getVideoLengthFromTimeLength:item.duration.value*1/ item.duration.timescale]]; weakSelf.setview.backForward.text=[NSString stringWithFormat:@"%@",[weakSelf getStringFromCMTime:item.currentTime.value/item.currentTime.timescale]]; }]; 这个点我觉得是重要的,cmtimemake(1,1)指的是1/1这个时间走一次block。