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

iPhone 14 Pro Max麦克风初始化崩溃问题求助

问题描述

在Testflight中发现iPhone 14 Pro Max(iOS 16.1)设备出现崩溃,该问题在匿名用户设备上持续复现,但实体iPhone 14 Pro Max和模拟器中应用运行正常。应用基于AudioKit 4.11.2开发,包含麦克风追踪、音序器与复音合成器,崩溃发生在AKMicrophone()初始化阶段,怀疑是新设备的采样率或输入/输出格式差异导致。

相关代码如下:

private var mic: AKMicrophone?

private func setupMicInput() {
        
        mic = AKMicrophone() // 崩溃发生在此处
        
        guard let mic = mic else { return }

        if !mic.isStarted {
            mic.start()
        }
                
        let audioInputs = AKManager.inputDevices!.compactMap { $0 }
        
        // 选择底部麦克风
        do {
            try mic.setDevice(audioInputs[0])
        } catch {
            Log(error, category: .audio)
        }
    }

崩溃报告:

0   CoreFoundation                  0x1bbc1de88 __exceptionPreprocess + 164 (NSException.m:202)
1   libobjc.A.dylib                 0x1b4f4b8d8 objc_exception_throw + 60 (objc-exception.mm:356)
2   CoreFoundation                  0x1bbd8a814 +[NSException raise:format:arguments:] + 96 (NSException.m:0)
3   AVFAudio                        0x1d25a14a4 AVAE_RaiseException(NSString*, ...) + 52 (AVAEInternal.h:69)
4   AVFAudio                        0x1d2672cfc AVAudioIONodeImpl::SetOutputFormat(unsigned long, AVAudioFormat*) + 864 (AVAEInternal.h:77)
5   AVFAudio                        0x1d25ed97c AVAudioEngineGraph::_Connect(AVAudioNodeImplBase*, AVAudioNodeImplBase*, unsigned int, unsigned int, AVAudioFormat*) + 5088 (AVAudioEngineGraph.mm:2308)
6   AVFAudio                        0x1d268d510 AVAudioEngineImpl::Connect(AVAudioNode*, AVAudioNode*, unsigned long, unsigned long, AVAudioFormat*) + 1488 (AVAudioEngineGraph.mm:2122)
7   AVFAudio                        0x1d2690d00 -[AVAudioEngine connect:to:format:] + 128 (AVAudioEngine.mm:836)
8                                   0x102c7db1c specialized AKMicrophone.init(with:) + 1024 (AKMicrophone.swift:50)
9                                   0x102c7cccc AKMicrophone.init(with:) + 20 (:0)
10                                  0x102305ac4 AKMicrophone.__allocating_init(with:) + 24 (:0)
11                                  0x102305ac4 AudioManager.setupMicInput() + 60 (AudioManager.swift:325)
解决方案
  • 显式指定兼容的麦克风格式
    iPhone 14 Pro Max的音频硬件可能存在特殊采样率/格式,初始化AKMicrophone时显式传入与设备匹配的格式,避免自动格式适配失败:

    // 获取设备首选输入格式
    if let inputDevice = AKManager.inputDevices?.first,
       let inputFormat = inputDevice.preferredInputFormat {
        mic = AKMicrophone(with: inputFormat)
    } else {
        // 降级到通用兼容格式
        let defaultFormat = AVAudioFormat(standardFormatWithSampleRate: 44100, channels: 1)!
        mic = AKMicrophone(with: defaultFormat)
    }
    
  • 延迟麦克风初始化到音频会话激活后
    确保AVAudioSession完全激活后再初始化麦克风,避免会话状态不稳定引发的格式冲突:

    private func setupAudioSession() {
        do {
            try AKManager.setSession(category: .playAndRecord, with: .defaultToSpeaker)
            try AKManager.startSession()
            // 会话激活后异步初始化麦克风
            DispatchQueue.main.async {
                self.setupMicInput()
            }
        } catch {
            Log(error, category: .audio)
        }
    }
    
  • 捕获初始化异常并降级处理
    给AKMicrophone初始化添加异常捕获,避免崩溃同时提供重试逻辑:

    private func setupMicInput() {
        do {
            // 尝试初始化麦克风,捕获AVFAudio抛出的异常
            try mic = AKMicrophone()
        } catch {
            Log("麦克风初始化失败:\(error)", category: .audio)
            // 使用48kHz格式重试(iPhone 14系列常用采样率)
            let fallbackFormat = AVAudioFormat(standardFormatWithSampleRate: 48000, channels: 1)!
            mic = AKMicrophone(with: fallbackFormat)
        }
        
        guard let mic = mic else { 
            Log("麦克风初始化最终失败", category: .audio)
            return 
        }
    
        // 后续启动和设备设置逻辑...
    }
    
  • 升级AudioKit版本
    AudioKit 4.11.2为旧版本,可能未适配iOS 16.1和iPhone 14 Pro Max的新硬件特性,建议升级到最新稳定版(如v5.x),新版本通常会修复这类硬件兼容问题。

  • 校验麦克风权限状态
    虽然崩溃日志指向格式问题,但仍需确保用户已授予麦克风权限,避免权限异常间接导致初始化失败:

    switch AVAudioSession.sharedInstance().recordPermission {
    case .granted:
        setupMicInput()
    case .denied:
        Log("麦克风权限被拒绝", category: .audio)
    case .undetermined:
        AVAudioSession.sharedInstance().requestRecordPermission { granted in
            if granted {
                DispatchQueue.main.async {
                    self.setupMicInput()
                }
            }
        }
    @unknown default:
        break
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 05:25:13