首页 > 解决方案 > AKNodeRecorder 崩溃

问题描述

我的应用程序中有下一个流程:

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

标签: iosswiftaudiokit

解决方案


推荐阅读