Negru video CAAnimation și AVFoundation AVAssetExportSession

Sunt un începător relativ pe întregul circuit de editare video AVFoundation.

Aplicația curentă de testare este o aplicație cu două ecrane, primul ecran face o înregistrare video AVFoundation (1.mov), iar al doilea ecran vă permite să vizualizați videoclipul și să acordați câteva credite pentru titlu cu un CAAnimation.

Fișierul video 1.mov este înregistrat în portret salvat pe disc și apoi este executat prin această rutină care ar trebui să-mi dea un titlu pe partea de sus a videoclipului. Cu toate acestea, tot ce primesc este un videoclip negru cu dimensiunile corecte, lungime de timp cu CATextLayer pe ea.

Sunt destul de sigur că am lipsit ceva de bază. Am un cod care ar trebui să se ocupe de întreaga rotire a portretului peisaj.

-(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

2 răspunsuri

Problema a fost cu următoarele rânduri.

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

Modificarea dimensiunii videoSize.width la 320 și videoSize.height = 480 au rezolvat problema.

0
adăugat

Dar dacă mărimea videoclipului nu va fi 320X480, se va mizeria. Încearcă să-l folosești pentru a obține dimensiunea videoclipului.

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