2012-06-04 1 views
1

전 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"); 


} 

답변

1

문제는 다음 줄에서 발생했습니다. 320 videoSize.width 변경

parentLayer.frame = CGRectMake(0,0, videoSize.width, videoSize.height); 
videoLayer.frame = CGRectMake(0,0, videoSize.width, videoSize.height); 

및 videoSize.height 480 문제를 해결.

0

그러나 비디오의 크기가 320X480이되지 않으면 엉망이됩니다. 이것을 사용하여 비디오 크기를 얻으십시오.

 CGSize videoSize = [[[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] naturalSize];