You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中使用AudioKit实现麦克风-效果-录音链路遇空文件问题

问题分析与修正方案

核心错误点

  1. NodeRecorder参数误用:你使用了fileDirectoryURL参数,它的作用是指定保存文件的目录,而非具体文件路径,应该用fileURL直接指定输出WAV文件的完整路径。
  2. 未启动录制流程:创建NodeRecorder后没有调用record()方法,导致音频录制根本没有开始。
  3. 录制节点错误:当前录制的是原始麦克风输入,而非经过变调处理后的音频,需要将录制节点指向PitchShifter的输出。
  4. 停止逻辑缺失:停止录制时未调用recorder?.stop(),无法触发音频数据写入文件的操作。
  5. 变量拼写错误:var recoder: NodeRecorder? 应为 recorder,会导致变量引用异常。

修正后的完整代码

import AudioKit
import AVFoundation
import SoundpipeAudioKit

class AudioRecorder: ObservableObject {
  
    let engine = AudioEngine()
    var recorder: NodeRecorder? // 修正拼写错误

    private(set) lazy var outputFileURL: URL = {
        let documentsPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        return documentsPath.appendingPathComponent("recording.wav")
    }()

    func startRecording() {
        do {
            try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker])
            try AVAudioSession.sharedInstance().setActive(true)
        } catch {
            print("Failed to set up recording session.")
            return
        }

        guard let input = engine.input else {
            print("No audio input found")
            return
        }

        // 先创建变调处理节点并设置为引擎输出
        let pitchShifter = PitchShifter(input)
        engine.output = pitchShifter

        do {
            // 初始化录制器,指定处理后的节点和输出文件路径
            recorder = try NodeRecorder(node: pitchShifter, fileURL: outputFileURL)
            // 启动录制
            try recorder?.record()
        } catch let err {
            fatalError("\(err)")
        }

        do {
            try engine.start()
        } catch {
            print("Unable to start audio engine: \(error.localizedDescription)")
            return
        }
    }

    func stopRecording() {
        // 先停止录制并写入文件
        recorder?.stop()
        recorder = nil // 释放录制器资源

        engine.stop()
        do {
            try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
        } catch {
            print("Failed to stop recording session.")
        }
    }
}

关键修正说明

  • 调整录制目标:将NodeRecorder的监听对象改为PitchShifter,确保保存的是经过变调处理后的音频。
  • 启动录制操作:添加try recorder?.record(),触发音频数据的采集与写入。
  • 完善停止流程:停止录制时优先调用recorder?.stop(),保证音频数据完整写入文件后再停止引擎。

内容的提问来源于stack exchange,提问作者Tofig Hasanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:27:06