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