iOS、Swift

AVPlayer切换播放源与循环播放

2017-06-26  本文已影响720人  伙伴崩溃

踩坑完毕:稍微总结一下使用方式:

第一步:把播放器做成一个单利类,方便外部的调用;毕竟一个APP一般同时就播放一个视频:+ +(VGVideoPlayer *)shareVGVideoPlayer{

            static VGVideoPlayer *videoPlayer;

           static dispatch_once_t onceToken;

            dispatch_once(&onceToken, ^{

            videoPlayer = [[VGVideoPlayer alloc] init];

             [videoPlayer addNotification];

             });

           return videoPlayer;

}

第二步:拿到外部的数据,进行处理,当然了,你如果不是这样的数据,就可以不用看这个方法喽:

- (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];

//关键代码

       [p seekToTime:kCMTimeZero];

       [self.player play];

   }else{

        if (self.delegate && [self.delegate respondsToSelector:@selector(videoPlayEnd)]) {

                [self.delegate videoPlayEnd];

           }

      }

}

解释一下字段:loop :视频是否可以循环播放;

- (void)stopPlaying{

[self.player pause];

self.player = nil;

movieId = 0;

[self.baseView removeFromSuperview];

self.baseView = nil;

}

#pragma mark - 添加挂起通知和进入前后台通知

-(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];

}

// 结束挂起

- (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 - 截取当前屏幕

- (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;

}

代码粘贴完毕:大家可以直接拷贝使用:完整的样式,下边截屏:

上一篇下一篇

猜你喜欢

热点阅读