Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video overlay on a video using MTIBlendMode.screen #361

Open
2 tasks done
GustasCodes opened this issue May 23, 2023 · 0 comments
Open
2 tasks done

Video overlay on a video using MTIBlendMode.screen #361

GustasCodes opened this issue May 23, 2023 · 0 comments

Comments

@GustasCodes
Copy link

GustasCodes commented May 23, 2023

Hello. I'm trying to blend two videos together using MTIBlendMode.screen.
I've read similar question here: #302 and here #MetalPetal/VideoIO#26.

My code generates blended video but always in wrong dimensions. Let's say I blend two videos with different resolutions (they both are vertical). And in the blended video I can see that the main video became horizontal while overlay video is still vertical but scaled. Why that happens? How I should provide frame sizes? I also tried to set originalAsset naturalSize width and height for MultilayerCompositingFilter but no luck.

I expect my final video to be blended with overlay in the same resolution as originalAsset. (both originalAsset and overlayAsset always will be vertical).

Code:

    let overlayAsset = AVURLAsset(url: Bundle.main.url(forResource: "blendoverlay", withExtension: "mp4")!)
    
    // 1 - Create AVMutableComposition object. This object will hold your AVMutableCompositionTrack instances.
    let mixComposition = AVMutableComposition()

    // 2 - Create two video tracks
    guard let firstTrack = mixComposition.addMutableTrack(withMediaType: .video,
                                                          preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else { return }
    do {
        try firstTrack.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: originalAsset.duration),
                                       of: originalAsset.tracks(withMediaType: .video)[0],
                                       at: CMTime.zero)
    } catch {
        print("Failed to load first track")
        return
    }

    guard let secondTrack = mixComposition.addMutableTrack(withMediaType: .video,
                                                           preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else { return }
    do {
        try secondTrack.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: overlayAsset.duration),
                                        of: overlayAsset.tracks(withMediaType: .video)[0],
                                        at: CMTime.zero)
    } catch {
        print("Failed to load second track")
        return
    }
    
    // 3 - Blend videos
    
    let renderContext = try! MTIContext(device: MTLCreateSystemDefaultDevice()!)

    videoComposition = MTIVideoComposition(asset: mixComposition, context: renderContext, queue: DispatchQueue.main, filter: { request in
      let sourceImages = request.sourceImages
      guard let originalImage = sourceImages[originalAsset.tracks(withMediaType: .video)[0].trackID] else {
        return MTIImage.black
      }
      guard var overlayImage = sourceImages[overlayAsset.tracks(withMediaType: .video)[0].trackID] else {
        return MTIImage.black
      }
      
      let filter = MultilayerCompositingFilter()
      filter.layers = [ MultilayerCompositingFilter.Layer(content: overlayImage).frame(CGRect(x: 0, y: 0, width: 1, height: 1), layoutUnit: .fractionOfBackgroundSize)
        .blendMode(.screen)]
      filter.inputBackgroundImage = originalImage
      return filter.outputImage!
    })
    
    let playerItem = AVPlayerItem(asset: mixComposition)
    playerItem.videoComposition = videoComposition!.makeAVVideoComposition()
    self.videoComposition = videoComposition
    player.replaceCurrentItem(with: playerItem)
    player.play()
    completion(player)`

Checklist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant