- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个同时利用 STT(语音到文本)和 TTS(文本到语音)的应用程序。但是,我遇到了一些模糊的问题,非常感谢您的专业知识。
该应用程序包含一个位于屏幕中央的按钮,单击该按钮可使用以下代码启动所需的语音识别功能。
// MARK: - Constant Properties
let audioEngine = AVAudioEngine()
// MARK: - Optional Properties
var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
var recognitionTask: SFSpeechRecognitionTask?
var speechRecognizer: SFSpeechRecognizer?
// MARK: - Functions
internal func startSpeechRecognition() {
// Instantiate the recognitionRequest property.
self.recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
// Set up the audio session.
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(.record, mode: .measurement, options: [.defaultToSpeaker, .duckOthers])
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print("An error has occurred while setting the AVAudioSession.")
}
// Set up the audio input tap.
let inputNode = self.audioEngine.inputNode
let inputNodeFormat = inputNode.outputFormat(forBus: 0)
self.audioEngine.inputNode.installTap(onBus: 0, bufferSize: 512, format: inputNodeFormat, block: { [unowned self] buffer, time in
self.recognitionRequest?.append(buffer)
})
// Start the recognition task.
guard
let speechRecognizer = self.speechRecognizer,
let recognitionRequest = self.recognitionRequest else {
fatalError("One or more properties could not be instantiated.")
}
self.recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest, resultHandler: { [unowned self] result, error in
if error != nil {
// Stop the audio engine and recognition task.
self.stopSpeechRecognition()
} else if let result = result {
let bestTranscriptionString = result.bestTranscription.formattedString
self.command = bestTranscriptionString
print(bestTranscriptionString)
}
})
// Start the audioEngine.
do {
try self.audioEngine.start()
} catch {
print("Could not start the audioEngine property.")
}
}
internal func stopSpeechRecognition() {
// Stop the audio engine.
self.audioEngine.stop()
self.audioEngine.inputNode.removeTap(onBus: 0)
// End and deallocate the recognition request.
self.recognitionRequest?.endAudio()
self.recognitionRequest = nil
// Cancel and deallocate the recognition task.
self.recognitionTask?.cancel()
self.recognitionTask = nil
}
当单独使用时,这段代码就像一个魅力。但是,当我想使用 AVSpeechSynthesizer
对象读取转录的文本时,似乎没有什么是清楚的。
看了多个Stack Overflow帖子的建议,建议修改
audioSession.setCategory(.record, mode: .measurement, options: [.defaultToSpeaker, .duckOthers])
以下内容
audioSession.setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker, .duckOthers])
还是徒劳。在分别运行 STT 和 TTS 后,应用程序仍然崩溃。
我的解决方案是使用这个而不是前面提到的
audioSession.setCategory(.multiRoute, mode: .default, options: [.defaultToSpeaker, .duckOthers])
这让我完全不知所措,因为我真的不知道发生了什么错综复杂的事情。如果有任何相关解释,我将不胜感激!
最佳答案
我也在用 SFSpeechRecognizer 和 AVSpeechSythesizer 开发一个应用程序,对我来说 .setCategory(.playAndRecord, mode: .default)
工作正常,它是我们需要的最佳类别,according to Apple .甚至,我能够在音频引擎运行时 .speak()
SFSpeechRecognitionTask 的每个转录,没有任何问题。我的意见是你的程序逻辑中的某个地方导致了崩溃。如果您可以用相应的错误更新您的问题,那就太好了。
关于为什么 .multiRoute
类别有效:我猜 AVAudioInputNode
有问题。如果您在控制台中看到这样的错误
Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: IsFormatSampleRateAndChannelCountValid(hwFormat)
或者像这样
Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'required condition is false: nullptr == Tap()
您只需要对代码的某些部分重新排序,例如将 Audio Session 的设置移动到只被调用一次的地方,或者确保输入节点的抽头总是在安装新的之前删除,即使识别任务是否成功完成。也许(我从未使用过它).multiRoute
能够通过 its nature 处理不同的音频流和路由来重用相同的输入节点。
在 Apple 的 WWDC session 之后,我在我的程序中使用的逻辑如下:
override func viewDidLoad() { //or init() or when necessarily
super.viewDidLoad()
try? AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default)
}
func shouldProcessSpeechRecognition() {
guard AVAudioSession.sharedInstance().recordPermission == .granted,
speechRecognizerAuthorizationStatus == .authorized,
let speechRecognizer = speechRecognizer, speechRecognizer.isAvailable else { return }
//Continue only if we have authorization and recognizer is available
startSpeechRecognition()
}
func startSpeechRecognition() {
let format = audioEngine.inputNode.outputFormat(forBus: 0)
audioEngine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: format) { [unowned self] (buffer, _) in
self.recognitionRequest.append(buffer)
}
audioEngine.prepare()
do {
try audioEngine.start()
recognitionTask = speechRecognizer!.recognitionTask(with: recognitionRequest, resultHandler: {...}
} catch {...}
}
func endSpeechRecognition() {
recognitionTask?.finish()
stopAudioEngine()
}
func cancelSpeechRecognition() {
recognitionTask?.cancel()
stopAudioEngine()
}
func stopAudioEngine() {
audioEngine.stop()
audioEngine.inputNode.removeTap(onBus: 0)
recognitionRequest.endAudio()
}
有了它,我可以在我的代码中的任何地方调用一个 AVSpeechSynthesizer
实例并说出一段话。
关于ios - 同时使用 SFSpeechRecognizer 和 AVSpeechSythesizer 时如何正确设置 AVAudioSession 和 AVAudioEngine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53147291/
我正在尝试动态修改附加到 AVAudioEngine 的节点图,但该图在每次重新连接后输出静音。 在下面的示例中,我想将 player 动态连接到 engine.mainMixerNode,但是每当我
我正在尝试使用 AVAudioEngine 播放 AVAudioFile。代码大部分取自苹果开发者在线视频,但没有回放。花了一些时间浏览论坛,但似乎没有任何线索。 我有两种方法。第一个调用标准的打开文
我的应用程序动态添加和删除为 mainMixerNode 提供数据的节点。发生这种情况时,我会听到咔哒声或爆裂声,因为音量并未减弱。 建立连接时如何实现平滑过渡?我是否需要在 AudioUnit 中自
我正在尝试查找有关如何使用 AVAudioEngine 的详细文档。有谁知道我在哪里可以找到它? 我找到了这个,但与文档丰富的 UI 内容相比,它似乎非常简陋。 https://developer.a
这里是第一个 stackoverflow 问题,所以请多多包涵!在为 MacOS 设计更大的音频程序的过程中,我试图创建一个测试应用程序,它可以简单地从任何系统音频输入中获取音频并将其发送到任何输出。
我正在用 Swift 编写一个 iOS 应用程序,该应用程序正在录制用户的声音,然后可以使用一些语音效果进行播放,但问题是使用内置 iPhone 麦克风时播放非常安静。带耳机就没问题。 录制代码: l
我正在使用 AVAudioEngine 进行测量。我从界面中播放刺激声音,并使用 micTap 记录返回的信号。 我现在正在研究支持多种不同格式的不同音频接口(interface)。我通过混合器转换
我成功地将 AVAudioPlayer 节点附加到我的 AVAudioEngine。但是,我需要稍后检查这些节点是否已附加到它(因此我不会重新添加它们)。 引擎上是否有任何特定属性可供我检查以查看其是
简单的问题。如何使用 AVAudioEngine 播放多声道音频文件(> 2 声道),以便我可以听到默认 2 声道输出(耳机/扬声器)上的所有声道。以下代码(去除了用于呈现的错误检查)播放文件的前两个
我正在创建一个基本的音板应用程序。我有两个开关。一种在激活时将使音频变慢且音调更低,另一种则使其变得更快和更高。我有一个 if else if if 语句,它查看这些开关,然后相应地播放音频,但是当我
我正在开发一键通功能,发送者可以将字节数组形式的音频发送到服务器,接收者可以通过套接字连接实时收听它。 当我尝试使用 AVAudioEngine 在接收端播放视频时,它不起作用。 let bu
我正在尝试制作音频处理应用程序。有没有办法使用 AVAudioEngine 将音频效果应用于音频文件? 最佳答案 是的,你当然可以,你可以使用: AVAudioPlayerNode AVAudioUn
我正在尝试设置一个 AudioQueue 以从 iPhone 上的麦克风传输音频。 我创建我的音频引擎: var audioEngine = AVAudioEngine() 还有我的音频队列:
我正在使用一个 AVAudioEngine 对象,它附有许多 AVAudioPlayerNodes。音频一切正常,除了它会停止 iPhone 在后台播放的任何音频(即来自 iTunes 或其他音乐应用
我正在设置一个 AVAudioEngine 实现以从麦克风获取音频并将其流式传输到 websocket 连接。首先,我已经点击了麦克风输入和一个中间混音器,该混音器将麦克风的音频从 44khz 下采样
在我下面的代码中,我创建了两个声音,sound1 和 sound2。每个声音都包含多个样本,允许同时播放相同的声音。问题是,如果我创建看似超过 6 到 8 个 AVAudioPlayerNode,每个
我已经设置了我的音频引擎并连接了几个节点,以便制作如下所示的音频图: // //AVAudioPlayerNode --> AVAudioMixerNode --> AVAudioUnitVarisp
我正在使用 AVAudioPlayerNode 播放歌曲,我正在尝试使用 UISlider 来控制它的时间,但我无法弄清楚如何使用 AVAUdioEngine. 最佳答案 经过反复试验,我想我终于弄明
我在对从麦克风获取的音频进行下采样时遇到问题。我正在使用 AVAudioEngine 通过以下代码从麦克风中采集样本: assert(self.engine.inputNode != nil) let
我正在尝试运行来自 their website here 的 Apple SpeakToMe:将语音识别与 AVAudioEngine 结合使用示例.我的问题是,当您停止 AVAudioEngine
我是一名优秀的程序员,十分优秀!