Сбой AKNodeRecorder - PullRequest
       11

Сбой AKNodeRecorder

0 голосов
/ 07 сентября 2018

У меня есть следующий поток в моем приложении:

  1. Пользователь записывает аудио
  2. Применение эффектов к записанному звуку (или оставить все как есть)
  3. Приложение воспроизводит аудиофайл в автономном режиме.
  4. Затем пользователь может изменить эффект или перезаписать звук

Существует проблема с записью аудио, когда мы на последнем шаге и представили аудио файл с эффектом.

Я каждый раз терпел крах:

AKMicrophone.swift:init():45:Mixer inputs 8
AKNodeRecorder.swift:record():104:AKNodeRecorder: recording
2018-09-07 11:53:09.569326+0300 SEmoji[9009:1453392] [mcmx] 338: input bus 0 sample rate is 0
2018-09-07 11:53:09.571785+0300 SEmoji[9009:1453392] [avae] AVAEInternal.h:103:_AVAE_CheckNoErr: [AVAudioEngineGraph.mm:1839:InstallTapOnNode: (err = AUGraphParser::InitializeActiveNodesInInputChain(ThisGraph, *inputNode)): error -10875
2018-09-07 11:53:09.576701+0300 SEmoji[9009:1453392] *** Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -10875'
*** First throw call stack:
(0x182daad8c 0x181f645ec 0x182daabf8 0x1886d31a0 0x1886eff58 0x1886ff410 0x1887785e8 0x1887686e8 0x10265b738 0x1024f24a4 0x1024f3b44 0x1024f3f54 0x18ccf8100 0x18ccf7b10 0x18ccbd870 0x18cb69484 0x18ccbd870 0x18cb69484 0x18cb5da48 0x18cb528f8 0x18cb51238 0x18d332c0c 0x18d3351b8 0x18d32e258 0x182d53404 0x182d52c2c 0x182d5079c 0x182c70da8 0x184c53020 0x18cc5178c 0x10246cf80 0x182701fc0)
libc++abi.dylib: terminating with uncaught exception of type NSException

Вот как я готовлюсь к записи:

   let mic = AKMicrophone()
   var recorder: AKNodeRecorder!

    AudioKit.engine.reset()
    AudioKit.engine.stop()

    AKSettings.bufferLength = .medium

    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
        try AKSettings.setSession(category: .playAndRecord, with: .allowBluetoothA2DP)
    } catch {
        AKLog("Could not set session category.")
    }

    AKSettings.defaultToSpeaker = true


    self.recorder = try? AKNodeRecorder(node: mic)
    self.player = AKPlayer()
    do {
        try AudioKit.start()
    } catch {
        AKLog("AudioKit did not start!")
    }

Начать запись:

do {
      AudioKit.engine.inputNode.removeTap(onBus: 0)
      try self.recorder.record()
} catch {
      print("Cant record")
}

Остановить запись и сохранить файл:

let tape = self.recorder.audioFile!

self.recorder.stop()
tape.exportAsynchronously(name: "temp_test.m4a", baseDir: .temp,     exportFormat: .m4a) { file, error in
    try? self.recorder.reset()
    AudioKit.engine.inputNode.removeTap(onBus: 0) // I read in some similar topic that we need to remove tap
    self.player.load(audioFile: file)
}

Применение эффекта к аудиофайлу:

let pitchshifter = AKPitchShifter(self.audioPlayer)
pitchshifter.shift = 12

AudioKit.output = pitchshifter

if !AudioKit.engine.isRunning {
   try? AudioKit.start()
}

Визуализация файла:

func makeAudioFile(withCompletion completion: (Error?, URL?) -> Void) {

    let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("temp.m4a")
    if FileManager.default.fileExists(atPath: url.path) {
        try? FileManager.default.removeItem(at: url)
    }


    let recordSettings: [String: Any] = [
        AVFormatIDKey:kAudioFormatMPEG4AAC,
        AVSampleRateKey:44100.0,
        AVNumberOfChannelsKey:2,
        AVEncoderBitRateKey:12800,
        AVLinearPCMBitDepthKey:16,
        AVEncoderAudioQualityKey:AVAudioQuality.max.rawValue
    ]

    do {
        let tape = try AKAudioFile(forWriting: url, settings: recordSettings)
        try AudioKit.renderToFile(tape, seconds: Double(CMTimeGetSeconds(self.asset.duration))) {
            self.audioPlayer.setPosition(0)
            self.audioPlayer.play()
        }
        self.audioWasRendered = true
        completion(nil, url)
    } catch {
        print(error)
        completion(error, nil)
    }
}
...