【问题标题】:Why Can't I Choose Female "Microsoft Zira" Voice in SpeechSynthesisUtterance()?为什么我不能在 SpeechSynthesisUtterance() 中选择女性“Microsoft Zira”语音?
【发布时间】:2021-07-31 04:01:28
【问题描述】:

我的以下 HTML 页面正确地朗读了文本,但它不是用女性声音朗读 Microsoft Zira Desktop - English (United States)问题:我可能在这里遗漏了什么,我们怎样才能让它以女性的声音说话?

备注:我在MS EdgeGoogle Chrome 中多次尝试了这个html,无论是否刷新页面,但它一直用相同的男性声音说话。似乎它忽略了下面 JavaScript 中的 msg.voice 值。我正在使用Windows 10 - 这可能不重要。

<!DOCTYPE html>
<html>
<head>
<script>
    function myFunction() {
  var msg = new SpeechSynthesisUtterance();
      msg.voice = speechSynthesis.getVoices().filter(function(voice) {
    return voice.name == "Microsoft Zira Desktop - English (United States)"})[0];
    msg.text = document.getElementById("testDiv").textContent;
    window.speechSynthesis.speak(msg);
}
</script>
</head>
<body>

<h2>JavaScript in Head</h2>

<div id="testDiv">SQL Managed Instance gives you an instance of SQL Server but removes much of the <b>overhead</b> of managing a <u>virtual machine</u>. Most of the features available in SQL Server are available in SQL Managed Instance. This option is ideal for customers who want to use instance-scoped features and want to move to Azure without rearchitecting their applications.</div>

<button type="button" onclick="myFunction()">Try it</button>

</body>
</html>

更新

根据用户 @Frazer 的建议,我在我的 google chrome 控制台中运行 speechSynthesis.getVoices() 并得到以下结果 - 其中确实包含 Microsoft Zira .... 语音:

观察

按照this 的建议,我将&lt;script&gt; 块移到了主体块的末尾(就在&lt;/body&gt; 之前),但仍然是相同的男声。 但是,当我将声音从Microsoft Zira Desktop - English (United States) 替换为Google UK English Female 时,会发生以下情况:在第一次点击Try it 按钮时,扬声器仍然是默认男性,但在随后的每一次点击中在这个按钮上,我正确地得到了Google UK English Female 的声音。注意:Microsoft Zira Desktop - English (United States) 在上述场景中没有任何作用。这让我相信这项技术仍然是体验式的——正如 here 所述。

【问题讨论】:

  • 您的代码对我有用。如果您在控制台中运行 SpeechSynthesis.getVoices() 会发生什么? Zira 是回归的声音之一吗?
  • @Frazer 感谢您调查此问题。根据您的建议,我在控制台中运行了speechSynthesis.getVoices(),它确实包含 zira。我添加了一个 UPDATE 部分来回答您的问题。
  • 如果您尝试其中一种 Google 语音会发生什么,例如“谷歌英国英语女性”?
  • @Frazer 仍然完全相同(可能是 Windows 10 上的默认设置)男性声音。在其他在线应用程序上,当我从下拉菜单中选择不同的声音(男性或女性)时,它会正确地使用所选声音说话。它只是没有发生在我的本地 html 文件上(如上所示)。
  • 如果在控制台中按顺序运行这些会发生什么?你得到什么输出?:speechSynthesis.getVoices(); const u = new SpeechSynthesisUtterance('1'); u.voice = SpeechSynthesis.getVoices()[2];语音合成.speak(u);

标签: javascript text-to-speech speech-synthesis webspeech-api


【解决方案1】:

为什么它适用于某些浏览器?

我在这里有一个类似问题的答案 Why is the voiceschanged event fired on page load?,但我认为您的情况已经完全不同,值得一个新的答案。

首先,为什么它有时会起作用?因为"Microsoft Zira Desktop - English (United States)" 是通过 API 调用从 Web 检索到的,并且在下一行执行时这些数据不可用。 基本上,您应该等到onvoiceschanged 被调用,然后才能真正调用getVoices() 来获取声音。

引用文档...

然而,对于 Chrome,您必须等待事件触发后才能填充列表,因此底部的 if 语句如下所示。 (来源:MDN WebDocs: SpeechSynthesis.onvoiceschanged)(强调我的。)

如果列表未填充,并且您没有可用的女性语言,则默认情况下会播放男性语言。

因为构造函数 `getVoices()` 进行 API 调用,所以将其视为异步

尝试像这样运行您的代码...

var msg = new SpeechSynthesisUtterance();
var voices = window.speechSynthesis.getVoices();

window.speechSynthesis.onvoiceschanged = function() {
    voices = window.speechSynthesis.getVoices();
};

function myFunction() {
    console.log(voices);
      msg.voice = voices.filter(function(voice) {
    return voice.name == "Microsoft Zira - English (United States)"})[0];
    console.log(msg.voice);
    msg.text = document.getElementById("testDiv").textContent;
    window.speechSynthesis.speak(msg);
}

附:这是我自己的编码示例,说明如何处理文本到音频阅读器上加载的声音:GreenGluon CMS: text-audio.js 也在这里:PronounceThat.com pronounce-that.js

【讨论】:

  • 我运行了你的代码(你从我的代码中修改的)。当页面首次在 Google Chrome 控制台中加载时,它会打印 Before page is fully loaded. Test.html:7 []length: 0[[Prototype]]: Array(0)。当我点击Try it 按钮时,它会打印Now page is fully loaded. 以及上面我的帖子 UPDATE 部分的屏幕截图中显示的文本。从这个测试来看,它似乎应该工作 - 但由于某些原因,它不是。 Web 连接似乎不是问题。还有其他建议吗?
  • Hrm,我在pronouncethat.com 使用我的代码。它也基本上是一样的,只是一个文本到音频的按钮。那样有用吗?看起来你可能有一个奇怪的特殊情况,但是用 SpeechSynthesis 加载声音总是很棘手。
  • 哦,嘿,只是想一想,我在看发音that.com 和你的代码之间的差异,也许把var msg = new SpeechSynthesisUtterance(); 放在函数定义之外,所以,声音肯定是加载在您实际调用它的时间。或者,将您的逻辑移至window.speechSynthesis.onvoiceschanged = function () {}
  • 您的网站与选择 Microsoft Zira Desktop - English (United States) 完美配合。此外,根据您的建议,将 var msg = new SpeechSynthesisUtterance(); 移到函数之外,它可以在不将脚本块移动到正文块末尾的情况下工作。但是,第一次单击仍会产生默认的男声。而且,它适用于Google UK English Female,但不适用于Microsoft Zira Desktop - English (United States)。而且,它适用于 Chrome,但不适用于 Edge。我同意我可能有一个奇怪的特殊情况。
  • @nam 嘿,我在上面的答案中添加了一些代码,我认为 应该 100% 解决您的问题。它在新的中间部分,“在此处调用您的代码”等。我认为这应该可以解决它。
【解决方案2】:

将“禁用”属性添加到您的按钮,然后在 /body 标记之前使用 Zira 或 Chrome 语音尝试此操作。

speechSynthesis.onvoiceschanged = () => {
  voices = speechSynthesis.getVoices()
  if (voices.length) document.querySelector("button").disabled = false
}
let voices = speechSynthesis.getVoices()

const  myFunction = () => {
  const msg = new SpeechSynthesisUtterance();
  msg.voice = voices.filter(voice => {
    return voice.name === "Microsoft Zira Desktop - English (United States)"
  })[0];
  msg.text = document.getElementById("testDiv").textContent;
  speechSynthesis.speak(msg);
}

【讨论】:

  • 一个很好的改进:在带有Google UK English Female 的 Chrome 上,您的代码也可以在第一次单击按钮时运行。仍然没有发生的事情:在 Chrome 上,它不适用于 Microsoft Zira Desktop - English (United States)。在 Edge 上,它继续使用 Microsoft Zira....Google UK English Female 的默认男声。不确定与 Microsoft 相关的问题发生了什么。至少我对你的努力表示赞成 (+1)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 2015-06-30
  • 1970-01-01
  • 2023-03-24
相关资源
最近更新 更多