AVAudioRecorder/AVAudioSession与Apple Airpods的兼容性问题

8

我在这里看到已经有人提过相同的问题:

AirPods不适用于语音记录应用程序

我查了一下这个线程,但没有回应。

但是,请问有人知道为什么AVAudioRecorder可能无法使用AirPods作为应用程序中录制音频的输入设备吗?我已经通过内置麦克风以及其他蓝牙设备(Beats、廉价的蓝牙扬声器电话等)进行了音频录制,但在使用AirPods时,我无法捕捉音频。

此外,在准备录制时,我会循环遍历可用的输入,并强制输入为蓝牙设备(请参见下面的代码),在这种情况下是AirPods。同样,在所有其他蓝牙设备上工作,但不适用于AirPods。

您有什么想法吗?任何关于我们做错了什么的指导都将非常感激。这让我非常恼火。

NSError *error;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord withOptions:audioSession.categoryOptions|AVAudioSessionCategoryOptionAllowBluetooth
                    error:&error];
[audioSession setActive:YES error:nil];

NSLog(@"Data sources: %@", [audioSession availableInputs]);
// Data sources: ("<AVAudioSessionPortDescription: 0x1706071b0, type = MicrophoneBuiltIn; name = iPhone Microphone; UID = Built-In Microphone; selectedDataSource = Bottom>",
"<AVAudioSessionPortDescription: 0x170611bd0, type = BluetoothHFP; name = Dan\U2019s AirPods; UID = 50:32:37:E0:90:37-tsco; selectedDataSource = (null)>"    

for (AVAudioSessionPortDescription *desc in [audioSession availableInputs]){
    NSLog(@"Port desc: %@", desc.portType);
    // Loop: 1) Port desc: MicrophoneBuiltIn
    //       2) Port desc: BluetoothHFP

    if (desc.portType == AVAudioSessionPortBluetoothHFP) {
        NSLog(@"Trying to change preferred input");
        NSError *error;
        BOOL didSet = [audioSession setPreferredInput:desc error:&error];
        NSString *didSetString = didSet ? @"True" : @"False";
        NSLog(@"Post change preferred input: %@, error: %@", didSetString, error);
        // Post change preferred input: True, error: (null)
    }
}
3个回答

7
事实证明,我们所遇到的问题与设置的音频类别有关。由于我们在使用各种蓝牙输出设备时遇到了问题,我们将音频类别设置为AVAudioSessionCategoryPlayback并保持不变,除非我们准备录制音频。
根据这篇Stack文章:AVAudioSession: Some Bluetooth devices are not working properly on my App 在上面的代码中,我们在即将录制音频之前将类别切换到AVAudioSessionCategoryRecord。虽然这对内置麦克风和其他蓝牙设备有效,但不能与AirPods一起使用。相反,设置类别为AVAudioSessionCategoryPlayAndRecord可以使AirPods正常录制音频。
我仍然在整个应用程序的会话中维护只有播放的类别。只有在准备录制音频时才切换到PlayAndRecord。
顺便说一下:苹果没有将AirPods列为MFi设备。https://mfi.apple.com/MFiWeb/getFAQ.action#1-1

我自己也遇到了这个问题,将.record切换到.playAndRecord确实解决了我的AirPods问题。你有任何想法吗?我测试过的其他蓝牙耳机(超过10个)都可以使用.record。我很高兴修复如此简单,但担心根本原因没有得到解决。 - bclymer

0

谢谢。我会仔细阅读这个,看看它是否有帮助。 - djneely
2
我不会给这个点踩,但是Airpods没有被列为MFI,所以ExternalAccessory不会起作用,但是你发现得很好! :) - Dominik Bucher

0
func addMicrophone() throws {
    
    print("------")
    print("addMicrophone")
    print("------")
    
    // Add Audio Input
        
    do {
        
        let audioSession : AVAudioSession = AVAudioSession.sharedInstance()
        try audioSession.setCategory(AVAudioSession.Category.playAndRecord, options: [.allowBluetooth, .defaultToSpeaker])
        try audioSession.setActive(true)
        
        // select the Bluetooth port if available
        
        let portDescriptions : [AVAudioSessionPortDescription] = audioSession.availableInputs ?? []
        
        var builtInMicPort : AVAudioSessionPortDescription?
        var airPodsPort : AVAudioSessionPortDescription?
        
        for port in portDescriptions {
            
            print("port: \(port)")
            
            if port.portType == AVAudioSession.Port.builtInMic {
                
                print("found builtInMic")
                
                builtInMicPort = port
                
            }
            
            // airpods
            
            if port.portType == AVAudioSession.Port.bluetoothHFP || port.portType == AVAudioSession.Port.bluetoothLE || port.portType == AVAudioSession.Port.bluetoothA2DP {

                print("found airPods")
                                    
                airPodsPort = port
                
            }
            
            if port.portName == "Bluetooth" || "\(port)" == "Bluetooth" {
                                    
                print("found airPods")

                airPodsPort = port
                
            }
            
        }
        
        // airpods
        
        if airPodsPort != nil {
            
            print("use airPodsPort")
            
            try audioSession.setPreferredInput(airPodsPort)
                            
            // video
            
            self.captureSession?.usesApplicationAudioSession = true
            self.captureSession?.automaticallyConfiguresApplicationAudioSession = false
            
            // audio input
        
            let audioInput = AVCaptureDevice.default(for: .audio)
                
            if captureSession?.canAddInput(try AVCaptureDeviceInput(device: audioInput!)) ?? false {
            
                try captureSession?.addInput(AVCaptureDeviceInput(device: audioInput!))
            
            }

            print("success")
            
        }

    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接