问题描述
我正在尝试使用AVAudioEngine播放按钮声音。但不幸的是,声音文件只能播放一次。
这个想法是,用户点击按钮,播放声音并开始录制。用户再次点击该按钮后,应该会播放第二声,表明录制会话已经结束。
到目前为止,出现第一个声音,并开始录音。 不幸的是,第二个声音(结束声音)不会播放。
我发现,当我使用与录音功能相同的AudioEngine时,根本不会播放声音。
由于我是AVFoundation框架的新手,所以我不确定这里的问题是什么。
谢谢。
var StartSoundEngineScene1 = AVAudioEngine()
var StartSoundNodeScene1 = AVAudioPlayerNode()
func SetupAudio(AudioEngine: AVAudioEngine,SoundNode: AVAudioPlayerNode,FileURL: URL) {
guard let AudioFile = try? AVAudioFile(forReading: FileURL) else{ return }
let AudioSession = AVAudioSession.sharedInstance()
AudioEngine.attach(SoundNode)
AudioEngine.connect(SoundNode,to: AudioEngine.mainMixerNode,format: AudioFile.processingFormat)
AudioEngine.prepare()
}
override func viewDidLoad() {
super.viewDidLoad()
SetupAudio(AudioEngine: StartSoundEngineScene1,SoundNode: StartSoundNodeScene1,FileURL: StartRecSound)
}
func ButtonSound (AudioEngine: AVAudioEngine,FileURL: URL){
try? AudioEngine.start()
guard let audioFile = try? AVAudioFile(forReading: FileURL) else{ return }
SoundNode.scheduleFile(audioFile,at: nil,completionHandler: nil)
SoundNode.volume = 0.16
SoundNode.play()
}
func StartRecording(){
ButtonSound(AudioEngine: StartSoundEngineScene1,FileURL: StartRecSound)
Timer.scheduledTimer(withTimeInterval: 0.7,repeats: false) { timer in
if audioEngine.isRunning {
audioEngine.stop()
recognitionRequest?.endAudio()
} else {
print("Rercording Started")
if let recognitionTask = self.recognitionTask {
recognitionTask.cancel()
self.recognitionTask = nil
}
self.recordedMessage = ""
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSession.Category.record)
try audioSession.setMode(AVAudioSession.Mode.measurement)
}catch {
print(error)
}
recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
guard let recognitionRequest = self.recognitionRequest else {
fatalError("Unable to create a speech audio buffer")
}
recognitionRequest.shouldReportPartialResults = true
recognitionRequest.requiresOnDeviceRecognition = true
recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest,resultHandler: { (result,error) in
var isFinal = false
if let result = result {
let sentence = result.bestTranscription.formattedString
self.recordedMessage = sentence
print (self.recordedMessage)
isFinal = result.isFinal
}
if error != nil || isFinal {
self.audioEngine.stop()
self.audioEngine.inputNode.removeTap(onBus: 0)
self.recognitionRequest = nil
self.recognitionTask = nil
self.RecordBtn.isEnabled = true
}
})
let recordingFormat = audioEngine.inputNode.outputFormat(forBus: 0)
audioEngine.inputNode.installTap(onBus: 0,bufferSize: 1024,format: recordingFormat) { (buffer,when) in
self.recognitionRequest?.append(buffer)
}
audioEngine.prepare()
do{
try audioEngine.start()
}catch {
print(error)
}
}
}
}
func StopRecording(){
if audioEngine.isRunning{
audioEngine.stop()
ButtonSound(AudioEngine: StartSoundEngineScene1,FileURL: StopRecSound)
recognitionRequest?.endAudio()
audioEngine.inputNode.removeTap(onBus: 0)
}
}
解决方法
您将AVAudioSessionCategory设置为记录。
try audioSession.setCategory(AVAudioSession.Category.record)
如果要同时播放和录制,则应将此类别设置为playAndRecord
然后...如果在播放或录制过程中更改了AVAudioSession,则将更改AVAudioEngine的配置,然后将触发AVAudioEngineConfigurationChange通知。