iOS视频播放
2016-07-06 15:03
621 查看
在iOS中处理视频播放一般可以使用MPMoviePlayerViewController或者AVPlayer
若要将播放器视图加到某个view上,要这样写
MPMoviePlayerViewController的状态监控可通过moviePlayer的发出的通知来接收。下面介绍下常用到的。
a.状态改变
b.视频播放结束(失败)
需要引入库
a.播放完成监控(可实现循环播放)
b.状态改变和缓冲进度,可处理遮盖图片避免闪黑屏以及加载进度的显示
这里附上取视频第一帧的代码:
一、MPMoviePlayerViewController的使用
MPMoviePlayerViewController是系统封装的一个播放器控制器,其中对于视频的控制由其属性@property (nonatomic, readonly) MPMoviePlayerController *moviePlayer;负责。
1.创建使用
NSURL *URL = [NSURL fileURLWithPath:_videoPath]; _player = [[MPMoviePlayerViewController alloc] initWithContentURL:URL]; _player.moviePlayer.controlStyle = MPMovieControlStyleNone;//不显示控制控件 _player.moviePlayer.repeatMode = MPMovieRepeatModeNone;//不循环播放 _player.moviePlayer.scalingMode =MPMovieScalingModeAspectFill;//保存宽高比,填满视图 [_player.moviePlayer prepareToPlay]; [_player.moviePlayer play];播放
若要将播放器视图加到某个view上,要这样写
[self.view addSubview:_player.view];
2.播放状态的监控处理
有时候,播放器开始播放的时候,会有一点黑屏的缓冲加载时间,感觉上会先黑屏一下才出现视频,为了视频加载的时候不显示黑屏,一般可先覆盖一张图片(比如视频第一帧),等待视频加载完成才隐藏图片播放视频。这种场景下便需要监听播放器的通知了。MPMoviePlayerViewController的状态监控可通过moviePlayer的发出的通知来接收。下面介绍下常用到的。
a.状态改变
[self addObserver:@selector(loadStatusChanged:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
- (void)loadStatusChanged:(NSNotification *)notification { MPMoviePlayerController *player = notification.object; if ([player isEqual: _player.moviePlayer] && (player.loadState & MPMovieLoadStatePlayable)) { [player play];//现在才播放 [_coverView removeFromSuperview];//移除遮盖图片 } }
b.视频播放结束(失败)
[self addObserver:@selector(playDidFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
- (void)playDidFinished:(NSNotification *)notification { MPMoviePlayerController *player = notification.object; if (![player isEqual:_player.moviePlayer]) { return; } NSDictionary *notificationUserInfo = [notification userInfo]; NSNumber *resultValue = [notificationUserInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey]; MPMovieFinishReason reason = [resultValue intValue]; if (reason == MPMovieFinishReasonPlaybackError) { NSError *mediaPlayerError = [notificationUserInfo objectForKey:@"error"]; if (mediaPlayerError) { GLLoge(@"动画播放失败: %@", [mediaPlayerError localizedDescription]); } else { GLLoge(@"动画播放出错了"); } } }
注意:
不可以同时加载播放两个以上的MPMoviePlayerViewController,多个播放器最终只有一个播放能生效,通知也只能收到一个播放器发出的。
二,AVPlayer的使用
AVPlayer相对于MPMoviePlayerViewController更为底层,功能更强大。需要引入库
#import <AVFoundation/AVFoundation.h>
1.创建使用
@property (nonatomic)AVPlayer *player; @property (nonatomic)AVPlayerItem *playerItem; _playerItem=[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"launch" withExtension:@"mp4"]]; //创建播放源对象 _player=[AVPlayer playerWithPlayerItem:self.playerItem];//播放器对象 AVPlayerLayer *layer=[AVPlayerLayer playerLayerWithPlayer:self.player]; layer.videoGravity=AVLayerVideoGravityResizeAspectFill; layer.frame=[UIScreen mainScreen].bounds; layer.backgroundColor=[[UIColor whiteColor] CGColor]; [self.layer addSublayer:layer];//必须使用AVPlayerLayer加到view的layer中,否则看不到视频 [_player play];
2.AVPlayer的状态监控
AVPlayer是没有循环播放模式的,但可以通过状态监控,在视频播放完后,从头再播放。它的播放控制和各种状态是通过其播放源AVPlayerItem来监控的。a.播放完成监控(可实现循环播放)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(runLoopTheMovie:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
- (void)runLoopTheMovie:(NSNotification *)notification{ //注册的通知 可以自动把 AVPlayerItem 对象传过来,只要接收一下就OK AVPlayerItem * playItem = [notification object]; //关键代码 [playItem seekToTime:kCMTimeZero];//时间拨到0,重新开始 [_player play]; }
b.状态改变和缓冲进度,可处理遮盖图片避免闪黑屏以及加载进度的显示
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];// 监听status属性 [self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];// 监听loadedTimeRanges 缓冲属性
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{ AVPlayerItem *playerItem = (AVPlayerItem *)object; if ([keyPath isEqualToString:@"status"]) { if ([playerItem status] == AVPlayerStatusReadyToPlay) { NSLog(@"AVPlayerStatusReadyToPlay"); //隐藏遮盖图片 [UIView animateWithDuration:0.3 animations:^{ self.coverImageView.alpha=0; } completion:^(BOOL finish){ if (finish) { self.coverImageView.hidden=YES; } }]; } else if ([playerItem status] == AVPlayerStatusFailed) { GLLoge(@"动画播放失败"); } } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) { NSTimeInterval timeInterval = [self availableDuration];// 计算缓冲进度 NSLog(@"Time Interval:%f",timeInterval); CMTime duration = self.playerItem.duration; CGFloat totalDuration = CMTimeGetSeconds(duration); [self.videoProgress setProgress:timeInterval / totalDuration animated:YES]; } } - (NSTimeInterval)availableDuration { NSArray *loadedTimeRanges = [[self.playerView.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 *)convertTime:(CGFloat)second{ NSDate *d = [NSDate dateWithTimeIntervalSince1970:second]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; if (second/3600 >= 1) { [formatter setDateFormat:@"HH:mm:ss"]; } else { [formatter setDateFormat:@"mm:ss"]; } NSString *showtimeNew = [formatter stringFromDate:d]; return showtimeNew; }
这里附上取视频第一帧的代码:
//获取视频第一帧图像 - (UIImage*)getCoverImage{ AVURLAsset *asset = [AVURLAsset assetWithURL:[[NSBundle mainBundle] URLForResource:@"launch" withExtension:@"mp4"]]; NSParameterAssert(asset); AVAssetImageGenerator *assetImageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; assetImageGenerator.appliesPreferredTrackTransform =YES; assetImageGenerator.apertureMode =AVAssetImageGeneratorApertureModeEncodedPixels; CGImageRef thumbnailImageRef = NULL; NSError *thumbnailImageGenerationError = nil; CMTime time = CMTimeMakeWithSeconds(0.0, 600); thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:time actualTime:NULL error:&thumbnailImageGenerationError]; if (!thumbnailImageRef) NSLog(@"thumbnailImageGenerationError %@", thumbnailImageGenerationError); UIImage *thumbnailImage = thumbnailImageRef ? [[UIImage alloc] initWithCGImage:thumbnailImageRef] :nil; CGImageRelease(thumbnailImageRef); return thumbnailImage; }
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 买视频送图书-五月活动
- DVI 视频接口图文解析
- C#实现语音视频录制-附demo源码
- 编写C++程序使DirectShow进行视频捕捉
- AnyChat的视频会议程序实例详解
- C#调用mmpeg进行各种视频转换的类实例
- C#获取视频某一帧的缩略图的方法
- 基于jQuery的网页影音播放器jPlayer的基本使用教程
- 显示youtube视频缩略图和Vimeo视频缩略图代码分享
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用开发中AFNetworking库的常用HTTP操作方法小结