我正在尝试使用与相机相同的旋转变换导出视频。例如,我使用CGAffineTransform(0, -1, 1, 0, 1080, 0)
以1920x1080分辨率(横向)拍摄一些视频。完成某些工作后,我想要使用与原始视频相同的naturalSize
和preferredTransform
导出该视频,但ExportSession
正在旋转我的视频。
下面的代码将原始视频转换为纵向模式,纵向旋转,但这不是我想要实现的。
有什么想法吗?提前谢谢。
- (void)applyDrawWithCompletion:(void(^)(NSURL *))completion {
//setup video asset layer
AVURLAsset* videoAsset = (AVURLAsset *)self.avPlayer.currentItem.asset;
AVMutableComposition* mixComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
ofTrack:clipVideoTrack
atTime:kCMTimeZero error:nil];
AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *clipAudioTrack = [videoAsset tracksWithMediaType:AVMediaTypeAudio][0];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [mixComposition duration]) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];
[compositionVideoTrack setPreferredTransform:clipVideoTrack.preferredTransform];
//new layer with draw image
CGSize videoSize = CGSizeMake(clipVideoTrack.naturalSize.height, clipVideoTrack.naturalSize.width);
CALayer *drawLayer = [CALayer layer];
drawLayer.contents = (id)self.tempDrawImage.image.CGImage;
drawLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
//proper sorting of video layers
CALayer *parentLayer = [CALayer layer];
CALayer *videoLayer = [CALayer layer];
parentLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
videoLayer.frame = CGRectMake(0, 0, videoSize.width, videoSize.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:drawLayer];
AVMutableVideoComposition* videoComp = [AVMutableVideoComposition videoComposition];
videoComp.renderSize = videoSize;
videoComp.frameDuration = CMTimeMake(1, 30);
videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
//Adding layer along asset duration
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mixComposition duration]);
AVAssetTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
//Apply transform to layer instructions
[layerInstruction setTransform:clipVideoTrack.preferredTransform atTime:kCMTimeZero];
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
videoComp.instructions = [NSArray arrayWithObject: instruction];
//Export edited video
AVAssetExportSession *assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
assetExport.videoComposition = videoComp;
NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"editedVideo.mov"];;
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath]) {
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
assetExport.outputFileType = AVFileTypeQuickTimeMovie;
assetExport.outputURL = [NSURL fileURLWithPath:exportPath];
assetExport.shouldOptimizeForNetworkUse = YES;
[assetExport exportAsynchronouslyWithCompletionHandler:^(void) {
if (assetExport.status == AVAssetExportSessionStatusCompleted) {
completion(assetExport.outputURL);
}else if(assetExport.status == AVAssetExportSessionStatusFailed || assetExport.status == AVAssetExportSessionStatusCancelled){
completion(nil);
}
}];
}
答案 0 :(得分:1)
我使用相同的方法处理原始相机视频并添加以下代码:
CGAffineTransform t = clipVideoTrack.preferredTransform;
BOOL isPortrait = (t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0) || (t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0);
//new layer with draw image
CGSize videoSize = clipVideoTrack.naturalSize;
if (isPortrait) {
videoSize = CGSizeMake(clipVideoTrack.naturalSize.height, clipVideoTrack.naturalSize.width);
}
这会将横向视频更改为肖像,其转换与其他已编辑和处理的视频相同。 这不是我想要的,但它解决了我的问题。如果有人知道如何实现原始问题目标,请随时添加答案。