如何让我的网络浏览器以编程方式说话?
Posted
技术标签:
【中文标题】如何让我的网络浏览器以编程方式说话?【英文标题】:How can I make my web browser speak programmatically? 【发布时间】:2018-01-29 15:04:06 【问题描述】:是否可以让网站以编程方式向用户发送欢迎信息?
假设我想在成功登录我的网站后向用户打招呼。我知道我可以录制问候消息(即作为 MP3 格式)并播放,但我希望能够以编程方式执行此操作,因为所有用户的名称都会不同。
例如,当 John Doe 登录时,我可能想说Welcome, John Doe
。
我怎么能用纯 javascript 做到这一点?
注意:这不是为了在生产系统中使用,而是为了用作更大的用户体验实验的一小部分。
【问题讨论】:
不要。那是糟糕的用户体验。 如果你只是为了自己或为了好玩而做这件事,那就把自己搞砸了,但如果你正在构建面向公众的东西,那就避免这样做,因为这不是一个好的用户体验 建议规范的问题/答案应包含与主题有关的大量相关细节,请参阅What is a canonical question/answer, and what is their purpose?。这个Answer 目前省略了关于如何在不同浏览器上实际实现 Web Speech API 的关键细节。对于互操作,window.speechSynthesis.getVoices()
和 onvoiceschanged
事件使用不能忽略。
“成功登录后向用户打招呼”肯定是“糟糕的用户体验”。尽管以这种方式使用音频可能有实际原因,但在正常情况下这不是其中之一。
相关:Should I add sound effects to my web site?Why is sound sparingly used on websites?Should we use a sound/jingle when users arrive on our site or open our app?
【参考方案1】:
为了让window.speechSynthesis.speak()
在 Chromium 浏览器上呈现音频输出,用户需要安装 speech-dispatcher
并使用 --enable-speech-dispatcher
标志启动浏览器。
需要调用onvoiceschanged
事件处理程序和window.speech.synthesis.getVoices()
来填充可用语音列表。 API 并不简单。 .getVoices()
可能需要为SpeechSynthesisVoice
对象调用两次,以填充.getVoices()
返回的数组。
请注意,对.speak()
的调用可能会被放入队列中,并且不会呈现为音频输出,这不是立即显而易见的;调用window.speechSynthesis.cancel()
会清除队列,然后音频输出可能会意外呈现。
然后您可以使用window.speechSynthesis.speak()
。
一段时间以来,我们一直在尝试在 Chromium 浏览器中为 *nix 默认启用 SSML 解析;无需使用需要某种形式的 EUA 或不像啤酒那样免费的外部 Web 服务。
例如,为了实现这一目标而联系过的实体和被问到的问题的列表很长
SSML parsing implementation at browsers
How to extract SSML parsing code of espeak to implement SSML parsing at SpeechSynthesisUtterance?
How to set SSML parsing to on at user configuration file?
Why hasn't Issue 88072 and Issue 795371 been answered? Are Internals>SpeechSynthesis and Blink>Speech dead?
*nix 上的 Firefox 也不解析 SSML。
也许随着广大用户的更多兴趣,我们最终可以默认启用此功能。
虽然在不使用外部 Web 服务的情况下进行 SSML 解析有一些变通方法;下面的第一个链接仍未得到答复;虽然包括 php 代码,该代码使用 shell_exec()
调用二进制文件,然后 $_POST
到本地服务器
How to programmatically send a unix socket command to a system server autospawned by browser or convert JavaScript to C++ souce code for Chromium?
SpeechSynthesisSSMLParser
请注意,当前的 Web Speech API 实现存在几个错误,特别是更改 SpeechSynthesisUtterance
的 volume
属性对 Chromium 和 Firefox 的音频输出没有影响
Setting SpeechSynthesisUtterance.volume does not change volume of audio output of speechSynthesis.speak()
Setting SpeechSynthesisUtterance.volume does not change volume of audio output of speechSynthesis.speak()
在使用.pause()
和.resume()
时还有一个错误,在尝试以编程方式解析SSML 的<break>
元素时遇到此错误
使用显然已死的 Web Speech API 的替代方法是 speak.js
,它是通过将 espeak
移植到 JavaScript 或 meSpeak.js
(speak.js
的一个分支)创建的。 espeak-ng
现在得到积极维护,例如使用 meSpeak.js
的修改版本
或使用在线词典提供反映单词的语音文件
How to create or convert text to audio at chromium browser?有趣的是,在发布该答案后,“gstatic”“字典”不再提供音频文件。
幸运的是,我们有
mozilla/voice-web非常活跃。
我们还可以在 Chromium/Chrome 和 Firefox 中使用 Native Message 来调用与原生 shell 交互并调用二进制本身
How to parse JSON from stdin at Chrome Native Messaging host?
How to parse JSON from stdin at Native Messaging host?
Chrome Native Messaging throwing error when sending a base64 string to client
此代码使用Native Messaging 以最少的修改达到预期结果
Chrome Native messaging with PHP或者作为一个激烈的措施,改变二进制
How to set options of commands called by browser?(观点,有事实支持)
语音合成技术有一个庞大的网络服务市场,无论是在其生成(“[L]yrebird”)和识别 - 为了盈利,即“*lexa”; “*奥利”; (*bm) "*atson *luemix"; (*oogle) "*actions";等等
开源开发人员有责任继续努力在开源浏览器上维护开源(FOSS;FLOSS)语音合成技术。如果我们希望这些技术默认在浏览器中实现,开源开发人员必须编写代码来实现这一点。
【讨论】:
非常彻底。我想补充一点,Safari 在它运行的任何地方都支持 API(所以是的,“只有”iOS 和 macOS),并且与 Chromium 不同,语音合成是否离线(macOS 已经具备数十年的能力),这使得几个时间- Google 的综合不提供敏感功能。 @Touffy 没试过 macOS/safari。是的,注意到 Chromium 源代码对 tts 相关的几个文件拥有 *pple 版权 @Touffy macOS/safari 默认不支持 SSML 解析,对吗? 确实,据我所知,Safari 不支持 SSML(可能是因为底层的 MacOS API 也不支持),但这对于 OP 的简单需求来说应该不是问题。纯文本应该可以正常工作。 @Touffy 在对原始问题进行编辑之后,不确定问题的目的是什么,也不确定要求是什么。询问您有关 macOS/safari 中的 SSML 解析的问题,以确认 macOS/safari 中仍然不存在该功能。【参考方案2】:SpeechSynthesisUtterance
可以做到这一点
Web Speech API 的接口。有关此here 的更多信息。
下面的 javascript 在 Chrome 中执行时会显示“Welcome John Doe”。确保音量已调高!
const message = new SpeechSynthesisUtterance('Welcome, John Doe');
window.speechSynthesis.speak(message);
Web Speech API 还提供语音识别界面。以下代码会将口语打印到浏览器的控制台。
const recognition = new webkitSpeechRecognition();
recognition.onresult = function(event)
for (let i = event.resultIndex; i < event.results.length; ++i)
console.log(event.results[i][0].transcript);
要开始捕获语音,请运行recognition.start();
要停止捕获语音,请运行 recognition.stop();
鉴于这是一项实验性技术,它不会是完美的,并且并非所有浏览器和版本都支持它。查看browser compatibility table 了解支持的浏览器和版本。
【讨论】:
示例应该包含.getVoices()
调用,使用起来不是那么简单。
注意,声音是异步加载的。对window.speechSynthesis.speak()
的调用可能发生在SpeechSynthesisVoice
对象填充.getVoices()
返回的数组之前
识别和合成是在本地完成还是使用互联网?
@beppe9000 本地。 Chrome 附带了自己的声音版本,SpeechSynthesisUtterance
可以设置和使用。
@guest271314 不错以上是关于如何让我的网络浏览器以编程方式说话?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Angular 中浏览器的本机下载小部件以编程方式下载文件?