iOS AVPlayer 使用详解
来源:互联网 发布:凡科微传单软件 编辑:程序博客网 时间:2024/05/04 04:51
http://blog.csdn.net/yuhao111122/article/details/50589434
//// SMAVPlayerViewController.m// AVPlayerDemo//// Created by Yx on 15/11/29.// Copyright © 2015年 WuhanBttenMobileTechnologyCo.,Ltd. All rights reserved.//#import "SMAVPlayerViewController.h"#import <AVFoundation/AVFoundation.h>#import "SMSliderBar.h"#import "MBMessageTip.h"#import "VedioModel.h"#import "VedioHistory.h"#define ScreenHeight [[UIScreen mainScreen] bounds].size.height#define ScreenWidth [[UIScreen mainScreen] bounds].size.width@interface SMAVPlayerViewController ()<SMSliderDelegate>@property (weak, nonatomic) IBOutlet UIView *viewHead; //显示返回按钮View@property (weak, nonatomic) IBOutlet UIView *viewLogin; //加载view@property (weak, nonatomic) IBOutlet UIImageView *imageViewLogin; //加载image@property (weak, nonatomic) IBOutlet UIView *viewAvPlayer; //播放视图@property (weak, nonatomic) IBOutlet SMSliderBar *slider; //进度条@property (weak, nonatomic) IBOutlet UIView *viewBottom; //底部控制view@property (weak, nonatomic) IBOutlet UIButton *btnPause; //暂停播放按钮@property (weak, nonatomic) IBOutlet UIButton *btnNetx; //下一个按钮@property (weak, nonatomic) IBOutlet UILabel *labelTimeNow; //当前时间label@property (weak, nonatomic) IBOutlet UILabel *labelTimeTotal; //总时间label@property (strong, nonatomic) AVPlayer *player; //播放器对象@property (strong, nonatomic) id timeObserver; //视频播放时间观察者@property (assign, nonatomic) float totalTime; //视频总时长@property (assign, nonatomic) BOOL isHasMovie; //是否进行过移动@property (assign, nonatomic) BOOL isBottomViewHide; //底部的view是否隐藏@property (assign, nonatomic) NSInteger subscript; //数组下标,记录当前播放视频@property (assign, nonatomic) NSInteger currentTime; //当前视频播放时间位置@end@implementation SMAVPlayerViewController@synthesize subscript;- (void)viewDidLoad { [super viewDidLoad]; self.slider.type = SMSliderTypeHoz; self.slider.progressBgColor = [UIColor whiteColor]; self.slider.isAllowDrag = YES; self.slider.delegate=self; subscript = 0; self.currentTime = 0; [self prohibitOperation]; [self setMediaPlayer]; [self addPlayerClick];//双击,单击事件 [self addProgressObserver];//进度监听 [self addNotification];//广播监听播放状态 [self setupObservers];//监听应用状态 self.viewLogin.layer.cornerRadius = 8; self.imageViewLogin.layer.masksToBounds = YES; self.imageViewLogin.layer.cornerRadius = 34/2; splashTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(roteImageView) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:splashTimer forMode:NSRunLoopCommonModes];}- (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; [[UIApplication sharedApplication]setStatusBarHidden:YES]; //接受远程控制事件 [[UIApplication sharedApplication]beginReceivingRemoteControlEvents]; [self becomeFirstResponder];}- (void)viewDidDisappear:(BOOL)animated{ [super viewDidDisappear:animated]; [[UIApplication sharedApplication] setStatusBarHidden:NO]; [[UIApplication sharedApplication] endReceivingRemoteControlEvents]; [self resignFirstResponder]; [splashTimer invalidate];}- (void)setMediaPlayer{ //创建播放器层 AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; playerLayer.frame = CGRectMake(0, 0, ScreenHeight ,ScreenWidth ); [self.viewAvPlayer.layer addSublayer:playerLayer]; [self.player seekToTime:CMTimeMakeWithSeconds(self.startTime, 1000)];//设置播放位置1000 为帧率 [_player play];}#pragma mark - set/get- (AVPlayer *)player{ if (!_player) { AVPlayerItem *playerItem = [self getPlayItem:subscript]; [self addObserverToPlayerItem:playerItem]; _player = [AVPlayer playerWithPlayerItem:playerItem]; } return _player;}- (AVPlayerItem *)getPlayItem:(NSUInteger)videoIndex{ /*播放本地视频 NSString *urlStr=[[NSBundle mainBundle] pathForResource:@"testav.mp4" ofType:nil]; NSURL *url=[NSURL fileURLWithPath:urlStr]; AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:url]; return playerItem;*/ //NSString *urlStr= @"http://7xoour.com2.z0.glb.qiniucdn.com/9605401000"; _currentTime = 0; [self savePayHistory]; VedioModel *vedioModel = _arrVedio[videoIndex]; NSString *urlStr =[vedioModel.strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSURL *url=[NSURL URLWithString:urlStr]; /*获取总帧数与帧率 NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:AVURLAssetPreferPreciseDurationAndTimingKey]; AVURLAsset *myAsset = [[AVURLAsset alloc] initWithURL:url options:opts]; CMTimeValue value = myAsset.duration.value;//总帧数 CMTimeScale timeScale = myAsset.duration.timescale; //timescale为帧率 fps */ AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url]; return playerItem;}#pragma mark - 通知//给AVPlayerItem添加播放完成通知- (void)addNotification{ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];}// 播放完成通知- (void)playbackFinished:(NSNotification *)notification{ NSLog(@"视频播放完成."); [self prohibitOperation]; [self savePayHistory]; [self nextClick:nil];}//注册通知- (void)setupObservers{ NSNotificationCenter *notification = [NSNotificationCenter defaultCenter]; [notification addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]]; [notification addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication]];}- (void)applicationDidBecomeActive:(NSNotification *)notification{ if (self.player.rate == 0) { [self.player play]; [self.btnPause setTitle:@"暂停" forState:UIControlStateNormal]; [self.btnPause setBackgroundImage:[UIImage imageNamed:@"play_stop.png"] forState:UIControlStateNormal]; }}- (void)applicationDidEnterBackground:(NSNotification *)notification{ if (self.player.rate == 1){ [self.player pause]; [self.btnPause setTitle:@"播放" forState:UIControlStateNormal]; [self.btnPause setBackgroundImage:[UIImage imageNamed:@"play_start.png"] forState:UIControlStateNormal]; }}- (void)removeNotification{ [[NSNotificationCenter defaultCenter] removeObserver:self];}#pragma mark - KVO- (void)addProgressObserver{ AVPlayerItem *playerItem = self.player.currentItem; //这里设置每秒执行一次 __weak __typeof(self) weakself = self; self.timeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) { float current = CMTimeGetSeconds(time); float total = CMTimeGetSeconds([playerItem duration]); NSLog(@"当前已经播放%f",current); weakself.currentTime = current; if (current) { [weakself setTime:current withTotal:total]; } }];}/** * 给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]; //监听播放的区域缓存是否为空 [playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil]; //缓存可以播放的时候调用 [playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];}- (void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem{ [playerItem removeObserver:self forKeyPath:@"status"]; [playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"]; [playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty"]; [playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];}/** * 通过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; if ([keyPath isEqualToString:@"status"]) { AVPlayerStatus status= [[change objectForKey:@"new"] intValue]; if(status == AVPlayerStatusReadyToPlay){ self.totalTime = CMTimeGetSeconds(playerItem.duration); NSLog(@"开始播放,视频总长度:%.2f",CMTimeGetSeconds(playerItem.duration)); [self.btnPause setTitle:@"暂停" forState:UIControlStateNormal]; [self.btnPause setBackgroundImage:[UIImage imageNamed:@"play_stop.png"] forState:UIControlStateNormal]; [_player play]; [self.viewLogin setHidden:YES]; [self clearProhibitOperation]; }else if(status == AVPlayerStatusUnknown){ NSLog(@"%@",@"AVPlayerStatusUnknown"); }else if (status == AVPlayerStatusFailed){ NSLog(@"%@",@"AVPlayerStatusFailed"); } }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;//缓冲总长度 if (self.currentTime < (startSeconds + durationSeconds + 8)) { self.viewLogin.hidden = YES; if ([self.btnPause.titleLabel.text isEqualToString:@"暂停"]) { [_player play]; } }else{ self.viewLogin.hidden = NO; } self.slider.bufferValue = totalBuffer/self.totalTime; NSLog(@"缓冲:%.2f",totalBuffer); }else if ([keyPath isEqualToString:@"playbackBufferEmpty"]){ NSLog(@"playbackBufferEmpty"); [self.viewLogin setHidden:YES]; }else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]){ [self.viewLogin setHidden:NO]; NSLog(@"playbackLikelyToKeepUp"); }}#pragma mark - 手势监听- (void)addPlayerClick{ //单机手势监听 UITapGestureRecognizer * tapGes=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(playerSingleClick:)]; tapGes.numberOfTapsRequired=1; [self.viewAvPlayer addGestureRecognizer:tapGes]; /* //双击手势监听 UITapGestureRecognizer * tapGesDouble=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(playerDoubleTap:)]; tapGesDouble.numberOfTapsRequired=2; [self.viewAvPlayer addGestureRecognizer:tapGesDouble]; //双击手势确定监测失败才会触发单击手势的相应操作 [tapGes requireGestureRecognizerToFail:tapGesDouble];*/}//显示或隐藏控制view- (void)playerSingleClick:(UITapGestureRecognizer*)recognizer{ if (self.isBottomViewHide) { //显示 [UIView animateWithDuration:0.3 animations:^{ [self.viewBottom setAlpha:1]; [self.viewHead setAlpha:1]; }]; }else{ //隐藏 [UIView animateWithDuration:0.3 animations:^{ [self.viewBottom setAlpha:0.0]; [self.viewHead setAlpha:0.0]; }]; } self.isBottomViewHide=!self.isBottomViewHide;}//改变播放模式- (void)playerDoubleTap:(UITapGestureRecognizer*)recognizer{ AVPlayerLayer *playerLayer=[AVPlayerLayer playerLayerWithPlayer:self.player]; if ([playerLayer.videoGravity isEqualToString:AVLayerVideoGravityResizeAspect]) { playerLayer.videoGravity=AVLayerVideoGravityResizeAspectFill; }else if ([playerLayer.videoGravity isEqualToString:AVLayerVideoGravityResizeAspectFill]){ playerLayer.videoGravity=AVLayerVideoGravityResize; }else if ([playerLayer.videoGravity isEqualToString:AVLayerVideoGravityResize]){ playerLayer.videoGravity=AVLayerVideoGravityResizeAspect; }}#pragma mark - smSliderDelegate- (void)SMSliderBar:(UIView *)slider valueChanged:(float)value{ self.isHasMovie = YES;}- (void)SMSliderBarBeginTouch:(UIView *)slider{ [_player pause]; self.isHasMovie = NO;}- (void)SMSliderBarEndTouch:(UIView *)slider{ if (self.isHasMovie) { [_player seekToTime:CMTimeMakeWithSeconds(self.totalTime*self.slider.value, _player.currentItem.duration.timescale)completionHandler:^(BOOL finished) { if (finished) { [_player play]; } }]; }}#pragma mark - IBAction- (IBAction)pauseClick:(id)sender { if (_player.rate == 0) { [_player play]; [self.btnPause setTitle:@"暂停" forState:UIControlStateNormal]; [self.btnPause setBackgroundImage:[UIImage imageNamed:@"play_stop.png"] forState:UIControlStateNormal]; }else{ [_player pause]; [self.btnPause setTitle:@"播放" forState:UIControlStateNormal]; [self.btnPause setBackgroundImage:[UIImage imageNamed:@"play_start.png"] forState:UIControlStateNormal]; }}- (IBAction)nextClick:(id)sender { ++subscript; self.labelTimeNow.text = @"00:00:00"; self.labelTimeTotal.text = @"00:00:00"; self.slider.value = 0; if (subscript < self.arrVedio.count) { [self.player seekToTime:CMTimeMakeWithSeconds(0, _player.currentItem.duration.timescale)]; [self removeNotification]; [self removeObserverFromPlayerItem:self.player.currentItem]; [self.player removeTimeObserver:self.timeObserver]; [_player replaceCurrentItemWithPlayerItem:[self getPlayItem:subscript]]; [self addObserverToPlayerItem:self.player.currentItem]; [self addNotification]; [self addProgressObserver]; if (self.player.rate == 0 ) { [self.player play]; } }else{ --subscript; /* [self.player.currentItem cancelPendingSeeks]; [self.player.currentItem.asset cancelLoading]; */ [self.btnPause setTitle:@"播放" forState:UIControlStateNormal]; [self.btnPause setBackgroundImage:[UIImage imageNamed:@"play_start.png"] forState:UIControlStateNormal]; self.labelTimeTotal.text = @"00:00:00"; self.labelTimeNow.text = @"00:00:00"; [MBMessageTip messageWithTip:self.view withMessage:@"没有更多了" ]; }}- (IBAction)backAction:(id)sender { [self savePayHistory]; [self.player pause]; [self dismissViewControllerAnimated:YES completion:nil];}#pragma mark - interface rotation//横屏- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{ return YES;}- (UIInterfaceOrientationMask)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskLandscapeRight;}- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{ NSString *frameString = NSStringFromCGRect(self.viewAvPlayer.frame); NSLog(@"视频窗口的frame:%@",frameString);}#pragma mark - 私有方法//设置播放时长- (void)setTime:(float)current withTotal:(float)total{ self.slider.value = current/total; self.labelTimeNow.text = [self displayTime:(int)current]; self.labelTimeTotal.text = [self displayTime:(int)total];}- (NSString*)displayTime:(int)timeInterval{ NSString * time = @""; int seconds = timeInterval % 60; int minutes = (timeInterval / 60) % 60; int hours = timeInterval / 3600; NSString * secondsStr=seconds<10?[NSString stringWithFormat:@"%@%d",@"0",seconds]:[NSString stringWithFormat:@"%d",seconds]; NSString * minutesStr=minutes<10?[NSString stringWithFormat:@"%@%d",@"0",minutes]:[NSString stringWithFormat:@"%d",minutes]; NSString * hoursStr=hours<10?[NSString stringWithFormat:@"%@%d",@"0",hours]:[NSString stringWithFormat:@"%d",hours]; time = [NSString stringWithFormat:@"%@%@%@%@%@",hoursStr,@":",minutesStr,@":",secondsStr]; return time;}//视频加载指示条- (void)roteImageView{ CABasicAnimation* rotationAnimation; rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 ]; rotationAnimation.cumulative = YES; rotationAnimation.repeatCount = 1; rotationAnimation.duration = 1; [self.imageViewLogin.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];}//保存播放历史- (void)savePayHistory{ NSDate *currentDate = [NSDate date];//获取当前时间,日期 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"YYYY-MM-dd"]; NSString *dateString = [dateFormatter stringFromDate:currentDate]; VedioModel *vedioModel = _arrVedio[subscript]; VedioHistory *vedioHistory = [[VedioHistory alloc] init]; [vedioHistory insertTitle:vedioModel.strTitle createTime:dateString userId:[NSNumber numberWithInt:[vedioModel.strUserID intValue]] videoType:[NSNumber numberWithInt:vedioModel.vedioType] playTime:[NSNumber numberWithInteger:self.currentTime] videoUrl:vedioModel.strURL picUrl:vedioModel.strImage];}//视频未播放时禁止点击- (void)prohibitOperation{ self.btnNetx.enabled = NO; self.btnPause.enabled = NO; self.slider.isAllowDrag = NO;}//视频播放时取消禁止点击- (void)clearProhibitOperation{ self.btnNetx.enabled = YES; self.btnPause.enabled = YES; self.slider.isAllowDrag = YES;}- (void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self]; [self removeObserverFromPlayerItem:self.player.currentItem]; [self.player removeTimeObserver:self.timeObserver];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning];}@end
0 0
- iOS AVPlayer 使用详解
- iOS-AVPlayer的简单使用
- 播放视频AVPlayer使用详解
- 关于iOS网络音频播放的一些详解(使用AVPlayer播放网络音频)
- iOS - 使用AVPlayer播放音频、视频
- ios 使用AVPlayer自定义视频播放器
- ios 使用AVPlayer自定义视频播放器
- AVplayer的使用详解 完整注释
- 使用AVPlayer
- [IOS 开发] iOS音频篇:使用AVPlayer播放网络音乐
- [IOS 开发] iOS音频篇:使用AVPlayer播放网络音乐
- iOS SDK详解之视频播放(AVPlayer)附Demo
- iOS中使用AVPLayer自定义视频播放器
- iOS音频篇:使用AVPlayer播放网络音乐
- iOS音频篇:使用AVPlayer播放网络音乐
- iOS音频篇:使用AVPlayer播放网络音乐
- IOS 视屏开发之AVPlayer的基本使用
- iOS音频篇:使用AVPlayer播放网络音乐
- StringBuffer和StringBuilder编程遇到的问题
- 杭电1084What Is Your Grade?
- MATLAB画固定大小的彩色图片
- 解决android6.0版本无法调图片
- 杭电ACM1012(备忘)
- iOS AVPlayer 使用详解
- VC控件DateTimePicker使用方法
- iOS开发使用sdWebImage实现对tableView的cell加载图片淡入动画
- CString与char *互转总结
- mysql密码忘了的解决方法
- css中的calc()函数
- Spring MVC + MongoDB + Maven搭建项目开发环境
- display: none;、visibility: hidden、opacity=0区别总结
- iOS 的传值处理(顺逆)