自从 M71 版本,不允许在没有用户激活的情况下使用 JavaScript 的 speechSynthesis.speak() 方法。

22

我是这样使用speechSynthesis API的:

speechSynthesis.speak(new SpeechSynthesisUtterance("hello world"));

但是现在我在更新Google Chrome之后遇到了错误:

[Deprecation] speechSynthesis.speak()没有用户操作不再允许,自M71,即2018年12月左右。请参阅https://www.chromestatus.com/feature/5687444770914304了解更多详细信息 speechSynthesisMessage @application-2c16c437c2795ae01c0a8852e5f8da58dad99d6e17814a31f1eea19922c5ebd2.js:147

我如何解决此问题并请求权限?

7个回答

22

这是Chrome关于在网页中播放声音的新政策的一部分。
你只需要让用户在父文档的生命周期内提供一个用户手势(你可以在这里找到列表),即使事件已经过去,只要用户曾与页面进行交互即可。

请注意,这些事件甚至可以穿越框架,例如在StackOverflow中,只需点击“Run”按钮的简单事实就会允许内部框架执行此代码:

const ut = new SpeechSynthesisUtterance('No warning should arise');
speechSynthesis.speak(ut);

在你的代码中,你只需要提供一种UI,以确保你的用户在调用该方法之前与页面进行了交互(例如按钮/切换将非常完美)。


所以,我们可以针对1个(初始)用户交互多次调用speechSynthesis.speak(message)吗? - kb0000
3
对我来说不起作用,版本号为84.0.4147.105(官方构建)(64位),操作系统为Linux Mint。 - devellopah
2
对我不起作用,在Ubuntu 20.04上使用Chromium 86.0.4240.75(官方版本)(64位),但在同一操作系统的Firefox 82.0(64位)上可以正常工作。 - obe

11
如果您在chrome://settings/content/sound中将站点地址设置为“受信任”,即使没有用户交互,也似乎可以启用声音和语音合成。我将Chrome用作系统监视器,在电视上使用kiosk模式,没有任何用户交互。甚至没有键盘和鼠标。尽管如此,在某些版本的Chrome/Chromium中我还是能够启用,但在其他版本中则不行。

更新:我在Raspbian中使用Chromium,似乎它不再预装语音。因此,我在其他地方合成了这些语音并将它们作为音频文件发送,现在即使没有用户交互也可以正常工作。 - TNT

5

这个错误意味着整个文档(网站)没有用户交互,谷歌浏览器更新了其关于在没有用户交互的情况下从网站播放声音的政策。

用户交互包括:单击,双击,mouseup,pointerup,重置,提交等。

解决方案:

因此,如果您想在没有真正的用户交互的情况下运行 speechSynthesis.speak();,则可以使用像.click()等方法创建临时的用户交互。


就我个人而言,我尝试了这个方法,但它并没有起作用。我在一个DOM元素上创建了一个点击事件处理程序,然后在加载后触发了该点击事件,但当播放时间到来时,语音仍然没有被触发。 - dr b

2

虽然我还没有找到任何询问权限的方法,但用户可以在Google Chrome中启用权限:

  1. 点击URL栏左侧的图标,打开网站设置

  2. 声音设置从“自动(默认)”更改为“允许

这样做后,该网站将能够在没有任何用户交互的情况下发出声音,包括语音。

不幸的是,我还没有在代码中找到一种知道是否正在工作的方法。(也许我们可以尝试其他音频API,并查看它是否响应错误消息。)


0

我尝试了 confirm()alert()。是的,显然这些点击不算数。 - Lonnie Best

-1
我遇到了相同的问题,我通过使用window.onload解决了它,像这样:
window.onload = function(){ 
var u = new SpeechSynthesisUtterance('All is Ok');
 u.text = 'Hello World';    
 u.lang = 'en-US';
 u.rate = 1;
 u.pitch = .4;     
 speechSynthesis.speak(u);
}

当然,这只会在页面加载后触发一次,但对我来说这是一个很好的解决方案。


-3
一个简单的技巧,无需真实用户活动,就是执行隐藏按钮上的点击事件,像这样。
document.querySelector('button').click();
var msg = new SpeechSynthesisUtterance('Test');

你测试过了吗? - Rohit Nishad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接