上一篇做出了视频拼接的demo
https://www.jianshu.com/writer#/notebooks/3738533/notes/58909623
但是视频之间的拼接点有点生硬,所以可以使用
AVMutableVideoCompositionLayerInstruction做淡入淡出的效果。
核心方法
startOpacity: 起始的透明度
toEndOpacity:结束的透明度
timeRange:设置透明度的时间范围
- (void)setOpacityRampFromStartOpacity:(float)startOpacity toEndOpacity:(float)endOpacity timeRange:(CMTimeRange)timeRange;
最终的做出的效果图:

核心代码:
//淡入淡出过度时间
#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);
}];
网友评论