×

短视频从无到有 (十二)视频中插入另外一个视频(优酷App视频广告效果)

96
卢叁
2018.08.10 14:18 字数 462

前言:昨天躺床上在优酷app看片时,看到优酷视频中播放视频广告的效果非常好,想到实现这个效果时,无外乎三个方法。方法如下:

第一种

初始化两个视频播放器,提前预加载好广告视频,等到要播放视频广告时,暂停正在播放的视频,切换到视频广告播放。此种方法在切换时画面不是很流畅,可增加过渡动画,但此种方案太low,优酷app肯定不是这么处理的,pass掉。

第二种

把整个视频切割成很多段视频,视频广告也是一段视频,然后把这些视频合成一个完整的视频,不清楚的同学可以看我另外一遍文章短视频从无到有 (六)视频合成及压缩、转换格式。只是这样一来,后台所做的工作就多了,而且也很 low,pass掉。

第三种

最高大上的一种,运用AVAssetTrack,取出要混合视频的音频轨和视频轨,分别insert相应的视频轨和音频轨即可。代码依然很简单,如下:

 NSArray *videosPathArray =@[@"",
                                                   @""];

AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];
    
    
    AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];
    NSDictionary* options = @{AVURLAssetPreferPreciseDurationAndTimingKey:@YES
                              
                              };
    //网络视频 URLWithString: 本地视频 fileURLWithPath:
    
    //第一个视频
    AVURLAsset *asset1 =[AVURLAsset URLAssetWithURL:[NSURL URLWithString:videosPathArray[0]] options:options];
    
    AVAssetTrack *videoTrack1 =[[asset1 tracksWithMediaType:AVMediaTypeVideo] firstObject];
    AVAssetTrack *audioTrack1 =[[asset1 tracksWithMediaType:AVMediaTypeAudio] firstObject];
    
    
    //第二个视频
    AVURLAsset *asset2 =[AVURLAsset URLAssetWithURL:[NSURL URLWithString:videosPathArray[1]] options:options];
    CMTimeRange range2 =CMTimeRangeMake(kCMTimeZero, asset2.duration);
    AVAssetTrack *videoTrack2 =[[asset2 tracksWithMediaType:AVMediaTypeVideo] firstObject];
    AVAssetTrack *audioTrack2 =[[asset2 tracksWithMediaType:AVMediaTypeAudio] firstObject];
    
    //先混合第二个视频
    NSError *errorVideo2;
    [videoTrack insertTimeRange:range2 ofTrack:videoTrack2 atTime:kCMTimeZero error:&errorVideo2];
    NSError *errorAudio2;
    [audioTrack insertTimeRange:range2 ofTrack:audioTrack2 atTime:kCMTimeZero error:&errorAudio2];
    
    //第一个视频插入到第二个视频中 譬如插入1分钟时间的视频
    NSError *errorVideo1;
    [videoTrack insertTimeRange:CMTimeRangeMake(CMTimeMake(1,1), CMTimeMake(60,1)) ofTrack:videoTrack1 atTime:CMTimeMake(1, 1) error:&errorVideo1];
    
    NSError *errorAudio1;
    [audioTrack insertTimeRange:CMTimeRangeMake(CMTimeMake(1,1), CMTimeMake(60,1)) ofTrack:audioTrack1 atTime:CMTimeMake(1, 1) error:&errorAudio1];
  
    
    NSLog(@"出错:%@____%@______%@____%@",errorVideo2.localizedDescription,errorAudio2.localizedDescription,errorAudio1.localizedDescription,errorVideo1.localizedDescription);

上一步,我们把第一个视频(即广告视频),插入到第二个视频(即要看的视频)中,那么我们就先处理第二个视频,然后直接insert即可。最后我们得到编辑后的mixComposition,然后直接交给播放器播放即可:

  
    LYAVPlayerView *playerView =[[LYAVPlayerView alloc]init];
  //  CGFloat scale =_composition.naturalSize.width/_composition.naturalSize.height;
    playerView.frame =CGRectMake(0,100,ScreenWidth,ScreenHeight-160);
    playerView.videoGravity =AVLayerVideoGravityResizeAspect;
    [playerView setPlayerItem:[[AVPlayerItem alloc]initWithAsset:mixComposition]];
    [self.view addSubview:playerView];
    [playerView play];

后记: AVAssetTrack还有另外两个函数removeTimeRange:insertEmptyTimeRange:,大家可以调用测试下,看是什么效果。

有什么问题,欢迎大家留言讨论。

日记本
Web note ad 1