Swift Merging audio and video files into one video

83 Views Asked by At

I wrote a program in Swift.I want to merge a video with an audio file, but got this error.

"failed Error Domain=AVFoundationErrorDomain Code=-11838 "Operation Stopped" UserInfo=0x17da4230 {NSLocalizedDescription=Operation Stopped, NSLocalizedFailureReason=The operation is not supported for this media.}" Code

    func mergeVideoWithAudio(videoUrl: URL, audioUrl: URL, success: @escaping ((URL) -> Void), failure: @escaping ((Error?) -> Void)) {


        let mixComposition: AVMutableComposition = AVMutableComposition()
        var mutableCompositionVideoTrack: [AVMutableCompositionTrack] = []
        var mutableCompositionAudioTrack: [AVMutableCompositionTrack] = []
        let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()

        let aVideoAsset: AVAsset = AVAsset(url: videoUrl)
        let aAudioAsset: AVAsset = AVAsset(url: audioUrl)

        if let videoTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid), let audioTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid) {
            mutableCompositionVideoTrack.append(videoTrack)
            mutableCompositionAudioTrack.append(audioTrack)

        if let aVideoAssetTrack: AVAssetTrack = aVideoAsset.tracks(withMediaType: .video).first, let aAudioAssetTrack: AVAssetTrack = aAudioAsset.tracks(withMediaType: .audio).first {
            do {
                try mutableCompositionVideoTrack.first?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: CMTime.zero)
                try mutableCompositionAudioTrack.first?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: CMTime.zero)
                   videoTrack.preferredTransform = aVideoAssetTrack.preferredTransform

            } catch{
                print(error)
            }

           totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(start: CMTime.zero,duration: videoTrack.timeRange.duration)
          }
        }

        let mutableVideoComposition: AVMutableVideoComposition = AVMutableVideoComposition()
        mutableVideoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
        mutableVideoComposition.renderSize = CGSize(width: 480, height: 640)

        if let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
            let outputURL = URL(fileURLWithPath: documentsPath).appendingPathComponent("\("fileName").mp4")

            do {
                if FileManager.default.fileExists(atPath: outputURL.path) {

                    try FileManager.default.removeItem(at: outputURL)
                }
            } catch { }


//        var outputURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("temp_video_data.mp4", isDirectory: false)
//        outputURL = URL(fileURLWithPath: outputURL.path)

//            let mediaItems = MPMediaQuery.songs().items
//            let mediaCollection = MPMediaItemCollection(items: mediaItems ?? [])
//            let player1 = MPMusicPlayerController.systemMusicPlayer
//            player1.setQueue(with: mediaCollection)
//            player1.play()


//            guard let url = URL(string: url )else {return}
//            let player = AVPlayer(url: url)
//            let playerController = AVPlayerViewController()
//            playerController.player = player
//            playerController.allowsPictureInPicturePlayback = true
//            playerController.delegate = self
//            playerController.player?.play()
//            present(playerController, animated: true, completion: nil)


//            let player3 = AVPlayer(url: vidUrl!)
//            let playerLayer3 = AVPlayerLayer(player: player3)
//            playerLayer3.videoGravity = .resizeAspect
//            playerLayer3.needsDisplayOnBoundsChange = true //
//            playerLayer3.frame = self.videoImg.bounds // 1
//
//            self.videoImg.layer.masksToBounds = true // 2
//            self.videoImg.layer.addSublayer(playerLayer3)
//            player3.play()




//            let assetsLib = PHPhotoLibrary()
//            assetsLib.
//            assetsLib.writeVideoAtPath(toSavedPhotosAlbum: outputURL, completionBlock: nil)

            print(outputURL, "outputURL.....")
            if let exportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) {
                exportSession.outputURL = NSURL.fileURL(withPath: outputURL.path)
                exportSession.outputFileType = AVFileType.mov
                exportSession.shouldOptimizeForNetworkUse = true

                // try to export the file and handle the status cases
                exportSession.exportAsynchronously(completionHandler: {
                    switch exportSession.status {
                    case .failed:
                        if let _error = exportSession.error {
                            print("failedddd",_error)

                            failure(_error)
                        }

                    case .cancelled:
                        if let _error = exportSession.error {
                            print("cancellled")
                            failure(_error)
                        }

                    default:
                        print("finished")
                        success(outputURL)
                    }
                })
            } else {
                print("failurrrrrrrr")
                failure(nil)
            }
        }
    }

Here the calling of Function

let vidUrl! = file:///private/var/mobile/Containers/Data/PluginKitPlugin/C6BD4529-DF11-4A67-B56E-C3A841D86D75/tmp/trim.CC7EABA8-08EC-4C33-8E6A-E85A5EBCFB64.MOV
let outputURL! = file:///var/mobile/Containers/Data/Application/9115DCFE-4134-48AD-84BF-452AC0D33278/Documents/y2matecom-ChallaOfficialFullVideoKhanSaabAYMediaRecordsLatestPunjabiSongs2016.mp3

    mergeVideoWithAudio(videoUrl: vidUrl!, audioUrl: outputURL!) { resultUrl in
                            print("sucessssssssss",resultUrl)
                        } failure: { error in
                            print(error?.localizedDescription,"hgjjhfghdg")
    
                        }

Note:Every time the Failure Block calls and cause operation stopped

In my idea media type like mpeg4 is wrong. Where is the problem? What am i missing?

0

There are 0 best solutions below