gpt4 book ai didi

javascript - 将语音对象而不是字符串传递给语音合成

转载 作者:行者123 更新时间:2023-12-01 12:04:03 24 4
gpt4 key购买 nike

感谢@Ivan我有一个简单的代码来通过复选框选择语音合成声音:

// Get the voice select element.
const select_US = document.querySelector('.select_US');
const select_UK = document.querySelector('.select_UK');
let selected_voices;

// Fetch the list of voices and populate the voice options at the beginning of the course
function loadVoices() {
// Fetch the available voices.
let voices_US = speechSynthesis.getVoices().filter(function(voice) {
return voice.lang == 'en-US';

});

//console.log(voices_US); //outputs array of voice objects

const checkboxes_US = voices_US.map(function(name) {

const html = `
<div>
<input type="checkbox" id="${name}" name="${name}">
<label for="${name}">${name.name}</label>
</div>
`.trim();

const wrapper = document.createElement('div');
wrapper.innerHTML = html;

const element = select_US.appendChild(wrapper.firstChild);
return element.querySelector('input');

});

//You have 3 seconds to select voices via checkboxes
setTimeout(function() {

selected_voices = checkboxes_US.filter(checkbox => checkbox.checked).map(checkbox => checkbox.name);

console.log(selected_voices);

}, 3000)

}

// Execute loadVoices.
loadVoices();

// Chrome loads voices asynchronously.
window.speechSynthesis.onvoiceschanged = function(e) {
loadVoices();
};

// Create a new utterance for the specified text and add it to
// the queue.
function speak(text) {
// Create a new instance of SpeechSynthesisUtterance.
var msg = new SpeechSynthesisUtterance();
msg.voice = selected_voices[0];

// Set the text.
msg.text = text;

// Queue this utterance.
window.speechSynthesis.speak(msg);
}

// after 5 seconds initiate speech synthesis
setTimeout(function() {
console.log('Speaking..');
speak('This is a simple example text here!');
}, 5000);
<div class="select_US">
</div>

预期的行为是用户有 3 秒的时间通过复选框选择声音。

用户可以根据需要选择任意数量的语音,但我们只想要数组中的第一个语音:

msg.voice = selected_voices[0];

如果 selected_voices 包含语音对象,代码将正常工作,但存在问题。当我记录它时:

enter image description here

好像是数组里面的字符串元素!

相反,我们应该看到:

enter image description here

我认为 selected_voices 是问题所在,它未能提供正确的值。

我该如何解决?没有手,我找不到解决方案。

最佳答案

要查看(部分)问题,请记录您生成的 HTML:

<div class="select_US">
<div>
<input type="checkbox" id="[object SpeechSynthesisVoice]" name="[object SpeechSynthesisVoice]">
<label for="[object SpeechSynthesisVoice]">Microsoft David Desktop - English (United States)</label>
</div><div>
<input type="checkbox" id="[object SpeechSynthesisVoice]" name="[object SpeechSynthesisVoice]">
<label for="[object SpeechSynthesisVoice]">Microsoft Zira Desktop - English (United States)</label>
</div><div>
<input type="checkbox" id="[object SpeechSynthesisVoice]" name="[object SpeechSynthesisVoice]">
<label for="[object SpeechSynthesisVoice]">Google US English</label>
</div></div>

看到[object SpeechSynthesisVoice]了吗?当你做的时候

  let voices_US = speechSynthesis.getVoices().filter(function(voice) {
return voice.lang == 'en-US';

});

voices_us 成为语音数组。但是当你这样做的时候

voices_US.map(function(name) {

name 包含的实际上是一个声音,而不是一个字符串,这是问题的很大一部分。这就是为什么精确的变量名很重要的原因之一。让我们改为调用参数 voice,并使用其 name 属性获取字符串。

然后,一旦超时回调运行,.find 选中的复选框之一。如果有,取它的name(一个字符串),然后在voices数组中.find同名的语音。然后,您可以将找到的语音分配给 voiceInstance 并在 speak 中使用 msg.voice = voiceInstance;

您还应该只运行一次 loadVoices 的主要部分,否则您将不断创建新的输入。

'use strict';

// Get the voice select element.
const select_US = document.querySelector('.select_US');
const select_UK = document.querySelector('.select_UK');
let voiceInstance;

// Fetch the list of voices and populate the voice options at the beginning of the course
function loadVoices() {
// Fetch the available voices.
const voices_US = speechSynthesis.getVoices().filter(voice => voice.lang == 'en-US');
if (!voices_US.length || voiceInstance) {
// Chrome; voices haven't loaded yet, or a voice is already selected
return;
}
const checkboxes_US = voices_US.map(function(voice) {
const { name } = voice;
const div = document.createElement('div');
div.innerHTML = `
<input type="checkbox" id="${name}" name="${name}">
<label for="${name}">${name}</label>
`;
select_US.appendChild(div);
return div.querySelector('input');
});

//You have 3 seconds to select voices via checkboxes
setTimeout(function() {
const checkbox = checkboxes_US.find(checkbox => checkbox.checked);
if (!checkbox) {
console.log('Not fast enough');
return;
}
const name = checkbox.name;
voiceInstance = speechSynthesis.getVoices().find(voice => voice.name === name);
}, 3000)

}

// Execute loadVoices.
loadVoices();

// Chrome loads voices asynchronously.
window.speechSynthesis.onvoiceschanged = loadVoices;

// Create a new utterance for the specified text and add it to
// the queue.
function speak(text) {
if (!voiceInstance) {
// No instance to use to speak with
return;
}
// Create a new instance of SpeechSynthesisUtterance.
var msg = new SpeechSynthesisUtterance();
msg.voice = voiceInstance;

// Set the text.
msg.text = text;

// Queue this utterance.
window.speechSynthesis.speak(msg);
}

// after 5 seconds initiate speech synthesis
setTimeout(function() {
console.log('Speaking..');
speak('This is a simple example text here!');
}, 5000);
<div class="select_US">
</div>

逻辑可能更容易理解,而不依赖于全局变量重新分配,如果每次超时都调用下一次:

'use strict';

if (!window.chrome) {
loadVoices();
} else {
// Chrome loads voices asynchronously.
window.speechSynthesis.addEventListener('voiceschanged', loadVoices, { once: true });
}

function loadVoices() {
const allVoices = speechSynthesis.getVoices();
const voices_US = allVoices.filter(voice => voice.lang == 'en-US');
const select_US = document.querySelector('.select_US');
const checkboxes_US = voices_US.map(function(voice) {
const { name } = voice;
const div = select_US.appendChild(document.createElement('div'));
div.innerHTML = `
<input type="checkbox" id="${name}" name="${name}">
<label for="${name}">${name}</label>
`;
return div.querySelector('input');
});

//You have 3 seconds to select voices via checkboxes
setTimeout(function() {
const checkbox = checkboxes_US.find(checkbox => checkbox.checked);
if (!checkbox) {
console.log('Not fast enough');
return;
}
const name = checkbox.name;
const voiceInstance = speechSynthesis.getVoices().find(voice => voice.name === name);
console.log('Voice found...');
setTimeout(speak, 2000, 'This is a simple example text here!', voiceInstance);
}, 3000)
}

function speak(text, voice) {
var msg = new SpeechSynthesisUtterance();
msg.voice = voice;
msg.text = text;
window.speechSynthesis.speak(msg);
}
<div class="select_US">
</div>

关于javascript - 将语音对象而不是字符串传递给语音合成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59548756/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com