2011-05-13 6 views
15

カメラから静的な画像(ウォーターマーク)を使用してビデオをミックスしようとしています。AVVideoCompositionCoreAnimationToolを使用してCALayerでビデオを静止画とミックスします

アップルのWWDC AVEditDemoを含むいくつかの質問/回答を確認し、次のコードで終了しました。 残念ながら、書き出されたビデオには画像のレイヤーが含まれていません。 アイデア

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { 

/// incoming video 
NSURL *videoURL = [info valueForKey:UIImagePickerControllerMediaURL]; 

/// UIImage into CALayer 
UIImage *myImage = [UIImage imageNamed:@"m1h.png"]; 
CALayer *aLayer = [CALayer layer]; 
aLayer.contents = (id)myImage.CGImage; 

AVURLAsset* url = [AVURLAsset URLAssetWithURL:videoURL options:nil]; 
AVMutableComposition *videoComposition = [AVMutableComposition composition]; 
NSError *error; 
NSFileManager *fileManager = [NSFileManager defaultManager]; 

AVMutableCompositionTrack *compositionVideoTrack = [videoComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
AVAssetTrack *clipVideoTrack = [[url tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [url duration]) ofTrack:clipVideoTrack atTime:kCMTimeZero error:&error]; 

AVMutableVideoComposition* videoComp = [[AVMutableVideoComposition videoComposition] retain]; 
videoComp.renderSize = CGSizeMake(640, 480); 
videoComp.frameDuration = CMTimeMake(1, 30); 
videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithAdditionalLayer:aLayer asTrackID:2]; 


/// instruction 
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30)); 
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:clipVideoTrack]; 
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction]; 
videoComp.instructions = [NSArray arrayWithObject: instruction]; 

/// outputs 
NSString *filePath = nil; 
filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
filePath = [filePath stringByAppendingPathComponent:@"temp.mov"]; 
NSLog(@"exporting to: %@", filePath); 
if ([fileManager fileExistsAtPath:filePath]) 
{ 
     BOOL success = [fileManager removeItemAtPath:filePath error:&error]; 
     if (!success) NSLog(@"FM error: %@", [error localizedDescription]); 
} 

/// exporting 
AVAssetExportSession *exporter; 
exporter = [[AVAssetExportSession alloc] initWithAsset:videoComposition presetName:AVAssetExportPresetHighestQuality] ; 
exporter.videoComposition = videoComp; 
exporter.outputURL=[NSURL fileURLWithPath:filePath]; 
exporter.outputFileType=AVFileTypeQuickTimeMovie; 

[statusLabel setText:@"processing..."]; 

[exporter exportAsynchronouslyWithCompletionHandler:^(void){ 
    switch (exporter.status) { 
     case AVAssetExportSessionStatusFailed: 
      NSLog(@"exporting failed"); 
      break; 
     case AVAssetExportSessionStatusCompleted: 
      NSLog(@"exporting completed"); 
      UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, @selector(video:didFinishSavingWithError:contextInfo:), NULL); 
      break; 
     case AVAssetExportSessionStatusCancelled: 
      NSLog(@"export cancelled"); 
      break; 
    } 
}]; 

}

答えて

10

遊ん後、私はまたvideoCompositionCoreAnimationToolWithPostProcessingAsVideoLayerに使用される方法を変更し、上記のコードに加えて、このようなものになってしまった:

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:videoLayer]; 
[parentLayer addSublayer:aLayer]; 
videoComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; 

は、それが誰かに役立ちます願っています。

+2

Iは、((参照[ここ]同様の問題を有していhttp://stackoverflow.com/questions/6749216/how-ありますavassetexportsとの間で適切にエクスポートすることができます))、何かが間違っています。あなたが私を助けることができると思いますか? –

2

私はこれを動作させました!コードをheres!私はほとんどそれを書いていない、私はちょうどいくつかを微調整しましたが、唯一の問題は、ビデオ自体が風景モードのポートレートモードで回転されていますか?その横長の肖像画のビデオでは、しかし、画像は右上です!

CALayer *aLayer = [CALayer layer]; 
    aLayer.frame = CGRectMake(5, 0, 320, 480); 
    aLayer.bounds = CGRectMake(5, 0, 320, 480); 
    aLayer.contents = (id) [UIImage imageNamed:@"image.png"].CGImage; 
    aLayer.opacity = 0.5; 
    aLayer.backgroundColor = [UIColor clearColor].CGColor; 
    NSURL *url = [NSURL fileURLWithPath:[urlsOfVideos objectAtIndex:self.pageControl.currentPage]]; 
    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil]; 
    cmp = [AVMutableComposition composition]; 

    AVMutableCompositionTrack *trackA = [cmp addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
    AVAssetTrack *sourceVideoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]; 
    [trackA insertTimeRange:CMTimeRangeMake(kCMTimeZero, [asset duration]) ofTrack:sourceVideoTrack atTime:kCMTimeZero error:nil] ; 

    animComp = [AVMutableVideoComposition videoComposition]; 
    animComp.renderSize = CGSizeMake(320, 480); 
    animComp.frameDuration = CMTimeMake(1,30); 
    CALayer *parentLayer = [CALayer layer]; 
    CALayer *videoLayer = [CALayer layer]; 
    parentLayer.frame = CGRectMake(0, 0, 320, 480); 
    videoLayer.frame = CGRectMake(0, 0, 320, 480); 
    [parentLayer addSublayer:videoLayer]; 
    [parentLayer addSublayer:aLayer]; 
    animComp.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer]; 
    AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [asset duration]); 
    AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:trackA]; 
    //[layerInstruction setTrackID:2]; 
    [layerInstruction setOpacity:1.0 atTime:kCMTimeZero]; 
    instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction] ; 
    animComp.instructions = [NSArray arrayWithObject:instruction]; 
    [self exportMovie:self]; 

、ここでエクスポートコード

-(IBAction) exportMovie:(id)sender{ 
NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *tempPath = [docPaths objectAtIndex:0]; 
NSLog(@"Temp Path: %@",tempPath); 

NSString *fileName = [NSString stringWithFormat:@"%@/output-anot.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; 
    } 
}]; 

}

+9

あなたのイメージはtits.pngではありませんか? –

+1

@NicolasManziniいいえ、appleの文書にはboobs.pngと書かれています – NSGodMode

+0

LMFAO。私の悪い。このコードは、私が会社で働いていたプロジェクトで使用されていて、コンテンツをチェックせずにコピー/ペーストしただけです。ああ、私。 – Maximilian

関連する問題