首页 > 解决方案 > 使用 AVAssetExportSession 合并音频

问题描述

我想合并两个音频文件而没有太多的开销时间。下面的代码成功地合并了音频,但花费的时间太长(超过 30 秒超过几分钟的音频),我想知道是否有任何方法可以加快这个过程。我在几个地方阅读过AVAssetExportPresetPassthrough,但我似乎无法让该预设适用于任何文件类型。我能够开始工作的唯一设置是使用AVAssetExportPresetAppleM4A和导出为.m4a

创建 AVAssetExportSession 的代码

if (audioHasBeenRecorded) {
  // Merge recordings
  let composition = AVMutableComposition()
  let compositionAudioTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)

  guard let start = recorder.timeStart else { return }
  
  compositionAudioTrack?.insert(originalRecording: FileManagerHelper.recordingLocalURL(secondRecording: false), insertedRecording: FileManagerHelper.recordingLocalURL(secondRecording: true), startTime: CMTime(seconds: start, preferredTimescale: 1000000))

  if let assetExport = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A) {
    print(assetExport.supportedFileTypes)
    assetExport.outputFileType = AVFileType.m4a
    assetExport.outputURL = FileManagerHelper.recordingLocalURL(secondRecording: false)
    do { // Delete old audio
        try FileManager.default.removeItem(at: FileManagerHelper.recordingLocalURL(secondRecording: false))
        try FileManager.default.removeItem(at: FileManagerHelper.recordingLocalURL(secondRecording: true))
    } catch { log(error.localizedDescription, msgType: .error) }
   
    assetExport.exportAsynchronously(completionHandler: {
      if let error = assetExport.error {
        log(error, msgType: .error)
      } else {
        log("Successfully merged recordings!", msgType: .error)
        self.idea.numberOfPoints = self.audioVisualizer.count
        self.idea.save()
        
        self.setupPlayer() // Prepare to play the recorded audio file
        self.seekTo(TimeInterval((recorder.timeStart ?? 0) + (recorder.timeEnd ?? 0)))
        DispatchQueue.main.async { [ weak self ] in
          guard let self = self else { return }
          self.audioVisualizer.visualize(self.idea)
        }
      }
    })
  }
}

插入代码:

extension AVMutableCompositionTrack {
  func insert(originalRecording: URL, insertedRecording: URL, startTime: CMTime) {
    let originalAsset = AVURLAsset(url: originalRecording)
    let insertedAsset = AVURLAsset(url: insertedRecording)

    let range1 = CMTimeRangeMake(start: CMTime.zero, duration: startTime)
    let range2 = CMTimeRangeMake(start: CMTime.zero, duration: insertedAsset.duration)
    let range3 = CMTimeRangeMake(start: startTime + insertedAsset.duration, duration: originalAsset.duration - startTime)
    if let originalTrack = originalAsset.tracks(withMediaType: AVMediaType.audio).first,
       let insertedTrack = insertedAsset.tracks(withMediaType: AVMediaType.audio).first {
         try? insertTimeRange(range1, of: originalTrack, at: CMTime.zero)
         try? insertTimeRange(range2, of: insertedTrack, at: startTime)
         try? insertTimeRange(range3, of: originalTrack, at: startTime + insertedAsset.duration)
    }
  }
}

标签: iosswiftavassetexportsession

解决方案


推荐阅读