iOS:AVFoundation视频拼接-淡入淡出效果

2020-01-14  本文已影响0人  豆浆油条cc

上一篇做出了视频拼接的demo
https://www.jianshu.com/writer#/notebooks/3738533/notes/58909623

但是视频之间的拼接点有点生硬,所以可以使用
AVMutableVideoCompositionLayerInstruction做淡入淡出的效果。

核心方法
startOpacity: 起始的透明度
toEndOpacity:结束的透明度
timeRange:设置透明度的时间范围

- (void)setOpacityRampFromStartOpacity:(float)startOpacity toEndOpacity:(float)endOpacity timeRange:(CMTimeRange)timeRange;

最终的做出的效果图:


Untitled.gif

核心代码:

//淡入淡出过度时间
#define fadeTime CMTimeMake(2, 1)

- (AVMutableVideoCompositionInstruction*)getCompositionInstructions:(NSArray<AVMutableCompositionTrack*>*)compositionTracks tracks:(NSArray<AVAssetTrack*>*)tracks assets:(NSArray<AVAsset*>*)assets maxDuration:(CMTime)maxDuration naturalSize:(CGSize)naturalSize{
    
    //资源动画范围
    __block CMTimeRange atTime_end = kCMTimeRangeZero;
    __block CMTimeRange atTime_begin = kCMTimeRangeZero;

    
    __block CMTime duraton = kCMTimeZero;

    NSMutableArray* layerInstructions = [NSMutableArray array];

    //视频轨道中的一个视频,可以缩放、旋转等
    AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, maxDuration);
    
    [compositionTracks enumerateObjectsUsingBlock:^(AVMutableCompositionTrack * _Nonnull compositionTrack, NSUInteger idx, BOOL * _Nonnull stop) {
        AVAssetTrack *assetTrack = tracks[idx];
        AVAsset *asset = assets[idx];

        AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionTrack];
        
        //设置旋转角度
        CGAffineTransform transfrom = [self getTransfromFromTrack:assetTrack naturalSize:naturalSize];
        [layerInstruction setTransform:transfrom atTime:kCMTimeZero];

        duraton = CMTimeAdd(duraton, asset.duration);
        atTime_end =  CMTimeRangeMake(duraton, fadeTime);
                
        //淡出
        [layerInstruction setOpacityRampFromStartOpacity:1.0 toEndOpacity:0.0 timeRange:atTime_end];
        
        //淡入
        [layerInstruction setOpacityRampFromStartOpacity:0.0 toEndOpacity:1.0 timeRange:atTime_begin];

        atTime_begin = CMTimeRangeMake(CMTimeSubtract(duraton, fadeTime), asset.duration);

        [layerInstructions addObject:layerInstruction];
    }];
    
    mainInstruction.layerInstructions = layerInstructions;
    
    return mainInstruction;
}

在加载资源轨道的时候需要减去淡入淡出的时间点

    //加载音视频轨道
    [videos enumerateObjectsUsingBlock:^(NSURL* obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        AVAsset* asset = [AVAsset assetWithURL:obj];
        AVAssetTrack* videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
        AVAssetTrack* audioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
        
        //视频轨道容器
        AVMutableCompositionTrack* videoCompositionTrack = [mix addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];

        AVMutableCompositionTrack* audioCompositionTrack = [mix addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];

        [videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:videoTrack atTime:atTime error:nil];
        [audioCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:audioTrack atTime:atTime error:nil];

        [tracks addObject:videoTrack];
        [assets addObject:asset];
        
        [videoCompositionTracks addObject:videoCompositionTrack];
        
        //减去动画时间
        atTime = CMTimeAdd(atTime, asset.duration);
        maxDuration = CMTimeAdd(maxDuration, asset.duration);
    }];

GitHub:
https://github.com/qw9685/fadeVideos

上一篇 下一篇

猜你喜欢

热点阅读