AVAudioRecorder/AVAudioSession 与 Apple Airpods

问题描述 投票:0回答:3

我看到这里已经问过的问题:

AirPods 无法用作录音机应用程序的输入源

我已查看此线程,但没有回复。

但是,有谁知道 AVAudioRecorder 是否/为什么可能无法使用 AirPods 作为在应用程序中录制音频的输入设备?我通过内置麦克风以及其他 BT 设备(Beats、便宜的 BT 扬声器电话等)进行音频录制,但在使用 AirPods 时我无法捕获音频。

此外,当要录制时,我会循环访问可用的输入,并强制输入为 BT 设备(参见下面的代码),在本例中为 AirPods。同样,适用于除 AirPods 之外的所有其他 BT 设备。

想法?任何关于我们在这里做错了什么的指导都会很棒。这已经让人抓狂了。

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)
    }
}
ios objective-c bluetooth avaudiosession
3个回答
7
投票

事实证明我们遇到的问题与正在设置的类别有关。由于我们在使用各种蓝牙输出设备时遇到问题,我们将音频类别设置为

AVAudioSessionCategoryPlayback
,除非我们准备好录制。

根据此堆栈帖子:AVAudioSession:某些蓝牙设备在我的应用程序上无法正常工作

在上面的代码中,我们在开始录制之前将类别切换到

AVAudioSessionCategoryRecord
。虽然这适用于内置麦克风和其他蓝牙设备,但不适用于 AirPods。相反,将类别设置为
AVAudioSessionCategoryPlayAndRecord
允许使用 AirPods 进行录音。

然后,我仍然在整个应用程序中为音频播放会话保留“仅播放”类别。仅在要录制音频时切换到 PlayAndRecord。

附带说明:Apple 并未将 AirPods 列为 MFi 设备。 https://mfi.apple.com/MFiWeb/getFAQ.action#1-1


0
投票

我认为AirPods是MFI(Made For Iphone)配件,这意味着蓝牙通信通过ExternalAccessory框架https://developer.apple.com/documentation/externalaccessory

这是苹果演示: https://developer.apple.com/library/content/samplecode/EADemo/Introduction/Intro.html

提示:协议名称必须放在Info.plist中UISupportedExternalAccessoryProtocols键中

更多详情:https://mfi.apple.com/MFiWeb/getFAQ.action


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")
            
        }

    }

}
© www.soinside.com 2019 - 2024. All rights reserved.