踩坑完畢:稍微總結(jié)一下使用方式:
第一步:把播放器做成一個單利類,方便外部的調(diào)用;畢竟一個APP一般同時就播放一個視頻:+ +(VGVideoPlayer *)shareVGVideoPlayer{
??????????? static VGVideoPlayer *videoPlayer;
?????????? static dispatch_once_t onceToken;
??????????? dispatch_once(&onceToken, ^{
??????????? videoPlayer = [[VGVideoPlayer alloc] init];
???????????? [videoPlayer addNotification];
???????????? });
?????????? return videoPlayer;
}
第二步:拿到外部的數(shù)據(jù),進(jìn)行處理,當(dāng)然了,你如果不是這樣的數(shù)據(jù),就可以不用看這個方法嘍:
- (void)playVideoWithVideoModel:(VideoModel *_Nullable)model view:(UIView *_Nullable)view{
?????????????????? NSArray *movieSource = [model.source componentsSeparatedByString:@"."];
????????????????? NSString *path = [[NSBundle mainBundle] pathForResource:movieSource[0]??????????? ofType:movieSource[1]];
???????????????? if (movieId != [model.sourceId integerValue]) {
?????????????????? ? ? ? ? movieId = [model.sourceId integerValue];
????????????????????????? self.loop = model.loop;
???????????????????????? [self playWithUrlString:path view:view];
? ? ? ? ? ? ? ??? }
}
第三步:初始化:
- (void)playWithUrlString:(NSString *)urlString view:(UIView *)view{
??????????? if (urlString == nil) {
????????????????? return;
????????????? }
????????? [self creatBaseView:view];
?????? if (self.player) {
?????????????????? [[NSNotificationCenter defaultCenter] removeObserver:self? name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
??????????? }
NSURL *sourceUrl = [NSURL fileURLWithPath:urlString];
AVAsset *movieAsset = [AVAsset assetWithURL:sourceUrl];
[movieAsset loadValuesAsynchronouslyForKeys:@[@"duration", @"tracks", @"commonMetadata"] completionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
AVPlayerItem *playerItyem = [AVPlayerItem playerItemWithAsset:movieAsset];
if (!self.player) {
self.player = [AVPlayer playerWithPlayerItem:playerItyem];
[self.player setActionAtItemEnd:AVPlayerActionAtItemEndPause];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT);
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
[self.baseView.layer addSublayer:playerLayer];
}else{
//切換播放源,解決閃屏問題
[self.player replaceCurrentItemWithPlayerItem:playerItyem];
}
//注冊通知
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(runLoopTheMovie:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
[self.player play];
});
}];
}
- (void)creatBaseView:(UIView *)view{
if (!self.baseView) {
self.baseView = [[UIView alloc] initWithFrame:view.bounds];
[view addSubview:_baseView];
}
}
- (void)runLoopTheMovie:(NSNotification *)n{
????????? if (![[n object] isEqual:self.player.currentItem]) {
????????? ? ? ? ?? return;
?????????? }
if (self.loop) {
? //注冊的通知? 可以自動把 AVPlayerItem 對象傳過來,只要接收一下就OK
????? AVPlayerItem * p = [n object];
//關(guān)鍵代碼
?????? [p seekToTime:kCMTimeZero];
?????? [self.player play];
?? }else{
??????? if (self.delegate && [self.delegate respondsToSelector:@selector(videoPlayEnd)]) {
??????????????? [self.delegate videoPlayEnd];
?????? ? ? }
????? }
}
解釋一下字段:loop :視頻是否可以循環(huán)播放;
- (void)stopPlaying{
[self.player pause];
self.player = nil;
movieId = 0;
[self.baseView removeFromSuperview];
self.baseView = nil;
}
#pragma mark - 添加掛起通知和進(jìn)入前后臺通知
-(void)addNotification{
// 后臺&前臺通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(becomeActiveNotification) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resignActiveNotification) name:UIApplicationWillResignActiveNotification object:nil];
}
// 掛起
- (void)resignActiveNotification{
if (self.player) {
[self.player pause];
time = self.player.currentTime;
}
positionImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, IPHONE_WIDTH, IPHONE_HEIGHT)];
positionImage.image = [self captureCurrentScreen];
[[[UIApplication sharedApplication] keyWindow] addSubview:positionImage];
}
// 結(jié)束掛起
- (void)becomeActiveNotification{
if (self.player) {
@try {
[self.player seekToTime:time toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
if (finished) {
[self.player play];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[positionImage removeFromSuperview];
positionImage = nil;
});
}
}];
} @catch (NSException *exception) {
[self.player play];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[positionImage removeFromSuperview];
positionImage = nil;
});
}
}
}
#pragma mark - 截取當(dāng)前屏幕
- (UIImage *)captureCurrentScreen{
UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGRectGetWidth(_baseView.frame), CGRectGetHeight(_baseView.frame)), NO, [UIScreen mainScreen].scale);
[_baseView drawViewHierarchyInRect:CGRectMake(0, 0, CGRectGetWidth(_baseView.frame), CGRectGetHeight(_baseView.frame)) afterScreenUpdates:NO];
UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snapshot;
}
代碼粘貼完畢:大家可以直接拷貝使用:完整的樣式,下邊截屏: