2012-06-04 51 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

問題在於以下幾行。

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

將videoSize.width更改爲320,並將videoSize.height = 480修復爲問題。

0

但是,如果視頻的大小不會是320X480,它會搞砸。嘗試使用這一個來獲得視頻大小。

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