【发布时间】:2015-04-04 19:03:15
【问题描述】:
这里是 github https://github.com/spennyf/cropVid/tree/master 上的链接,您可以自己尝试一下,看看我在说什么,测试需要 1 分钟。谢谢!
我正在拍摄一个带有正方形的视频,以显示视频的哪一部分将被裁剪。像这样:
现在我正在做一张纸,正方形上有 4 条线,顶部和底部有半条线的差异。然后我使用我将发布的代码裁剪视频,但是当我显示视频时,我看到了这个(忽略背景和绿色圆圈):
正如您所看到的,有超过四行,所以我将它设置为裁剪某个部分,但它增加了更多,当我使用相机中显示的相同矩形时,以及相同的矩形用来裁剪的?
所以我的问题是为什么裁剪的大小不一样?
这是我如何进行裁剪和显示的:
//this is the square on the camera
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-80)];
UIImageView *image = [[UIImageView alloc] init];
image.layer.borderColor=[[UIColor whiteColor] CGColor];
image.frame = CGRectMake(self.view.frame.size.width/2 - 58 , 100 , 116, 116);
CALayer *imageLayer = image.layer;
[imageLayer setBorderWidth:1];
[view addSubview:image];
[picker setCameraOverlayView:view];
//this is crop rect
CGRect rect = CGRectMake(self.view.frame.size.width/2 - 58, 100, 116, 116);
[self applyCropToVideoWithAsset:assest AtRect:rect OnTimeRange:CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(assest.duration.value, 1))
ExportToUrl:exportUrl ExistingExportSession:exporter WithCompletion:^(BOOL success, NSError *error, NSURL *videoUrl) {
//here is player
AVPlayer *player = [AVPlayer playerWithURL:videoUrl];
AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:player];
layer.frame = CGRectMake(self.view.frame.size.width/2 - 58, 100, 116, 116);
}];
这是进行裁剪的代码:
- (UIImageOrientation)getVideoOrientationFromAsset:(AVAsset *)asset
{
AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CGSize size = [videoTrack naturalSize];
CGAffineTransform txf = [videoTrack preferredTransform];
if (size.width == txf.tx && size.height == txf.ty)
return UIImageOrientationLeft; //return UIInterfaceOrientationLandscapeLeft;
else if (txf.tx == 0 && txf.ty == 0)
return UIImageOrientationRight; //return UIInterfaceOrientationLandscapeRight;
else if (txf.tx == 0 && txf.ty == size.width)
return UIImageOrientationDown; //return UIInterfaceOrientationPortraitUpsideDown;
else
return UIImageOrientationUp; //return UIInterfaceOrientationPortrait;
}
这是其余的裁剪代码:
- (AVAssetExportSession*)applyCropToVideoWithAsset:(AVAsset*)asset AtRect:(CGRect)cropRect OnTimeRange:(CMTimeRange)cropTimeRange ExportToUrl:(NSURL*)outputUrl ExistingExportSession:(AVAssetExportSession*)exporter WithCompletion:(void(^)(BOOL success, NSError* error, NSURL* videoUrl))completion
{
// NSLog(@"CALLED");
//create an avassetrack with our asset
AVAssetTrack *clipVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
//create a video composition and preset some settings
AVMutableVideoComposition* videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.frameDuration = CMTimeMake(1, 30);
CGFloat cropOffX = cropRect.origin.x;
CGFloat cropOffY = cropRect.origin.y;
CGFloat cropWidth = cropRect.size.width;
CGFloat cropHeight = cropRect.size.height;
// NSLog(@"width: %f - height: %f - x: %f - y: %f", cropWidth, cropHeight, cropOffX, cropOffY);
videoComposition.renderSize = CGSizeMake(cropWidth, cropHeight);
//create a video instruction
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = cropTimeRange;
AVMutableVideoCompositionLayerInstruction* transformer = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack];
UIImageOrientation videoOrientation = [self getVideoOrientationFromAsset:asset];
CGAffineTransform t1 = CGAffineTransformIdentity;
CGAffineTransform t2 = CGAffineTransformIdentity;
switch (videoOrientation) {
case UIImageOrientationUp:
t1 = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.height - cropOffX, 0 - cropOffY );
t2 = CGAffineTransformRotate(t1, M_PI_2 );
break;
case UIImageOrientationDown:
t1 = CGAffineTransformMakeTranslation(0 - cropOffX, clipVideoTrack.naturalSize.width - cropOffY ); // not fixed width is the real height in upside down
t2 = CGAffineTransformRotate(t1, - M_PI_2 );
break;
case UIImageOrientationRight:
t1 = CGAffineTransformMakeTranslation(0 - cropOffX, 0 - cropOffY );
t2 = CGAffineTransformRotate(t1, 0 );
break;
case UIImageOrientationLeft:
t1 = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.width - cropOffX, clipVideoTrack.naturalSize.height - cropOffY );
t2 = CGAffineTransformRotate(t1, M_PI );
break;
default:
NSLog(@"no supported orientation has been found in this video");
break;
}
CGAffineTransform finalTransform = t2;
[transformer setTransform:finalTransform atTime:kCMTimeZero];
//add the transformer layer instructions, then add to video composition
instruction.layerInstructions = [NSArray arrayWithObject:transformer];
videoComposition.instructions = [NSArray arrayWithObject: instruction];
//Remove any prevouis videos at that path
[[NSFileManager defaultManager] removeItemAtURL:outputUrl error:nil];
if (!exporter){
exporter = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetHighestQuality] ;
}
// assign all instruction for the video processing (in this case the transformation for cropping the video
exporter.videoComposition = videoComposition;
exporter.outputFileType = AVFileTypeQuickTimeMovie;
if (outputUrl){
exporter.outputURL = outputUrl;
[exporter exportAsynchronouslyWithCompletionHandler:^{
switch ([exporter status]) {
case AVAssetExportSessionStatusFailed:
NSLog(@"crop Export failed: %@", [[exporter error] localizedDescription]);
if (completion){
dispatch_async(dispatch_get_main_queue(), ^{
completion(NO,[exporter error],nil);
});
return;
}
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"crop Export canceled");
if (completion){
dispatch_async(dispatch_get_main_queue(), ^{
completion(NO,nil,nil);
});
return;
}
break;
default:
break;
}
if (completion){
dispatch_async(dispatch_get_main_queue(), ^{
completion(YES,nil,outputUrl);
});
}
}];
}
return exporter;
}
所以我的问题是,当我使用完全相同的坐标和正方形大小时,为什么视频区域与裁剪/相机区域不同?
【问题讨论】:
-
可以肯定的是,一旦执行裁剪的视频(所以在完成块中)应该保存在 iphone 磁盘上。请直接检查该文件,我的意思是访问该文件(将 iphone 连接到 mac,并使用 iExplorer 或 iFunBox 等工具)。然后复制到mac上,用默认的mac快速播放器打开。通过这种方式,您将确保生成的裁剪视频与您在该正方形中看到的完全相同。此外,请确保裁剪区域对 x 和 y 轴都使用参考视图的正确坐标
-
@LucaIaco 好的,我正在使用 iExplorer 并将视频放在我的 Mac 上并快速播放,但裁剪区域仍然不正确。我一遍又一遍地查看坐标,我确信它们是正确的。我将在一个 git hub 项目上发布链接,这样你就可以下载并运行,如果你不介意的话,你可以自己看看。现在我正在拍摄一个绿色正方形的视频,并且只是裁剪部分中的正方形,但是当它被裁剪时我看到了白色。如果您查看项目,我将不胜感激
-
这里是正确的链接github.com/spennyf/cropVid
-
@LucaIaco 你能自己尝试一下吗?
-
我会尽快尝试 ;)
标签: ios xcode video cgrect avasset