Swift AVAudioEngine如何实现本地麦克风单独静音功能
解决方案
你可以通过在麦克风采集回调中新增静音标记控制的方式实现需求,不需要停止AVAudioEngine,也不会影响其他音频流的正常推流,完全适配你当前的场景,具体实现步骤如下:
- 在你的采集类中新增静音状态控制标记:
// 麦克风静音状态标记,默认未静音 private var isMicrophoneMuted = false
- 给静音按钮绑定点击事件,点击时直接修改标记值即可:
// 静音按钮点击回调 @IBAction func muteButtonTapped(_ sender: UIButton) { isMicrophoneMuted.toggle() sender.isSelected = isMicrophoneMuted }
- 修改原有麦克风采集的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() }
原有方案失效原因说明
audioEngine.inputNode.isVoiceProcessingInputMuted = true仅在AVAudioSession开启了语音处理模式时才会生效,普通音频采集场景下该属性无效。- 调用
audioEngine.stop()会直接中断音频采集流,导致推流的音频帧断层,所以观众端会出现卡顿。 rtmpStream.audioSettings[.muted] = true是全局音频静音配置,会将所有要推流的音频(包含麦克风、屏幕内录、其他设备输入)全部静音,不符合仅静音麦克风的需求。
内容的提问来源于stack exchange,提问作者Levan Karanadze
相关产品推荐
相关产品推荐

