[英]Find silence in AVAudioRecorder Session
一旦用戶停止播放,我該如何停止錄音? 像Siri一樣。 一旦你說,嗨Siri它會響應你的聲音。 意味着Siri app聽取音頻直到你停止拍攝。
我正在嘗試做同樣的事情。 如果我說,一旦我停止聲音, 獲取天氣詳情 。 我想觸發一個方法或用錄制的音頻調用API直到停止。
我的要求是app應該不斷聽取用戶發現語音結束事件發送數據到服務器或只是觸發一個方法。
碼:
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
}
}
在這里我創建了我的功能,它實際上會檢測到靜音5秒,如果條件滿足,你可以停止記錄那個時間
- 我曾經使用過Recording Manager NSObject類,因此您可以從下面的函數中獲取代碼並設法在您的函數中使用它
碼
//StartNewRecordingIfSilenceFor5Second
func newSessionIfSilence(){
//get Audio file name to store
let AudioFileName = getDocumentsDirectory().appendingPathComponent("\(getUniqueName()).wav")
//Declare a value that will be updated when silence is detected
var statusForDetection = Float()
//Recorder Settings used
let settings: [String: Any] = [
AVFormatIDKey: Int(kAudioFormatLinearPCM),
AVSampleRateKey: 16000,
AVNumberOfChannelsKey: 1,
AVLinearPCMBitDepthKey: 16,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,
AVLinearPCMIsBigEndianKey: false,
AVLinearPCMIsFloatKey: false,
]
//Try block
do {
//Start Recording With Audio File name
Manager.recorder = try AVAudioRecorder(url: AudioFileName, settings: settings)
Manager.recorder?.delegate = self
Manager.recorder?.isMeteringEnabled = true
Manager.recorder?.prepareToRecord()
Manager.recorder?.record()
//Tracking Metering values here only
Manager.meterTimer = Timer.scheduledTimer(withTimeInterval: 0.10, repeats: true, block: { (timer: Timer) in
//Update Recording Meter Values so we can track voice loudness
//Getting Recorder from another class
//i managed my recorder from Manager class
if let recorder = Manager.recorder
{
//Start Metering Updates
recorder.updateMeters()
//Get peak values
Manager.recorderApc0 = recorder.averagePower(forChannel: 0)
Manager.recorderPeak0 = recorder.peakPower(forChannel: 0)
//it’s converted to a 0-1 scale, where zero is complete quiet and one is full volume.
let ALPHA: Double = 0.05
let peakPowerForChannel = pow(Double(10), (0.05 * Double(Manager.recorderPeak0)))
// static var lowPassResults: Double = 0.0
RecordingManager.lowPassResults = ALPHA * peakPowerForChannel + (1.0 - ALPHA) * RecordingManager.lowPassResults
if(RecordingManager.lowPassResults > 0){
print("Mic blow detected")
//Do what you wanted to do here
//if blow is detected update silence value as zero
statusForDetection = 0.0
}
else
{
//Update Value for Status is blow being detected or not
//As timer is called at interval of 0.10 i.e 0.1 So add value each time in silence Value with 0.1
statusForDetection += 0.1
//if blow is not Detected for 5 seconds
if statusForDetection > 5.0 {
//Update value to zero
//When value of silence is greater than 5 Seconds
//Time to Stop recording
statusForDetection = 0.0
//Stop Audio recording
recorder.stop()
}
}
}
})
} catch {
//Finish Recording with a Error
print("Error Handling: \(error.localizedDescription)")
self.finishRecording(success: false)
}
}
您可以向錄像機添加定期監聽器(開始錄像后),並檢查recorder.averagePower(forChannel: 0)
您可以處理停止錄像的最低級別。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.