2014-09-11 77 views
1

我知道这是一个常见问题,我环顾四周,没有明确的答案。裁剪视频到广场iOS

的代码是从文章: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

难道解决方案如下解决您的问题。我有完全相同的问题,我似乎无法弄清楚为什么视频保持相同的大小? – 2015-09-18 16:49:07

+0

如果你能解决这个问题,请帮助我。 http://stackoverflow.com/questions/43451879/square-video-using-avfoundation – 2017-04-17 13:22:20

回答

2

您需要的

[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"); 
    } 
}]; 
+0

你可以发布编辑后的代码吗? – 2015-07-08 16:46:32

+0

@jiw我有一个类似的问题,但我很困惑,我会添加你在原代码中给出的代码,你能帮忙吗? – 2015-09-18 17:21:51

+0

@brianScroggins看到我的编辑。 – jlw 2015-09-18 19:33:43