我知道这是一个经常被问到的问题,我环顾四周,并没有明确的答案。
代码来自一篇文章:http://www.netwalk.be/article/record-square-video-ios
我想要的是:我想裁剪视频以使其成为正方形。
基本上这就是我正在做的事情。这对我来说很有意义,但由于某些原因,视频没有裁剪,事实上,它保持相同的尺寸(宽度和高度)。
AVAsset* asset = [AVAsset assetWithURL:self.videoURL];
AVMutableComposition *composition = [AVMutableComposition composition];
[composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
// input clip
AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
// make it square
AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.renderSize = CGSizeMake(3.0 , 3.0);
videoComposition.frameDuration = CMTimeMake(1, 30);
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(clipVideoTrack.naturalSize.width, clipVideoTrack.naturalSize.width) );
// rotate to portrait
AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
CGAffineTransform t1 = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.height, -(clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height) /2 );
CGAffineTransform t2 = CGAffineTransformRotate(t1, M_PI_2);
CGAffineTransform finalTransform = t2;
[transformer setTransform:finalTransform atTime:kCMTimeZero];
instruction.layerInstructions = [NSArray arrayWithObject:transformer];
videoComposition.instructions = [NSArray arrayWithObject: instruction];
AVAssetExportSession *exporter;
// export
exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality] ;
exporter.videoComposition = videoComposition;
exporter.outputURL=self.videoURL;
exporter.outputFileType=AVFileTypeMPEG4;
[exporter exportAsynchronouslyWithCompletionHandler:^(void){
NSLog(@"Exporting done!");
}];
我认为问题出在最后的出口商。要么它没有正确导出,要么我还缺少其他东西。请有人给我推荐一个很好的方法。感谢。
答案 0 :(得分:3)
您需要保存
的结果[composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
到
AVMutableCompositionTrack *theTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
你需要确定你的时间范围......你偶然会在一个时间范围内使用宽度和高度。你应该使用clipVideoTrack.timeRange。
最后,将视频片段插入合成轨道。
NSError *error; //always check this
[theTrack insertTimeRange:timeRange ofTrack:clipVideoTrack atTime:kCMTimeZero error:&error];
修改强>:
以下是一些示例代码,用于导出视频的中心方块。
声明AVAssetExportSession的属性:
@interface YourClassHere ()
@property (nonatomic) AVAssetExportSession *exporter;
@end
然后在你的方法中:
// output file
NSString* outputPath = <# your output path here #>;
if ([[NSFileManager defaultManager] fileExistsAtPath:outputPath])
[[NSFileManager defaultManager] removeItemAtPath:outputPath error:nil];
// input file
AVAsset* asset = [AVAsset assetWithURL:[NSURL fileURLWithPath:<# your path here #>]];
AVMutableComposition *composition = [AVMutableComposition composition];
[composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
// input clip
AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CGAffineTransform transform = clipVideoTrack.preferredTransform;
//get actual display size of video
CGSize videoSize;
if ((transform.a == 0 && transform.b == 1 && transform.c == -1 && transform.d == 0) // rotate 90
|| (transform.a == 0 && transform.b == -1 && transform.c == 1 && transform.d == 0)) { // rotate -90
videoSize = CGSizeMake(clipVideoTrack.naturalSize.height,clipVideoTrack.naturalSize.width);
} else {
videoSize = clipVideoTrack.naturalSize;
}
CGFloat squareDimension = fminf(videoSize.width,videoSize.height);
// make render size square
AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.renderSize = CGSizeMake(squareDimension,squareDimension);
videoComposition.frameDuration = CMTimeMake(1, 30);
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, kCMTimePositiveInfinity);
// shift video to be in the center
AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
CGAffineTransform translation = CGAffineTransformMakeTranslation(- (videoSize.width - squareDimension)/2, -(videoSize.height - squareDimension) /2 );
CGAffineTransform finalTransform = CGAffineTransformConcat(transform, translation);
[transformer setTransform:finalTransform atTime:kCMTimeZero];
instruction.layerInstructions = [NSArray arrayWithObject:transformer];
videoComposition.instructions = [NSArray arrayWithObject: instruction];
// export
self.exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality] ;
self.exporter.videoComposition = videoComposition;
self.exporter.outputURL=[NSURL fileURLWithPath:outputPath];
self.exporter.outputFileType=AVFileTypeQuickTimeMovie;
[self.exporter exportAsynchronouslyWithCompletionHandler:^(void){
switch(self.exporter.status) {
case AVAssetExportSessionStatusCompleted:
NSLog(@"file exported successfully");
break;
default:
NSLog(@"file did not export successfully");
}
}];
答案 1 :(得分:0)
请查看此仓库。我相信它将解决您所有的问题。