英文:
Safari webkitSpeechRecognition continuous bug
问题
我正在尝试使用webkitSpeechRecognition
,将continuous
设置为false
(当用户停止讲话时,webkitSpeechRecognition
会自动停止),但当我停止讲话并webkitSpeechRecognition
停止时,使用Safari iOS 和 macOS 仍然显示麦克风仍在监听。如果我手动启动它然后停止它,我就没有这个问题。
为了让Safari认识到麦克风不再在监听,我必须再次启动并手动停止webkitSpeechRecognition
。
编辑: 即使.onend
事件发生后,麦克风实际上仍在监听并输入文本。实际上 Safari 并没有在.onspeechend
上真正结束 - 我是不是做错了什么,还是这是一个bug?这只在Safari上发生,而不在Chrome上。请参见示例,即使显示停止,文本仍将被输入。
我是不是做错了什么?有解决方法吗?
let speechrecognition;
if ("webkitSpeechRecognition" in window) {
// 设置麦克风显示
speechrecognition = new webkitSpeechRecognition();
// 用户停止讲话后停止监听,或者可以继续监听,直到用户停止
speechrecognition.continuous = false;
// 临时结果与最终结果一起
speechrecognition.interimResults = true;
speechrecognition.onstart = () => {
console.log("开始");
};
speechrecognition.onend = () => {
console.log("停止");
};
let final_transcript = "";
speechrecognition.onresult = (event) => {
// 在本地创建临时的中间文本,因为我们不希望它像最终文本一样持久存在
let interim_transcript = "";
// 循环遍历来自语音识别对象的结果
for (let i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
final_transcript += event.results[i][0].transcript;
document.getElementsByClassName("dict")[0].innerHTML = final_transcript;
} else {
interim_transcript += event.results[i][0].transcript;
document.getElementsByClassName("dict")[0].innerHTML = interim_transcript;
}
}
final_transcript = "";
};
}
<div class="dict"></div>
<button onclick="speechrecognition.start();">开始</button>
<button onclick="speechrecognition.stop();">停止</button>
英文:
I am trying to use webkitSpeechRecognition with the continuous setting set to false (when the user stops speaking, webkitSpeechRecognition auto stops) but when I stop speaking and the webkitSpeechRecognition stops, when using Safari iOS and macOS still show that the microphone is still listening. If I manually start it and stop it, I don't have this problem.
In order to get Safari to recognize that the microphone is no longer listening, I have to start and manually stop webkitSpeechRecognition again.
EDIT: The microphone is actually listening and inputting text even after the .onend
event occurs. Essentially Safari is not actually ending on .onspeechend
- am I doing something wrong or is this a bug? It only occurs on Safari, not Chrome. Please see example, text will still be inputted even after it says stopped.
Am I doing something wrong? Is there a workaround to this?
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let speechrecognition;
if ("webkitSpeechRecognition" in window) {
// set microphone to show
speechrecognition = new webkitSpeechRecognition();
// stop listening after the user stops speaking or it can keep listening until the user stops
speechrecognition.continuous = false;
// interim results along with the final results
speechrecognition.interimResults = true;
speechrecognition.onstart = () => {
console.log ("started");
};
speechrecognition.onend = () => {
console.log ("stopped");
};
let final_transcript = "";
speechrecognition.onresult = (event) => {
// Create the interim transcript string locally because we don't want it to persist like final transcript
let interim_transcript = "";
// Loop through the results from the speech recognition object.
for (let i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
final_transcript += event.results[i][0].transcript;
document.getElementsByClassName("dict")[0].innerHTML = final_transcript;
} else {
interim_transcript += event.results[i][0].transcript;
document.getElementsByClassName("dict")[0].innerHTML = interim_transcript;
}
}
final_transcript = "";
};
}
<!-- language: lang-html -->
<div class="dict"></div>
<button onclick="speechrecognition.start();">start</button>
<button onclick="speechrecognition.stop();">stop</button>
<!-- end snippet -->
答案1
得分: 1
我认为将OP对他自己问题的评论转为答案是值得的,因为它对我也起到了作用。我发现在Safari for iOS 16.1.1上,调用recognition.stop()
成功触发了onend()
回调,但服务仍然继续监听。
无论是在onspeechend()
回调还是其他地方,似乎都要在调用stop()
之前多次冗余调用start()
是解决这个问题的关键。
function SeriouslyStopListening(recognition)
{
if (navigator.vendor.indexOf('Apple') > -1)
{
try{ recognition.start(); }
catch(err) { }
}
recognition.stop();
}
英文:
I thought it would be worth making OP's comment on his own question into an answer, since it also worked for me. I was finding that calling recognition.stop()
successfully caused the onend()
callback to fire, but then the service continued listening regardless (this is on Safari for iOS 16.1.1).
The practice of redundantly calling start()
right before you call stop()
seems to be the key to working around this, regardless of whether it's in an onspeechend()
callback or elsewhere.
function SeriouslyStopListening(recognition)
{
if (navigator.vendor.indexOf('Apple') > -1)
{
try{ recognition.start(); }
catch(err) { }
}
recognition.stop();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论