How do I change AVAudioSession settings to be not defaultToSpeaker?

Hi,


How do I change the AVAudioSession settings to be not default to speaker?

Even if I use my airPods, it plays everything through the speaker while recording.

This is my code for setup recording in my project:


func setupRecorder(){
       
        var channelLayout = AudioChannelLayout()
        memset(&channelLayout, 0, MemoryLayout<AudioChannelLayout>.size);
        channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
        
        let settings:[String : Any] = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 44100,
                                AVEncoderBitRateKey: 96000,
            AVNumberOfChannelsKey: 1,
                                AVChannelLayoutKey: NSData(bytes:&channelLayout, length:MemoryLayout<AudioChannelLayout>.size)
        ]
            let session = AVAudioSession.sharedInstance()
            do
            {
                try session.setCategory(AVAudioSession.Category.playAndRecord, options: .defaultToSpeaker)
                try session.setActive(true)
                
                audioRecorder = try AVAudioRecorder(url: getFileUrl(), settings: settings)
                audioRecorder.delegate = self
                audioRecorder.isMeteringEnabled = true
                audioRecorder.prepareToRecord()
            }
            catch let error {
                 displayAlert(msg_title: "Error", msg_desc: error.localizedDescription, action_title: "OK")
            }  
    }

Replies

How do I change the AVAudioSession settings to be not default to speaker?


Hmm, maybe I'm missing something, but your AVAudioSession settings are asking for default to speaker:


… session.setCategory(AVAudioSession.Category.playAndRecord, options: .defaultToSpeaker)


Maybe that's not the code fragment you intended to show us?

If I try to do another option, for example, .mixWithOthers- it's giving me the error: "libc++abi.dylib: terminating with uncaught exception of type NSException", and the app crashes.

if I leave it .defaultToSpeaker, it let's me record.

is there another way to change those settings, so the app won't crash?


This is the updated one:


func setupRecorder(){
        
        let session = AVAudioSession.sharedInstance()
        do
        {
            try session.setCategory(AVAudioSession.Category.playAndRecord, mode: .default, options: .mixWithOthers)
            try session.setActive(true)
            
            var channelLayout = AudioChannelLayout()
            memset(&channelLayout, 0, MemoryLayout<AudioChannelLayout>.size);
            channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
            
            let settings:[String : Any] = [
                AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                AVSampleRateKey: 44100,
                AVEncoderBitRateKey: 96000,
                AVNumberOfChannelsKey: 2,
                AVChannelLayoutKey: NSData(bytes:&channelLayout, length:MemoryLayout<AudioChannelLayout>.size)
            ]
            audioRecorder = try AVAudioRecorder(url: getFileUrl(), settings: settings)
            audioRecorder.delegate = self
            audioRecorder.isMeteringEnabled = true
            audioRecorder.prepareToRecord()
        }
        catch let error {
            displayAlert(msg_title: "Error", msg_desc: error.localizedDescription, action_title: "OK")
        }
        
    }

If your app is throwing an Obj-C NSException, you need to look in the log to find the message that says what the exception is. Your app is crashing because of the exception, but that in itself tells you nothing.


You also need to find out on which line of your app the exception is occurring. After you know what the exception is, set an Obj-C exception breakpoint (go to the Breakpoint pane in the navigator, and use the "+" at the bottom left to add that kind of breakpoint). The next time you run your app, it should stop at the place where the exception is thrown.


Also, you don't have to specify a category option at all. There's a variant of the setCategory function that has only two parameters: category and mode.