Mix video with static image in CALayer using AVVideoCompositionCoreAnimationTool

后端 未结 2 1588
悲哀的现实
悲哀的现实 2020-11-30 21:24

I am trying to mix video, coming from the camera with a static image (watermarking).

I have checked around questions/answers here and some examples, including WWDC A

相关标签:
2条回答
  • 2020-11-30 22:11

    i got this to work! heres the code! i didn't write most of it, i just tweaked some, but the only issue is the video itself is rotated for landscape in portrait mode? and then in landscape its portrait video, but the image is right side up!

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

    and here is the exporting code

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

    }

    0 讨论(0)
  • 2020-11-30 22:14

    After playing around I ended up with something like this in a addition to the above code, also changing the used method to 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];
    

    Hope it helps somebody.

    0 讨论(0)
提交回复
热议问题