전 AVFoundation 비디오 편집 회로에서 상대적으로 초보자입니다.검은 색 비디오 CAAnimation 및 AVFoundation AVAssetExportSession
내 현재 테스트 응용 프로그램은 두 화면 응용 프로그램이며 첫 번째 화면은 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");
}