网上有很多视频合成/拼接的代码,大部分并没有适应视频自己的旋转角度,
所以如果有竖屏资源,合成出的视频会被旋转90度。
花了点时间,做出了一个自适应旋转角度的视频合成demo
最终的做出的效果图:

主要使用下面的类:
AVMutableVideoCompositionLayerInstruction:对各个视频资源做处理:旋转,透明,裁剪。
核心代码:
- (AVMutableVideoCompositionInstruction*)getCompositionInstructions:(NSArray<AVMutableCompositionTrack*>*)compositionTracks tracks:(NSArray<AVAssetTrack*>*)tracks assets:(NSArray<AVAsset*>*)assets maxDuration:(CMTime)maxDuration naturalSize:(CGSize)naturalSize{
//资源动画范围
__block CMTime atTime = 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];
//设置透明
atTime = CMTimeAdd(atTime, asset.duration);
[layerInstruction setOpacity:0.0 atTime:atTime];
[layerInstructions addObject:layerInstruction];
}];
mainInstruction.layerInstructions = layerInstructions;
return mainInstruction;
}
设置视频的旋转
- (CGAffineTransform)getTransfromFromTrack:(AVAssetTrack*)track naturalSize:(CGSize)naturalSize{
UIImageOrientation assetOrientation = UIImageOrientationUp;
BOOL isPortrait = NO;
CGAffineTransform transfrom = track.preferredTransform;
if(transfrom.a == 0 && transfrom.b == 1.0 && transfrom.c == -1.0 && transfrom.d == 0) {
assetOrientation = UIImageOrientationRight;
isPortrait = YES;
}
if(transfrom.a == 0 && transfrom.b == -1.0 && transfrom.c == 1.0 && transfrom.d == 0) {
assetOrientation = UIImageOrientationLeft;
isPortrait = YES;
}
if(transfrom.a == 1.0 && transfrom.b == 0 && transfrom.c == 0 && transfrom.d == 1.0) {
assetOrientation = UIImageOrientationUp;
}
if(transfrom.a == -1.0 && transfrom.b == 0 && transfrom.c == 0 && transfrom.d == -1.0) {
assetOrientation = UIImageOrientationDown;
}
CGFloat assetScaleToFitRatio = naturalSize.width / track.naturalSize.width;
if(isPortrait) {
assetScaleToFitRatio = naturalSize.width / track.naturalSize.height;
CGAffineTransform assetScaleFactor = CGAffineTransformMakeScale(assetScaleToFitRatio,assetScaleToFitRatio);
transfrom = CGAffineTransformConcat(track.preferredTransform, assetScaleFactor);
}else{
CGAffineTransform assetScaleFactor = CGAffineTransformMakeScale(assetScaleToFitRatio,assetScaleToFitRatio);
transfrom = CGAffineTransformConcat(CGAffineTransformConcat(track.preferredTransform, assetScaleFactor),CGAffineTransformMakeTranslation(0, naturalSize.width/2));
}
return transfrom;
}
网友评论