代碼地址以下:
http://www.demodashi.com/demo/11168.htmlhtml
//建立播放器 url = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; AVPlayer *player = [AVPlayer playerWithURL:[NSURL URLWithString:url]]; self.avPlayer = player;
- (void)createDisplay{ // 顯示圖像的 _videoLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer]; //錨點的座標 _videoLayer.position = CGPointMake(KPLAYVIEWWIDTH/2, KPLAYVIEWHEIGHT/2); _videoLayer.bounds = CGRectMake(0, 0, KPLAYVIEWWIDTH, KPLAYVIEWHEIGHT); // 錨點,值只能是0,1之間 _videoLayer.anchorPoint = CGPointMake(0.5, 0.5); // AVLayerVideoGravityResizeAspect 按比例壓縮,視頻不會超出Layer的範圍(默認) // AVLayerVideoGravityResizeAspectFill 按比例填充Layer,不會有黑邊 // AVLayerVideoGravityResize 填充整個Layer,視頻會變形 // 視頻內容拉伸的選項 _videoLayer.videoGravity = AVLayerVideoGravityResizeAspect; // //播放時,視頻實際佔的區域 // NSLog(@"%@", NSStringFromCGRect(videoLayer.videoRect)); //Layer只能添加到Layer上面 [self.displayView.layer addSublayer:_videoLayer]; }
主要代碼以下:網絡
//監測屏幕旋轉 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; //添加AVPlayerItem播放結束通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.avPlayer.currentItem]; //添加AVPlayerItem開始緩衝通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bufferStart:) name:AVPlayerItemPlaybackStalledNotification object:self.avPlayer.currentItem]; //KOV監控 播放器進度更新 - (void)addObserverForAVPlayer { AVPlayerItem *playerItem = self.avPlayer.currentItem; // 給AVPlayer添加觀察者 必須實現 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context; //監控播放速率 [self.avPlayer addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:nil]; //監控狀態屬性(AVPlayer也有一個status屬性,經過監控它的status也能夠得到播放狀態) [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; //監控網絡加載緩衝狀況屬性 [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil]; //監控是否可播放 [playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil]; //播放進度觀察者 //設置每0.1秒執行一次 __weak GOVVideoView *weakSelf = self; _playerTimeObserver = [self.avPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 10.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) { if (weakSelf.dragSlider) { return ; } CGFloat current = CMTimeGetSeconds(time); weakSelf.current = current; CMTime totalTime = weakSelf.avPlayer.currentItem.duration; CGFloat total = CMTimeGetSeconds(totalTime); weakSelf.total = total; weakSelf.slider.value = current/total; weakSelf.currentTimeLabel.text = [weakSelf timeFormatted:current]; weakSelf.totalTimeLabel.text = [NSString stringWithFormat:@"/%@",[weakSelf timeFormatted:total]] ; }]; } //經過KVO監控回調 //keyPath 監控屬性 object 監視器 change 狀態改變 context 上下文 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ if ([keyPath isEqualToString:@"loadedTimeRanges"]) { //監控網絡加載狀況屬性 NSArray *array = self.avPlayer.currentItem.loadedTimeRanges; //本次緩衝時間範圍 CMTimeRange timeRange = [array.firstObject CMTimeRangeValue]; CGFloat startSeconds = CMTimeGetSeconds(timeRange.start); CGFloat durationSeconds = CMTimeGetSeconds(timeRange.duration); //現有緩衝總長度 CGFloat totalBuffer = startSeconds + durationSeconds; //視頻總時長 CMTime totalTime = self.avPlayer.currentItem.duration; CGFloat total = CMTimeGetSeconds(totalTime); if (totalBuffer/total <= 1.0 ) { [self.progressView setProgress:totalBuffer/total animated:YES]; } }else if([keyPath isEqualToString:@"playbackLikelyToKeepUp"]){ if (self.avPlayer.currentItem.playbackLikelyToKeepUp == YES) { if (_activityView != nil) { [self.activityView startAnimating]; [self.activityView removeFromSuperview]; _activityView = nil; } } }else if ([keyPath isEqualToString:@"status"]){ //監控狀態屬性 AVPlayerStatus status = [[change objectForKey:@"new"] intValue]; switch ((status)) { case AVPlayerStatusReadyToPlay: break; case AVPlayerStatusUnknown: break; case AVPlayerStatusFailed: break; } }else if ([keyPath isEqualToString:@"rate"]){ if (self.avPlayer.rate == 1) { } } }
隱藏/顯示狀態欄的方法:
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];這個方法在iOS9以後棄用了,而且須要
將View controller-based status bar appearance設置爲NO;而下面的重寫方法須要將View controller-based status bar appearance設置爲YES,這個方法在iOS7以後就有了;
//刷新狀態欄狀態
[self setNeedsStatusBarAppearanceUpdate];app
#pragma mark -- 隱藏/顯示狀態欄的方法 /*[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];這個方法在iOS9以後棄用了,而且須要 將View controller-based status bar appearance設置爲NO;而下面的重寫方法須要將View controller-based status bar appearance設置爲YES,這個方法在iOS7以後就有了; //刷新狀態欄狀態 [self setNeedsStatusBarAppearanceUpdate]; */ //設置樣式 - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; } //設置是否隱藏 - (BOOL)prefersStatusBarHidden { return self.isHiddenStatusBar; } //設置隱藏動畫 - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation { return UIStatusBarAnimationNone; }
//Block回調方法 typedef void(^FullScreenBlock)(BOOL isFull); typedef void(^ClosePLayerBlock)(); typedef void(^ShowBarBlock)(BOOL isShow); typedef void(^PlayFinishedBlock)(); @class GOVVideoPlayer; //代理方法 @protocol GOVVideoPlayerDelegate <NSObject> //播放結束 - (void)videoPlayerPlayFinished:(GOVVideoPlayer *)videoPlayer; //關閉播放器 - (void)videoPlayerClosePlayer:(GOVVideoPlayer *)videoPlayer; //全屏按鈕 - (void)videoPlayerFullScreen:(GOVVideoPlayer *)videoPlayer withIsFull:(BOOL)isFull; //隱藏/展現footBar和topBar - (void)videoPlayerShowBar:(GOVVideoPlayer *)videoPlayer withIsShow:(BOOL)isShow;
GOVVideoPlayer是在繼承於UIView的基礎上封裝的視頻View;
GOVVideoController是在繼承於UIViewController的基礎上封裝的視頻視圖控制器。
二者最大的不一樣是在全屏和取消全屏的處理上面:前者是一個視圖View,能夠直接加在父視圖上面,全屏時是加在 [UIApplication sharedApplication].keyWindow上的,然後者,小屏時是取GOVVideoController的View加在父視圖上,全屏和取消全屏時是採用present和dismiss模態化轉場的方法 。ide
iOS AVPlayer視頻播放器動畫
代碼地址以下:
http://www.demodashi.com/demo/11168.htmlurl
注:本文著做權歸做者,由demo大師代發,拒絕轉載,轉載須要做者受權spa