AVPlayerDemo(視頻播放器)

這是Xib的圖,不知道怎麼直接傳工程,知道的朋友能夠說一下,我就直接發工程了,僅供參考



#import "PlayerViewController.h" #import <AVFoundation/AVFoundation.h> @interface PlayerViewController () { BOOL falg; BOOL falg1; AVPlayerLayer *playerLayer; NSString *URLString; UIImageView *media_starImageView; NSString *filePath; NSURL *url; NSString *urlStr; NSArray *arr1; unsigned int i; } @property (nonatomic,strong) AVPlayer *player;//播放器對象 @property (weak, nonatomic) IBOutlet UIView *container; //播放器容器 @property (weak, nonatomic) IBOutlet UIButton *playOrPause; //播放/暫停按鈕 @property (weak, nonatomic) IBOutlet UIButton *nextButton;//下一集按鈕 @property (strong, nonatomic) IBOutlet UISlider *slider;//滑塊調整播放進度 @property (weak, nonatomic) IBOutlet UIButton *fullButton;//全屏按鈕 @property (weak, nonatomic) IBOutlet UILabel *leftLabel; @property (weak, nonatomic) IBOutlet UILabel *rightLabel; @end @implementation PlayerViewController #pragma mark - 控制器視圖方法 - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"視頻播放器"; //初始化視頻數組(在線播放) arr1 = @[@"http://123.134.67.201:80/play/BEDF14F6FF4FF604DCCB053EEE20536EB33EFC37.mp4", @"http://221.204.189.54:80/play/0F7758AF15BD3895E07E360C34B95AB42E631487.mp4", @"http://123.134.67.198:80/play/BFD75E46DE50B2D8BBD810F259B2CC892DE9F690.mp4", @"http://123.134.67.197:80/play/4B07614CBE84228E2645AC9F14C4BABFC5E6F0E1.mp4", @"http://58.244.255.12/play/82846AEB3B80981E4A674374C05B3F771144D3AF/1074654_smooth.mp4"]; i = 0; //初始化容器 self.container.frame = CGRectMake(0, 64, self.view.bounds.size.width, self.view.bounds.size.width); falg = YES; falg1 = YES; [self.playOrPause setImage:[UIImage imageNamed:@"pui_pausebtn_b_disable@2x"] forState:UIControlStateNormal]; //建立播放器層 [self setupUI]; //播放 [self.player play]; //將底部進度條等視圖提早,否則會被播放內容覆蓋掉 [self.container bringSubviewToFront:_playOrPause]; [self.container bringSubviewToFront:_nextButton]; [self.container bringSubviewToFront:_leftLabel]; [self.container bringSubviewToFront:_slider]; [self.container bringSubviewToFront:_rightLabel]; [self.container bringSubviewToFront:_fullButton]; } -(void)dealloc{ [self removeObserverFromPlayerItem:self.player.currentItem]; [self removeNotification]; } #pragma mark - 私有方法 -(void)setupUI{ //建立播放器層 playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; playerLayer.frame = self.container.bounds; playerLayer.videoGravity = AVLayerVideoGravityResize;//視頻填充模式 [self.container.layer addSublayer:playerLayer]; } /** * 截取指定時間的視頻縮略圖 * * @param timeBySecond 時間點 */ /** * 初始化播放器 * * @return 播放器對象 */ //初始化播放器 -(AVPlayer *)player{ if (!_player) { AVPlayerItem *playerItem=[self getPlayItem:0]; _player=[AVPlayer playerWithPlayerItem:playerItem]; //給播放器添加進度更新 [self addProgressObserver]; //給AVPlayerItem添加監控 [self addObserverToPlayerItem:playerItem]; } return _player; } /** * 根據視頻索引取得AVPlayerItem對象 * * @param videoIndex 視頻順序索引 * * @return AVPlayerItem對象 */ -(AVPlayerItem *)getPlayItem:(int)videoIndex{ #warning 爲了節約體積,本地視頻沒有上傳,本身找mp4格式的本地視頻 //本地播放 // NSString *file = [[NSBundle mainBundle] pathForResource:@"火影忍者65" ofType:@"mp4"]; // NSURL *url = [NSURL fileURLWithPath:file]; //在線播放 urlStr=[NSString stringWithFormat:@"http://123.134.67.201:80/play/BEDF14F6FF4FF604DCCB053EEE20536EB33EFC37.mp4"]; url=[NSURL URLWithString:urlStr]; AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:url]; return playerItem; } #pragma mark - 通知 /** * 添加播放器通知 */ -(void)addNotification{ //給AVPlayerItem添加播放完成通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem]; } //移除本地通知 -(void)removeNotification{ [[NSNotificationCenter defaultCenter] removeObserver:self]; } /** * 播放完成通知 * * @param notification 通知對象 */ -(void)playbackFinished:(NSNotification *)notification{ NSLog(@"視頻播放完成."); } #pragma mark - 監控 /** * 給播放器添加進度更新 */ -(void)addProgressObserver{ AVPlayerItem *playerItem = self.player.currentItem; UISlider *slider = self.slider; [slider addTarget:self action:@selector(changeValue:) forControlEvents:UIControlEventValueChanged]; __weak PlayerViewController *blockSelf = self; //這裏設置每秒執行一次 [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) { //當前時間(秒) float current=CMTimeGetSeconds(time); //總時間(秒) float total=CMTimeGetSeconds([playerItem duration]); [blockSelf leftLabel:[blockSelf convertTime:current]]; NSLog(@"當前播放時長%@", [blockSelf convertTime:current]); if (current) { [slider setValue:(current/total) animated:YES]; } }]; } - (void)changeValue:(UISlider *)aSlider { AVPlayerItem *playerItem = self.player.currentItem; //從當前位置播放 [self.player seekToTime:CMTimeMakeWithSeconds(aSlider.value * CMTimeGetSeconds([playerItem duration]), 1)]; //機智的暫停,防止形成拖動時進度條卡頓的尷尬(由於AVPlayer這個拖動後會暫停,不會自動播放) [self.player pause]; [self.playOrPause setImage:[UIImage imageNamed:@"pui_playbtn_b_disable@2x"] forState:UIControlStateNormal]; } //計算時間,返回字符串 - (NSString *)convertTime:(CGFloat)second{ NSDate *d = [NSDate dateWithTimeIntervalSince1970:second]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; if (second/3600 >= 1) { [formatter setDateFormat:@"01:mm:ss"]; } else { [formatter setDateFormat:@"mm:ss"]; } NSString *showtimeNew = [formatter stringFromDate:d]; return showtimeNew; } /** * 給AVPlayerItem添加監控 * * @param playerItem AVPlayerItem對象 */ -(void)addObserverToPlayerItem:(AVPlayerItem *)playerItem{ //監控狀態屬性,注意AVPlayer也有一個status屬性,經過監控它的status也能夠得到播放狀態 [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil]; //監控網絡加載狀況屬性 [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil]; } -(void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem{ [playerItem removeObserver:self forKeyPath:@"status"]; [playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"]; } /** * 經過KVO監控播放器狀態 * * @param keyPath 監控屬性 * @param object 監視器 * @param change 狀態改變 * @param context 上下文 */ //經過KVO監控播放器狀態 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ AVPlayerItem *playerItem=object; __weak PlayerViewController *blockSelf = self; if ([keyPath isEqualToString:@"status"]) { AVPlayerStatus status= [[change objectForKey:@"new"] intValue]; if(status==AVPlayerStatusReadyToPlay){ [blockSelf rightLabel:[blockSelf convertTime:CMTimeGetSeconds(playerItem.duration)]]; NSLog(@"視頻總時長%@", [blockSelf convertTime:CMTimeGetSeconds(playerItem.duration)]); } }else if([keyPath isEqualToString:@"loadedTimeRanges"]){ NSArray *array=playerItem.loadedTimeRanges; CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次緩衝時間範圍 float startSeconds = CMTimeGetSeconds(timeRange.start); float durationSeconds = CMTimeGetSeconds(timeRange.duration); NSTimeInterval totalBuffer = startSeconds + durationSeconds;//緩衝總長度 NSLog(@"視頻共緩衝時長%@", [blockSelf convertTime:totalBuffer]); } } - (void)leftLabel:(NSString *)leftLabelText { _leftLabel.text = leftLabelText; } - (void)rightLabel:(NSString *)rightLabelText { _rightLabel.text = rightLabelText; } #pragma mark - UI事件 /** * 點擊播放/暫停按鈕 * * @param sender 播放/暫停按鈕 */ - (IBAction)playClick:(UIButton *)sender { if(self.player.rate==0){ //說明時暫停 [sender setImage:[UIImage imageNamed:@"pui_pausebtn_b_disable@2x"] forState:UIControlStateNormal]; [self.player play]; }else if(self.player.rate==1){//正在播放 [self.player pause]; [sender setImage:[UIImage imageNamed:@"pui_playbtn_b_disable@2x"] forState:UIControlStateNormal]; } } //關閉自動旋轉 - (BOOL)shouldAutorotate{ return NO; } //全屏或退出Button - (IBAction)fullOrExit:(UIButton *)sender { if (falg) { [sender setImage:[UIImage imageNamed:@"pui_zoomoutbtn@2x"] forState:UIControlStateNormal]; falg = !falg; self.container.frame = CGRectMake(0, 0, self.view.bounds.size.height, self.view.bounds.size.width); playerLayer.frame = self.container.bounds; [self.view bringSubviewToFront:self.container]; // playerLayer.videoGravity = AVLayerVideoGravityResize;//視頻填充模式 //旋轉屏幕,可是隻旋轉當前的View [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight]; self.view.transform = CGAffineTransformMakeRotation(M_PI/2); CGRect frame = [UIScreen mainScreen].applicationFrame; self.view.bounds = CGRectMake(0, 64, frame.size.height, frame.size.width); //隱藏導航欄 [[self navigationController] setNavigationBarHidden:YES animated:YES]; } else { [sender setImage:[UIImage imageNamed:@"pui_zoominbtn@2x"] forState:UIControlStateNormal]; falg = !falg; self.container.frame = CGRectMake(0, 0, self.view.bounds.size.height, self.view.bounds.size.height); playerLayer.frame = self.container.bounds; [self.view bringSubviewToFront:self.container]; //旋轉屏幕,可是隻旋轉當前的View [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft]; self.view.transform = CGAffineTransformMakeRotation(M_PI*2); CGRect frame = [UIScreen mainScreen].applicationFrame; self.view.bounds = CGRectMake(0, 0, frame.size.height, frame.size.width); //顯示導航欄 [[self navigationController] setNavigationBarHidden:NO animated:YES]; } } //下一個視頻Button - (IBAction)nextButton:(UIButton *)sender { i++; [self removeNotification]; if (i == arr1.count) { i = 0; } urlStr=[NSString stringWithFormat:arr1[i]]; url=[NSURL URLWithString:urlStr]; AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:url]; [self.player replaceCurrentItemWithPlayerItem:playerItem]; [self addNotification]; } //點擊隱藏或者出現播放進度控制欄 - (IBAction)tapPlayer:(id)sender { if (falg1) { falg1 = !falg1; _playOrPause.hidden = YES; _nextButton.hidden = YES; _slider.hidden = YES; _fullButton.hidden = YES; _leftLabel.hidden = YES; _rightLabel.hidden = YES; } else { falg1 = !falg1; _playOrPause.hidden = NO; _nextButton.hidden = NO; _slider.hidden = NO; _fullButton.hidden = NO; _leftLabel.hidden = NO; _rightLabel.hidden = NO; } }

下面上傳圖片,只是解壓別的軟件裏面的圖片,也不知道上傳了能不能下載下來,png的傳不上去,就轉成jpg的了。


github主頁:https://github.com/ShaoWenLe
相關文章
相關標籤/搜索