Как объединить аудио с видео без потери оригинального звука видео - iOS Swift - PullRequest
0 голосов
/ 14 февраля 2019

Моя цель - объединить аудио (музыку в формате mp3) с видео, снятым камерой iPhone. Я могу объединить аудио и видео с помощью AVMutableComposition, но в конечном выводе видео не воспроизводится.

нижекод, который я использую:

    open func mergeVideoWithAudio(videoUrl: URL, audioUrl: URL){

    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)
    }

    let time = CMTimeMakeWithSeconds(Float64(musicTrimmerController.currentPlayerPosition), 1000)

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

            try mutableCompositionAudioTrack.first?.insertTimeRange(CMTimeRangeMake(time, aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: kCMTimeZero)

        } catch{
            print(error)
        }

        totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,aVideoAssetTrack.timeRange.duration)

        let compositionV = mixComposition.tracks(withMediaType: AVMediaType.video).last
        if ((aVideoAssetTrack != nil) && (compositionV != nil)) {
            compositionV?.preferredTransform = (aVideoAssetTrack.preferredTransform)
        }
    }
    if let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
        let outputURL = URL(fileURLWithPath: documentsPath).appendingPathComponent("movie.mov")
        do {
            if FileManager.default.fileExists(atPath: outputURL.path) {
                try FileManager.default.removeItem(at: outputURL)
            }
        } catch { }
        if let exportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) {0
            exportSession.outputURL = outputURL
            exportSession.outputFileType = AVFileType.mp4
            exportSession.shouldOptimizeForNetworkUse = true

            /// try to export the file and handle the status cases
            exportSession.exportAsynchronously(completionHandler: {
                switch exportSession.status {
                case .failed:
                    print(exportSession.error as Any)
                case .cancelled:
                    print(exportSession.error as Any)
                default:
                    print("Save video output")
                }
            })
        }
    }
}
...