Swift Слияние аудио и видео Swift3

У меня есть одно видео, и я объединяю другой звук с этим видео, поэтому прямо сейчас у меня есть два аудио с этим видео, один - оригинальный звук, а другой - собственный звук видео. Теперь проблема в том, что я могу установить громкость для собственного звука видео, но не могу установить громкость внешнего звука. Я использовал следующий код, чтобы сделать то же самое.

func mergeAV(videoUrl: URL, audioUrl: URL, shouldFlipHorizontally: Bool = false) {
    print("\(#function)")
    process_merge.startAnimating()

    let mixComposition = AVMutableComposition()
    var mutableCompositionVideoTrack = [AVMutableCompositionTrack]()
    var mutableCompositionAudioTrack = [AVMutableCompositionTrack]()
    var mutableCompositionAudioOfVideoTrack = [AVMutableCompositionTrack]()

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

    let compositionAddVideo = mixComposition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)
    let compositionAddAudio = mixComposition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)
    let compositionAddAudioOfVideo = mixComposition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)

    let aVideoAssetTrack: AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaType.video)[0]
    let aAudioOfVideoAssetTrack: AVAssetTrack? = aVideoAsset.tracks(withMediaType: AVMediaType.audio).first
    let aAudioAssetTrack: AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaType.audio)[0]

    compositionAddVideo?.preferredTransform = aVideoAssetTrack.preferredTransform

    mutableCompositionVideoTrack.append(compositionAddVideo!)
    mutableCompositionAudioTrack.append(compositionAddAudio!)
    mutableCompositionAudioOfVideoTrack.append(compositionAddAudioOfVideo!)

    do {
        try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: CMTime.zero)

        try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: CMTime.zero)

        if let aAudioOfVideoAssetTrack = aAudioOfVideoAssetTrack {
            try mutableCompositionAudioOfVideoTrack[0].insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: aVideoAssetTrack.timeRange.duration), of: aAudioOfVideoAssetTrack, at: CMTime.zero)
        }

    } catch {
        print(error.localizedDescription)
    }

    // Exporting
    let fileManager = FileManager.default
    let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let savePathUrl = documentsDirectory.appendingPathComponent("MergeAudioVideo.mp4")

    do {
        // delete old video
        try FileManager.default.removeItem(at: savePathUrl)
    } catch {
        print(error.localizedDescription)
    }

    var videoVolume : Float = 0.0
    var audioVolume : Float = 0.0
    videoVolume = self.vol_Video.value
    audioVolume = self.vol_Audio.value

    let audioMix: AVMutableAudioMix = AVMutableAudioMix()
    var audioMixParam: [AVMutableAudioMixInputParameters] = []

    let videoParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: aVideoAssetTrack)
    videoParam.trackID = (compositionAddVideo?.trackID)!

    let musicParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: aAudioAssetTrack)
    musicParam.trackID = (compositionAddAudio?.trackID)!

    videoParam.setVolume(videoVolume, at: CMTime.zero)
    musicParam.setVolume(audioVolume, at: CMTime.zero)

    videoParam.setVolumeRamp(fromStartVolume: videoVolume, toEndVolume: videoVolume, timeRange: aVideoAssetTrack.timeRange)
    musicParam.setVolumeRamp(fromStartVolume: videoVolume, toEndVolume: audioVolume, timeRange: aAudioAssetTrack.timeRange)

    audioMixParam.append(musicParam)
    audioMixParam.append(videoParam)

    audioMix.inputParameters = [musicParam,videoParam]

    let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)!
    assetExport.outputFileType = AVFileType.mp4
    assetExport.outputURL = savePathUrl
    assetExport.shouldOptimizeForNetworkUse = true
    assetExport.audioMix = audioMix

    print("Export Action")
    assetExport.exportAsynchronously { () -> Void in
        self.process_merge.stopAnimating()

        switch assetExport.status {
        case AVAssetExportSession.Status.completed:
            print("Merge video+Audio URL : \(savePathUrl)")
            print("Export : success")
            self.showMess(strMess: "Success...\nMerge video+Audio URL: \(savePathUrl)", isAlert: false)
            break

        default:
            print("Error : unknown")
            self.showMess(strMess: "Something was wrong. Please try again.\nError: \(assetExport.error?.localizedDescription ?? "unknown")", isAlert: true)
            break
        }
    }
}

Как я могу это решить? Пожалуйста помоги!

Привет @Khush, мне нужна твоя помощь при слиянии видео и аудио ...

Ahtazaz 09.04.2019 14:50

в моем случае у меня есть ВИДЕО АКТИВ, содержащий аудио, но я не знаю, почему я получаю пустой массив? ЕСЛИ я делаю ВИДЕО в течение 3-5 секунд, тогда я не получаю никаких ошибок, потому что массив не пуст, НО если я создаю видео продолжительностью более 5, 6 секунд, и это видео также содержит AUDIo, тогда в этом случае я получаю ПУСТОЙ МАССИВ (ИНДЕКС ЗА ПРЕДЕЛАМИ ГРАНИЦЫ), и он выходит из строя ... Можете ли вы мне помочь через [email protected]?

Ahtazaz 09.04.2019 14:53

Привет, @ мистер Ахтазаз, извините за опоздание, вы уже решили это? или все еще сталкивается с проблемой?

Khush 18.04.2019 08:37

Привет @Khush. да решено. Большое Вам спасибо...

Ahtazaz 18.04.2019 08:40

Подскажите, пожалуйста, в чем причина аварии?

Khush 18.04.2019 08:41

это была моя ошибка ...

Ahtazaz 18.04.2019 09:07
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
6
1 041
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
func mergeFilesWithUrl(videoUrl: URL, audioUrl: URL) {

    let mixComposition: AVMutableComposition = AVMutableComposition()

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

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

    mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid))
    mutableCompositionAudioTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))
    mutableCompositionAudioOfVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))

    let aAudioOfVideoTrack: AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeAudio)[0]
    let aVideoAssetTrack: AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0]
    let aAudioAssetTrack: AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaTypeAudio)[0]

    do {
        try mutableCompositionAudioOfVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aAudioOfVideoTrack, at: kCMTimeZero)
        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 {

    }

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

    let mutableVideoComposition: AVMutableVideoComposition = AVMutableVideoComposition()
    mutableVideoComposition.frameDuration = CMTimeMake(1, 30)

    mutableVideoComposition.renderSize = CGSize(width: 1280, height: 720)//CGSize(1280,720)

    //find your video on this URl
    let savePathUrl: NSURL = NSURL(fileURLWithPath: NSHomeDirectory() + "/Documents/newVideo.mp4")

    do { // delete old video
        try FileManager.default.removeItem(at: savePathUrl as URL)
    } catch {
        print(error.localizedDescription)
    }

    let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)!
    assetExport.outputFileType = AVFileTypeMPEG4
    assetExport.outputURL = savePathUrl as URL
    assetExport.shouldOptimizeForNetworkUse = true

    assetExport.exportAsynchronously {
        switch assetExport.status {
        case AVAssetExportSessionStatus.completed:
            print("success")
        case AVAssetExportSessionStatus.failed:
            print("failed \(assetExport.error)")
        case AVAssetExportSessionStatus.cancelled:
            print("cancelled \(assetExport.error)")
        default:
            print("complete")
        }
    }
}

Другие вопросы по теме