Find silence in AVAudioRecorder Session

Viewed 1778

How can I stop the audio recording once the user stops taking? Like Siri. Once you say, Hi Siri it will respond to your voice. Means Siri app listening to the audio until you stop the taking.

I'm trying to do the same thing. If I say, Get weather details once I stop my voice. I want to trigger one method or call the API with recorded audio till is stop.

My requirement is app should continuously listen to the user find the voice end event send data to the server or just trigger a method.

Code:

import UIKit
import CoreAudio
import CoreAudioKit
import AVFoundation
import Foundation
import AVKit



class ViewController: UIViewController, AVAudioRecorderDelegate {

    private var recorder    : AVAudioRecorder? = nil
    private var isRecording : Bool = false
    private var timer       : Timer? = nil

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        permissionWasGranted { (isValied) in
            print("isValied")
            self.isRecording = false;
            self.intiateTimer()

        }
    }

    @objc func intiateTimer() {
        self.timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.updateTimer), userInfo: nil, repeats: true)

    }
    @objc func updateTimer() {

        if !isRecording {
            //recorder = nil
            self.initRecorder()
            print("Recording intiated")
        }
        else {
            print("Recording Started")
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func getDocumentsDirectory() -> URL {
        let fileManager         = FileManager.default
        let urls                = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
        let documentDirectory   = urls.first!
        return documentDirectory.appendingPathComponent("recording.m4a")
    }

    // MARK: protocol


    func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
        recorder.stop()
        recorder.deleteRecording()
        recorder.prepareToRecord()
        isRecording = false
        self.updateTimer()
    }


    func permissionWasGranted(result: @escaping (_: Bool)->()) {
        switch AVAudioSession.sharedInstance().recordPermission() {
        case AVAudioSessionRecordPermission.granted:
            //if IS_DEBUG { print("Permission granted") }
            print("Permission granted")

            result(true)
            return
        case AVAudioSessionRecordPermission.denied:
            //if IS_DEBUG { print("Pemission denied") }
                print("Pemission denied")
        case AVAudioSessionRecordPermission.undetermined:
            //if IS_DEBUG { print("Request permission here") }
            print("Request permission here")

            AVAudioSession.sharedInstance().requestRecordPermission({ (granted) in
                if granted {
                    result(true)
                    return
                }
            })

        }
        result(false)
    }

    func initRecorder() {
        let settings = [
            AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
            AVSampleRateKey: 12000,
            AVNumberOfChannelsKey: 1,
            AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
        ]
        do {
            let session = AVAudioSession.sharedInstance()
            try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
            try session.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
            try session.setActive(true)

            try recorder = AVAudioRecorder(url: getDocumentsDirectory(), settings: settings)
            recorder!.delegate = self
            recorder!.isMeteringEnabled = true

            if !recorder!.prepareToRecord() {
                print("Error: AVAudioRecorder prepareToRecord failed")
            }


            let decibels = self.getDispersyPercent()
            if decibels > -120  && decibels < -20 {
                self.timer?.invalidate()
                isRecording = true;
                self.start()
            }


        } catch {
            print("Error: AVAudioRecorder creation failed")
        }
    }

    func start() {
        recorder?.record()
        recorder?.updateMeters()
    }

    func update() {
        if let recorder = recorder {
            recorder.updateMeters()
        }
    }

    func getDispersyPercent() -> Float {
        if let recorder = recorder {
            let decibels = recorder.averagePower(forChannel: 0)
            return decibels
        }
        return 0
    }

}
2 Answers
Related