How to merge 2 videos for one screen?

Viewed 550

I am making a karaoke app. I want to merge users videos like karaoke videos. Left side of screen one user and right side of screen other user. I can merge videos and audios but i did not understand how can i merge videos. Many of examples show that merge videos sequently.

func mergeMutableVideoWithAudio(videoUrl:URL, audioUrl:URL){
    let mixComposition : AVMutableComposition = AVMutableComposition()
    var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = []
    var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = []
    let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
    //start merge
    let aVideoAsset : AVAsset = AVAsset(url: videoUrl as URL)
    let aAudioAsset : AVAsset = AVAsset(url: audioUrl as URL)
    mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid))
    mutableCompositionAudioTrack.append( mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))
    let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0]
    let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaTypeAudio)[0]
    do{
        try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: kCMTimeZero)
        try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: kCMTimeZero)
    }catch{

    }

    mutableCompositionVideoTrack[0].preferredTransform = aVideoAssetTrack.preferredTransform

    totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,aVideoAssetTrack.timeRange.duration )
    let mutableVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition()
    mutableVideoComposition.frameDuration = CMTimeMake(1, 30)
    mutableVideoComposition.renderSize = CGSize(width: 480, height: 480)

    mergedAudioVideoURl = NSURL(fileURLWithPath: NSHomeDirectory() + "/Documents/FinalVideo.mp4")
    let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)!
    assetExport.outputFileType = AVFileTypeQuickTimeMovie
    assetExport.outputURL = mergedAudioVideoURl as URL
    removeFileAtURLIfExists(url: mergedAudioVideoURl)
    assetExport.shouldOptimizeForNetworkUse = false

    assetExport.exportAsynchronously { () -> Void in
        switch assetExport.status {
        case AVAssetExportSessionStatus.completed:
            let library = ALAssetsLibrary()
            library.writeVideoAtPath(toSavedPhotosAlbum: self.mergedAudioVideoURl as URL!, completionBlock: { (bool) in
                DispatchQueue.main.async {
                    UserModel.sharedInstance.isVideoMerged = true
                    let effect = self.view.subviews.last
                    effect?.removeFromSuperview()
                    self.popupViewController.dismiss(animated: true, completion: nil)
                }
            })
            print("-----Merge mutable video with trimmed audio exportation complete.\(self.mergedAudioVideoURl)")
        case  AVAssetExportSessionStatus.failed:
            print("failed \(String(describing: assetExport.error))")
        case AVAssetExportSessionStatus.cancelled:
            print("cancelled \(String(describing: assetExport.error))")
        default:
            print("complete")
        }
    }
}
0 Answers
Related