用户停止拍摄后,如何停止录音? 像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
}
}
答案 0 :(得分:2)
这里我创建了我的功能,它实际上会检测到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)
}
}
答案 1 :(得分:1)
您可以向录音机添加定期聆听者(开始录音后),并检查recorder.averagePower(forChannel: 0)
您是否可以处理停止录音的最低等级。