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

Swift AVAudioEngine如何实现本地麦克风单独静音功能

解决方案

你可以通过在麦克风采集回调中新增静音标记控制的方式实现需求,不需要停止AVAudioEngine,也不会影响其他音频流的正常推流,完全适配你当前的场景,具体实现步骤如下:

  1. 在你的采集类中新增静音状态控制标记:
// 麦克风静音状态标记,默认未静音
private var isMicrophoneMuted = false
  1. 给静音按钮绑定点击事件,点击时直接修改标记值即可:
// 静音按钮点击回调
@IBAction func muteButtonTapped(_ sender: UIButton) {
    isMicrophoneMuted.toggle()
    sender.isSelected = isMicrophoneMuted
}
  1. 修改原有麦克风采集的Tap回调逻辑,以下提供两种可选处理方案:

方案A(更推荐,无卡顿风险)

静音时将采集到的PCM音频数据置空,保持音频流连续,避免推流断层导致观众端卡顿,修改后的采集代码如下:

private func startTappingMicrophone() {
    let inputNode = audioEngine.inputNode
    let inputFormat = inputNode.outputFormat(forBus: 0)
    audioEngine.inputNode.installTap(onBus: 0, bufferSize: AVAudioFrameCount(bufferSize), format: inputFormat) { [weak self] buffer, _ in
          guard let self = self else { return }
          self.conversionQueue.async {
              // 新增静音处理逻辑
              if self.isMicrophoneMuted {
                  guard let floatChannelData = buffer.floatChannelData else { return }
                  let frameCount = Int(buffer.frameLength)
                  let channelCount = Int(buffer.format.channelCount)
                  // 遍历所有声道将音频数据置为0
                  for channel in 0..<channelCount {
                      memset(floatChannelData[channel], 0, frameCount * MemoryLayout<Float>.size)
                  }
              }
              if let cmSampleBuffer = self.configureSampleBuffer(pcmBuffer: buffer) {
                self.delegate?.recievedRecordedFrame(cmSampleBuffer)
              }
          }
    }
    audioEngine.prepare()
    try? audioEngine.start()
}

方案B(逻辑更简单)

静音时直接跳过当前音频帧的传递:

private func startTappingMicrophone() {
    let inputNode = audioEngine.inputNode
    let inputFormat = inputNode.outputFormat(forBus: 0)
    audioEngine.inputNode.installTap(onBus: 0, bufferSize: AVAudioFrameCount(bufferSize), format: inputFormat) { [weak self] buffer, _ in
          guard let self = self else { return }
          // 静音状态直接跳过后续处理
          guard !self.isMicrophoneMuted else { return }
          self.conversionQueue.async {
            if let cmSampleBuffer = self.configureSampleBuffer(pcmBuffer: buffer) {
              self.delegate?.recievedRecordedFrame(cmSampleBuffer)
            }
          }
    }
    audioEngine.prepare()
    try? audioEngine.start()
}

原有方案失效原因说明

  1. audioEngine.inputNode.isVoiceProcessingInputMuted = true仅在AVAudioSession开启了语音处理模式时才会生效,普通音频采集场景下该属性无效。
  2. 调用audioEngine.stop()会直接中断音频采集流,导致推流的音频帧断层,所以观众端会出现卡顿。
  3. rtmpStream.audioSettings[.muted] = true是全局音频静音配置,会将所有要推流的音频(包含麦克风、屏幕内录、其他设备输入)全部静音,不符合仅静音麦克风的需求。

内容的提问来源于stack exchange,提问作者Levan Karanadze

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:06:02