iOS 应用展示广告动画

陶炫明
2023-12-01

不少iOS应用启动时都添加了类似动画的视频广告,今天做了一个小demo,简洁易用!

一、资源

   广告视频采用mp4格式

   采用AVFoundition框架

   #import <AVFoundation/AVFoundation.h>

二、代码实现

  1.创建动画功能

      @property (nonatomic, strong) AVPlayer * player;

     @property (nonatomic, strong) AVPlayerItem * playerItem;

    - (void)createAvPlayer
     {
        CGRect playerFrame = CGRectMake(0, 0, kScreenWith, kScreenHeight);
    
        NSURL * url = [[NSBundle mainBundle] URLForResource:@"guideVideo" withExtension:@"mp4"];
    
        AVURLAsset * asset = [AVURLAsset assetWithURL:url];
    
        _playerItem = [AVPlayerItem playerItemWithAsset: asset];
    
        _player = [[AVPlayer alloc]initWithPlayerItem:_playerItem];
    
        AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
    
        playerLayer.frame = playerFrame;
    
        playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
    
        [self.view.layer addSublayer:playerLayer];
    
       [_player play];
     }

 这时候可以播放了。

 2.如果播放前需要有个缓冲效果,可以获取视频的第一帧图片作为封面加在视图上,当动画开始播放时,移除封面。

    @property (nonatomic, strong) UIImageView * coverImageView;

   - (void)creatCoverImageView
   {
      self.coverImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
      [self.view addSubview:self.coverImageView];
      self.coverImageView.image = [self getVideoPreViewImage];
   }  

  /*** 获取视频第一帧 ***/
 - (UIImage*)getVideoPreViewImage
 {
    NSURL * url = [[NSBundle mainBundle] URLForResource:@"guideVideo" withExtension:@"mp4"];
    
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
    
    AVAssetImageGenerator * gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    
    gen.appliesPreferredTrackTransform = YES;
    
    CMTime time = CMTimeMakeWithSeconds(0.0, 600);
    
    NSError *error = nil;
    
    CMTime actualTime;
    
    CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
    
    UIImage *img = [[UIImage alloc] initWithCGImage:image];
    
    CGImageRelease(image);
    
    return img;
  }

  注册AVPlayerItem 播放状态的观察者

 
- (void)addVideoKVO
{
    //KVO
    [_playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}

 - (void)removeVideoKVO
{
    [_playerItem removeObserver:self forKeyPath:@"status"];
}

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSString*, id> *)change context:(nullable void *)context
{
    if ([keyPath isEqualToString:@"status"])
    {
        AVPlayerItemStatus status = _playerItem.status;
        switch (status)
        {
            case AVPlayerItemStatusReadyToPlay:
            {

                NSLog(@"AVPlayerItemStatusReadyToPlay");//当播放开始时,移除封面
                [self.coverImageView removeFromSuperview];
            }
                break;
            case AVPlayerItemStatusUnknown:
            {
                NSLog(@"AVPlayerItemStatusUnknown");
            }
                break;
            case AVPlayerItemStatusFailed:
            {
                NSLog(@"AVPlayerItemStatusFailed");
            }
                break;
                
            default:
                break;
        }
    }
}

3.注册其他消息类型

-(void)addNotification
{
    //给AVPlayerItem添加播放完成通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
    
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginSccess:) name:k_Notification_login object:nil];
}


- (void)playbackFinished:(NSNotification *)notification
{
    // 播放完成后重复播放
    // 跳到最新的时间点开始播放
    
    [_player seekToTime:kCMTimeZero];
    [_player play];
    
}

- (void)appWillResignActive:(NSNotification *)notification
{
    if (self.player)
    {
        [self.player pause];
        
        self.time = self.player.currentTime;
    }
}

- (void)appBecomeActive:(NSNotification *)notification
{
    //在刚启动播放的时候,以及在播放到最后一帧的时候,有可能会出现异常并crash
    //用@try@catch来捕获这个异常,当出现异常的时候直接调用play让播放器自己决定播放的进度
    
    @try {
        
        [self.player seekToTime:self.time toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:^(BOOL finished) {
            if (finished) {
                [self.player play];
            }
        }];
        
        
    } @catch (NSException *exception) {
        
        [self.player play];
        
    } @finally {
        
    }
}


- (void)loginSccess:(NSNotification *)notification
{
    [self.navigationController popViewControllerAnimated:NO];
}

 类似资料: