您的位置:首页 > 移动开发 > IOS开发

iOS视频播放

2016-07-06 15:03 621 查看
在iOS中处理视频播放一般可以使用MPMoviePlayerViewController或者AVPlayer

一、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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios 视频