如何使用AVFoundation裁剪视频

24

我正在尝试使用AVFoundation裁剪我正在录制的视频。假设我创建了一个AVCaptureVideoPreviewLayer并将其框架设置为300x300。

AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer     layerWithSession:session];
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
captureVideoPreviewLayer.delegate = self;
captureVideoPreviewLayer.frame = CGRectMake(0,0, 300, 300);
[previewView.layer addSublayer:captureVideoPreviewLayer];

用户看到的视频被裁剪了。我希望能以用户所看到的方式精确保存视频。使用AVCaptureMovieFileOutput,视频显然会在不裁剪的情况下保存。我考虑使用AVCaptureVideoDataOutput拦截帧并自己裁剪它们,但我想知道是否有更有效的方法来实现这一点,也许可以使用AVExportSession和AVVideoComposition。

任何指导都将不胜感激。


你能使输出效果像预览层一样清晰吗?这一直是个问题,匹配AVLayerVideoGravityResizeAspectFill的锐度。 - Crashalot
2个回答

31

类似这样的代码。99% 的代码只是为了设置自定义的 CGAffineTransform,然后保存结果。

我假设你想要裁剪后的视频占据输出的整个大小/宽度,这样一个缩放仿射变换就是正确的解决方案(你可以将视频放大,达到裁剪+调整大小的效果)。

AVAsset* asset = // your input

AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];

AVMutableVideoComposition* videoComposition = [[AVMutableVideoComposition videoComposition]retain];
videoComposition.renderSize = CGSizeMake(320, 240);
videoComposition.frameDuration = CMTimeMake(1, 30);

AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30) );

AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
CGAffineTransform finalTransform = // setup a transform that grows the video, effectively causing a crop
    [transformer setTransform:finalTransform atTime:kCMTimeZero];
    instruction.layerInstructions = [NSArray arrayWithObject:transformer];
videoComposition.instructions = [NSArray arrayWithObject: instruction];

exporter = [[AVAssetExportSession alloc] initWithAsset:saveComposition presetName:AVAssetExportPresetHighestQuality] ;
exporter.videoComposition = videoComposition;
exporter.outputURL=url3;
exporter.outputFileType=AVFileTypeQuickTimeMovie;

[exporter exportAsynchronouslyWithCompletionHandler:^(void){}];

2
Adam,谢谢你的帖子。我实际上就是这样做的,本来想发回答的,但你比我更快!无论如何感谢你的帮助...我认为其他人肯定会受益。 - haider
嗨,亚当, 我正在使用相同的代码,可以获取音频但没有视频显示。你能告诉我有关裁剪视频的任何其他代码吗? - Vishal Khatri
1
我们能否得到一个“使视频增长,从而有效地裁剪”的变换示例? - etayluz
1
@AnkitKumarGupta 你已经有一个工作示例了——你已经回复了它。如果你有不同的问题,请提出一个新的问题。这就是这个网站的目的。 - Adam
@Adam 谢谢,我已经成功为自己创建了这个。你可以看一下并告诉我是否可以改进或我做错了什么。
https://github.com/ankit-betterbutter/CustomCamera
- Ankit Kumar Gupta
显示剩余6条评论

11

IOS7新增了一个专门用于裁剪的图层指令。

videolayerInstruction setCropRectangle:atTime:

_迈克


2
这并没有提供预期的结果。顺便说一下,此设置将从原始视频像素大小裁剪一个矩形,与设备屏幕大小无关。 - Maxim Veksler
@nibeck,您能否友好地提供一个代码块来演示如何使用它? - etayluz
我尝试过这个。但对我没用。不得不切换回翻译转换。 - Sreeraj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接