我是整个AVFoundation视频编辑电路的新手。
我当前的测试应用程序是一个双屏应用程序,第一个屏幕执行AVFoundation视频录制(1.mov),第二个屏幕允许您查看视频并使用CAAnimation在其上放置一些标题信用。
1.mov视频文件以纵向方式保存到磁盘中,然后通过此例程运行,这应该在视频上方给我一个标题。然而,我得到的只是一个正确尺寸的黑色视频,其上有CATextLayer的时间长度。
我很确定我错过了一些基本的东西。我确实有代码可以处理整个横向纵向旋转。
-(IBAction)ComposeMovie:(id)sender {
NSLog (@"ComposeMovie");
CALayer *aLayer = [CALayer layer];
aLayer.Frame = CGRectMake(0, 0, videoSize.height, videoSize.width);
CALayer *bLayer = [CALayer layer];
NSLog(@"Create the title");
CATextLayer *titleLayer = [CATextLayer layer];
titleLayer.string = @"SUDO make me a sandwich";
titleLayer.font = [UIFont boldSystemFontOfSize:18].fontName;
titleLayer.backgroundColor = [UIColor whiteColor].CGColor;
titleLayer.foregroundColor = [UIColor blackColor].CGColor;
titleLayer.fontSize = 24;
titleLayer.alignmentMode = kCAAlignmentRight;
titleLayer.bounds = CGRectMake(videoSize.width, videoSize.height /6, 300, 32);
[aLayer addSublayer:titleLayer];
NSURL *url = [NSURL fileURLWithPath:getCaptureMoviePath()]; //Hard coded path to the 1.mov file in the documents directory
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
AVMutableComposition *cmp = [[AVMutableComposition alloc] init] ;
AVMutableCompositionTrack *trackA = [cmp addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
NSError *error = nil ;
AVAssetTrack *sourceVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[trackA insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:sourceVideoTrack atTime:kCMTimeZero error:&error] ;
AVMutableVideoComposition *animComp = [[AVMutableVideoComposition videoComposition] retain];
animComp.renderSize = CGSizeMake(videoSize.height, videoSize.width);
animComp.frameDuration = CMTimeMake(1,30);
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30) );
AVMutableVideoCompositionLayerInstruction* rotator = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]];
CGAffineTransform translateToCenter = CGAffineTransformMakeTranslation( 0,-320);
CGAffineTransform rotateBy90Degrees = CGAffineTransformMakeRotation( M_PI_2);
CGAffineTransform shrinkWidth = CGAffineTransformMakeScale(0.66, 1); // needed because Apple does a "stretch" by default - really, we should find and undo apple's stretch - I suspect it'll be a CALayer defaultTransform, or UIView property causing this
CGAffineTransform finalTransform = CGAffineTransformConcat( shrinkWidth, CGAffineTransformConcat(translateToCenter, rotateBy90Degrees) );
[rotator setTransform:finalTransform atTime:kCMTimeZero];
instruction.layerInstructions = [NSArray arrayWithObject: rotator];
animComp.instructions = [NSArray arrayWithObject: instruction];
NSLog(@"Creating Animation");
//animComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithAdditionalLayer: asTrackID:1];
animComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithAdditionalLayer:aLayer asTrackID:2];
animComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithAdditionalLayer:bLayer asTrackID:3];
//AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [asset duration]);
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:trackA];
//[layerInstruction setTrackID:1];
/*CMTime startTime = CMTimeMake(3,1);
CMTime stopTime = CMTimeMake(5,1);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
*/
//AVMutableVideoCompositionLayerInstruction *passThroughLayer = AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(degreesToRadians(90.0));
CGAffineTransform rotateTranslate = CGAffineTransformTranslate(rotationTransform,320,0);
[layerInstruction setTransform:rotateTranslate atTime:kCMTimeZero];
[layerInstruction setOpacity:1.0 atTime:kCMTimeZero ];
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
animComp.instructions = [NSArray arrayWithObject:instruction];
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:aLayer];
[parentLayer addSublayer:bLayer];
[parentLayer addSublayer:videoLayer];
animComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
NSLog(@"Creating File");
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *tempPath = [docPaths objectAtIndex:0];
NSLog(@"Temp Path: %@",tempPath);
NSString *fileName = [NSString stringWithFormat:@"%@/render.MOV",tempPath];
NSFileManager *fileManager = [NSFileManager defaultManager] ;
if([fileManager fileExistsAtPath:fileName ]){
NSError *ferror = nil ;
BOOL success = [fileManager removeItemAtPath:fileName error:&ferror];
}
NSURL *exportURL = [NSURL fileURLWithPath:fileName];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:cmp presetName:AVAssetExportPresetHighestQuality] ;
exporter.outputURL = exportURL;
exporter.videoComposition = animComp ;
exporter.outputFileType= AVFileTypeQuickTimeMovie ;
[exporter exportAsynchronouslyWithCompletionHandler:^(void){
switch (exporter.status) {
case AVAssetExportSessionStatusFailed:{
NSLog(@"Fail");
break;
}
case AVAssetExportSessionStatusCompleted:{
NSLog(@"Success");
break;
}
default:
break;
}
}];
NSLog(@"End ComposeMovie");
}
答案 0 :(得分:1)
问题在于以下几行。
parentLayer.frame = CGRectMake(0,0, videoSize.width, videoSize.height);
videoLayer.frame = CGRectMake(0,0, videoSize.width, videoSize.height);
将videoSize.width更改为320,而videoSize.height = 480修复了此问题。
答案 1 :(得分:0)
但如果视频的大小不是320X480,那就会搞砸。尝试使用此视频来获取视频大小。
CGSize videoSize = [[[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize];