Search code examples
iosswiftavaudiorecorder

No Audio with AVAudioRecord


I'm trying a simple example to record audio in iOS using AVAudoiRecorder with Swift, I've created this class:

import Foundation
import AVFoundation

class AudioRecorder: NSObject, AVAudioRecorderDelegate {
    var audioRecorder: AVAudioRecorder?
    var file: URL? = nil
    
    func setupAudioSession() {
        let session = AVAudioSession.sharedInstance()
        
        do {
            try session.setCategory(.playAndRecord, mode: .default)
            try session.setActive(true)
            try session.overrideOutputAudioPort(.speaker)
            debugPrint("Listo todo")
        } catch {
            print("Error setting up audio session: \(error.localizedDescription)")
        }
    }
    
    func startRecording() {
        file = getDocumentsDirectory().appendingPathComponent("recording.wav")
        
        let settings: [String: Any] = [
            AVFormatIDKey: kAudioFormatLinearPCM,
            AVSampleRateKey: 44100.0,
            AVNumberOfChannelsKey: 2,
            AVLinearPCMBitDepthKey: 16,
            AVLinearPCMIsFloatKey: false,
            AVLinearPCMIsBigEndianKey: false
        ]
        
        do {
            audioRecorder = try AVAudioRecorder(url: file!, settings: settings)
            audioRecorder?.delegate = self
            audioRecorder?.prepareToRecord()
            audioRecorder?.record()
        } catch {
            print("Error starting recording: \(error.localizedDescription)")
        }
    }
    
    func stopRecording() {
        audioRecorder?.stop()
    }
    
    private func getDocumentsDirectory() -> URL {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    }
    
    // MARK: AVAudioRecorderDelegate
    func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
        if flag {
            print("Recording was successful.")
        } else {
            print("Recording failed.")
        }
    }
}

The view call setupAudioSession and when a button is pressed I call startRecording (and before do that I check the mic permissions with AVAudioSession.sharedInstance().requestRecordPermission).

When I press stop I get a Recording was successful message in the log from the audioRecorderDidFinishRecording callback. If I try to play the file using AVAudioPlayer I can read the file properties correctly:

"Playing ... Optional(\"file:///var/mobile/Containers/Data/Application/0760DB3E-440E-4898-83A6-0888EC2EA399/Documents/recording.wav\")"
"Duration: 4.180997732426304"
"Format: <AVAudioFormat 0x281ce80f0:  2 ch,  44100 Hz, Int16, interleaved>"
"Current Time: 0.0"
"Volume: 1.0"

But the there is not sound at all. I also setup the NSMicrophoneUsageDescription in the Info.plist to get access to the mic.

I've tried in Simulators and real devices and got not sound at all. Also, I've downloaded the WAV file and checked in an audio editor and the file is empty.

Any idea of what I can be missing? Looks like a really example and all the things I can find searching are very similar.


Solution

  • Ok, I think I finally managed to make it work. Not 100% sure, but looks like I had some problems with the instance retention of the AVAudioRecorder and AVAudioPlayer. After be sure that the instances are not being destroyed all start to work as expected.