How to record video with overlay view

Hi I am trying to record video with overlay.

I have written:

  • Decoding H264 VideoToolkit API fails with Error -8971 in VTDecompressionSessionCreate
  • How to crop a video to a circle in iOS?
  • GPUImage Video with transparency over UIView
  • Video merging in background iOS
  • Alternative to ffmpeg for iOS
  • MOV to Mp4 video conversion iPhone Programmatically
  • -(void)addOvelayViewToVideo:(NSURL *)videoURL
    

    to add overlay view on recorded video but it is not working.

    I written the code to record video in viewDidLoad using AVCaptureSession.

    //In ViewDidLoad
    //CONFIGURE DISPLAY OUTPUT
    self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
    [self.previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    self.previewLayer.frame = self.view.frame;
    [self.view.layer addSublayer:self.previewLayer];
    
    
    -(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
    {
        if(error.code != noErr)
        {
            id value = [[error userInfo] objectForKey:AVErrorRecordingSuccessfullyFinishedKey];
            if(value)
            {
                isSuccess = [value boolValue];
            }
        }
    
        if(isSuccess)
        {
            ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
            if([assetsLibrary videoAtPathIsCompatibleWithSavedPhotosAlbum:outputFileURL])
            {
                [self addOverviewToVideo:outputFileURL];
            }
            else{
                NSLog(@"could not saved to photos album.");
            }
        }
    
    }
    
    
    -(void)addOvelayViewToVideo:(NSURL *)videoURL
    {
        AVAsset *asset = [AVAsset assetWithURL:videoURL];
        AVMutableComposition *composition = [[AVMutableComposition alloc] init];
    
        AVMutableCompositionTrack *compositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
        [compositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];
        AVMutableVideoCompositionInstruction *compositionInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
        compositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
        AVMutableVideoCompositionLayerInstruction *videoLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionTrack];
        AVAssetTrack *assetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    
        UIImageOrientation videoAssetOrientation_  = UIImageOrientationUp;
        BOOL isVideoAssetPortrait_  = NO;
        CGAffineTransform videoTransform = assetTrack.preferredTransform;
        if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) {
            videoAssetOrientation_ = UIImageOrientationRight;
            isVideoAssetPortrait_ = YES;
        }
        if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) {
            videoAssetOrientation_ =  UIImageOrientationLeft;
            isVideoAssetPortrait_ = YES;
        }
        if (videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0) {
            videoAssetOrientation_ =  UIImageOrientationUp;
        }
        if (videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0) {
            videoAssetOrientation_ = UIImageOrientationDown;
        }
        [videoLayerInstruction setTransform:assetTrack.preferredTransform atTime:kCMTimeZero];
        [videoLayerInstruction setOpacity:0.0 atTime:asset.duration];
    
    
    
        compositionInstruction.layerInstructions = [NSArray arrayWithObject:videoLayerInstruction];
        AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    
        CGSize naturalSize = CGSizeMake(assetTrack.naturalSize.height, assetTrack.naturalSize.width);
        float renderWidth, renderHeight;
        renderWidth = naturalSize.width;
        renderHeight = naturalSize.height;
        videoComposition.renderSize = CGSizeMake(renderWidth, renderHeight);
        videoComposition.instructions = [NSArray arrayWithObject:compositionInstruction];
        videoComposition.frameDuration = CMTimeMake(1, 30);
    
    
        CALayer *overlayLayer = [CALayer layer];
        UIImage *overlayImage = [UIImage imageNamed:@"sampleHUD"];
        [overlayLayer setContents:(id)[overlayImage CGImage]];
        overlayLayer.frame = CGRectMake(0, 0, naturalSize.width, naturalSize.height);
        [overlayLayer setMasksToBounds:YES];
    
        CALayer *parentLayer = [CALayer layer];
        CALayer *videoLayer = [CALayer layer];
        parentLayer.frame = CGRectMake(0, 0, naturalSize.width, naturalSize.height);
        videoLayer.frame = CGRectMake(0, 0, naturalSize.width, naturalSize.height);
        [parentLayer addSublayer:videoLayer];
        [parentLayer addSublayer:overlayLayer];
    
        videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
        NSLog(@"renderSize:%f,%f", videoComposition.renderSize.width, videoComposition.renderSize.height);
    
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality];
        exportSession.outputURL = videoURL;
        exportSession.outputFileType = AVFileTypeQuickTimeMovie;
        exportSession.shouldOptimizeForNetworkUse = YES;
        exportSession.videoComposition = videoComposition;
        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            dispatch_async(dispatch_get_main_queue(), ^{
                //save the video in photos album
            });
        }];
    
    }
    

    I am still unable to figure out what is going wrong here. Need guidance on this.

    Can I add overlay while recording video?

    Any help will be appreciated.