【问题标题】:Mix video with static image in CALayer using AVVideoCompositionCoreAnimationTool使用 AVVideoCompositionCoreAnimationTool 在 CALayer 中将视频与静态图像混合
【发布时间】:2011-08-25 06:09:21
【问题描述】:

我正在尝试将来自相机的视频与静态图像(水印)混合。

我检查了这里的问题/答案和一些示例,包括来自 Apple 的 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;
    }
}];

}

【问题讨论】:

    标签: objective-c ios ios4 calayer avfoundation


    【解决方案1】:

    在玩了之后,除了上面的代码之外,我最终得到了类似的东西,还将使用的方法更改为 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];
    

    希望对某人有所帮助。

    【讨论】:

    • 我遇到了类似的问题(请参阅here),但出了点问题。你觉得你能帮到我吗?
    【解决方案2】:

    我得到了这个工作!这是代码!我没有写大部分,我只是调整了一些,但唯一的问题是视频本身在纵向模式下旋转为横向?然后是横向的纵向视频,但图像是正面朝上的!

    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;
        } 
    }];
    

    }

    【讨论】:

    • 请使用图层数组而不是图层 -> myVideoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayers:[NSArray arrayWithObjects:videoLayer, nil] inLayer:parentLayer];
    猜你喜欢
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 2019-05-23
    相关资源
    最近更新 更多