gpt4 book ai didi

javascript - SpeechSynthesisUtterance 脚本,带有播放、暂停、停止按钮以及语言和语音选择

转载 作者:行者123 更新时间:2023-11-29 22:45:40 28 4
gpt4 key购买 nike

我想用 SpeechSynthesisUtterance 阅读我的页面文本。

我找到了这个脚本:https://www.hongkiat.com/blog/text-to-speech/

几乎完美,但暂停按钮似乎没什么用,我希望我有设置语言和选择语音的能力。

我在这里找到了引用:https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance ,但我对 JavaScript 不是很了解。

对于语言,据我了解,应该使用html标签中设置的lang参数。

对于语音,我完全不知道如何在代码中实现它。

这很重要,因为我有英语、西类牙语、法语和意大利语的文本,没有语音和语言设置的结果有时听起来很奇怪。

更新

这些天我摆弄了一点,我设法(或多或少)结合了两个不同的脚本/示例。

这个:https://www.hongkiat.com/blog/text-to-speech/

还有这个:https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis#Examples

出来的代码是这样的:

HTML

<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="text-to-speech.js"></script>
</head>
<body>
<div class=buttons>
<button id=play></button> &nbsp;
<button id=pause></button> &nbsp;
<button id=stop></button>
</div>
<select id="voices">

</select>
<div id="description">
The SpeechSynthesis interface of the Web Speech API is the controller interface for the speech service; this can be used to retrieve information about the synthesis voices available on the device, start and pause speech, and other commands besides.
Questo è in italiano come viene?
</div>

</body>
</html>

CSS

@import url('https://fonts.googleapis.com/css?family=Crimson+Text');

.buttons {
margin-top: 25px;
}

button {
background: none;
border: none;
cursor: pointer;
height: 48px;
outline: none;
padding: 0;
width: 48px;
}

#play {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/play.svg);
}

#play.played {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/play1.svg);
}

#pause {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/pause.svg);
}

#pause.paused {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/pause1.svg);
}

#stop {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/stop.svg);
}

#stop.stopped {
background-image: url(https://rpsthecoder.github.io/js-speech-synthesis/stop1.svg);
}

JavaScript

onload = function() {
if ('speechSynthesis' in window) with(speechSynthesis) {

// select voices////
var synth = window.speechSynthesis;

var voiceSelect = document.querySelector('#voices');

var voices = [];

function populateVoiceList() {
voices = synth.getVoices().sort(function (a, b) {
const aname = a.name.toUpperCase(), bname = b.name.toUpperCase();
if ( aname < bname ) return -1;
else if ( aname == bname ) return 0;
else return +1;
});
var selectedIndex = voiceSelect.selectedIndex < 0 ? 0 : voiceSelect.selectedIndex;
voiceSelect.innerHTML = '';
for(i = 0; i < voices.length ; i++) {
var option = document.createElement('option');
option.textContent = voices[i].name + ' (' + voices[i].lang + ')';

if(voices[i].default) {
option.textContent += ' -- DEFAULT';
}

option.setAttribute('data-lang', voices[i].lang);
option.setAttribute('data-name', voices[i].name);
voiceSelect.appendChild(option);
}
voiceSelect.selectedIndex = selectedIndex;
}

populateVoiceList();
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = populateVoiceList;
}
//end select voices

var playEle = document.querySelector('#play');
var pauseEle = document.querySelector('#pause');
var stopEle = document.querySelector('#stop');
var flag = false;

playEle.addEventListener('click', onClickPlay);
pauseEle.addEventListener('click', onClickPause);
stopEle.addEventListener('click', onClickStop);

function onClickPlay() {
if (!flag) {
flag = true;
utterance = new SpeechSynthesisUtterance(document.querySelector('#description').textContent);
//utterance.voice = getVoices()[0];

//add voice//
var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
for(i = 0; i < voices.length ; i++) {
//if(voices[i].name === 'Google UK English Female') {
if(voices[i].name === selectedOption) {
utterance.voice = voices[i];
break;
}
}


voiceSelect.onchange = function(){
onClickStop();
stopEle.className = '';
onClickPlay();
playEle.className = 'played';
}
//and add voice

utterance.onend = function() {
flag = false;
playEle.className = pauseEle.className = '';
stopEle.className = 'stopped';
};
playEle.className = 'played';
stopEle.className = '';
speak(utterance);
}
if (paused) { /* unpause/resume narration */
playEle.className = 'played';
pauseEle.className = '';
resume();
}
}

function onClickPause() {
if (speaking && !paused) { /* pause narration */
pauseEle.className = 'paused';
playEle.className = '';
pause();
}
}

function onClickStop() {
if (speaking) { /* stop narration */
/* for safari */
stopEle.className = 'stopped';
playEle.className = pauseEle.className = '';
flag = false;
cancel();

}
}

}

else { /* speech synthesis not supported */
msg = document.createElement('h5');
msg.textContent = "Detected no support for Speech Synthesis";
msg.style.textAlign = 'center';
msg.style.backgroundColor = 'red';
msg.style.color = 'white';
msg.style.marginTop = msg.style.marginBottom = 0;
document.body.insertBefore(msg, document.querySelector('div'));
}

}

现在我有了播放、停止和暂停按钮(暂停仍然不起作用),我可以从设备可用的声音中选择一种声音。

似乎在 chrome 上运行良好,在 Firefox 上运行可能稍差(但我使用的是 Linux LMDE,也许是我的错)。过了一会儿,在 Chrome 上停止说话。我不知道为什么,但在我看来,我看到有人可能理解为什么在我这些天打开的数千个网页中的某些网页中,我必须重新打开它们。

如果选择的语音保存在 cookie 中就好了,所以如果我打开另一个页面,脚本会从我选择的最后一个语音开始(我不知道如何在 JavaScript 中实现)

更新2

我向前迈出了一些小步骤并进行了简化。

它似乎几乎可以工作,但并不总是暂停按钮,我现在最大的疑问是,使用 chrome,当我更新或更改页面时,它似乎不会停止,当你更改页面时,他保持不变,这真的很糟糕阅读上一页。

HTML

<div id="SpeechSynthesis">
<div>
<button id=play>play</button>
<button id=pause>pause</button>
<button id=stop>stop</button>
</div>
<select id="voices">

</select>
</div>
<p id="texttospeech">
The SpeechSynthesis interface of the Web Speech API is the controller interface for the speech service; this can be used to retrieve information about the synthesis voices available on the device, start and pause speech, and other commands besides.
Questo è in italiano come viene?
</p>

JavaScript

onload = function() {
if ('speechSynthesis' in window){
var synth = speechSynthesis;
var flag = false;

//stop when change page ???(not sure)
if(synth.speaking){ /* stop narration */
/* for safari */
flag = false;
synth.cancel();
}

/* references to the buttons */
var playEle = document.querySelector('#play');
var pauseEle = document.querySelector('#pause');
var stopEle = document.querySelector('#stop');

/* click event handlers for the buttons */
playEle.addEventListener('click', onClickPlay);
pauseEle.addEventListener('click', onClickPause);
stopEle.addEventListener('click', onClickStop);

// select voices////
//var synth = window.speechSynthesis;

var voiceSelect = document.querySelector('#voices');

var voices = [];

function populateVoiceList() {
voices = synth.getVoices().sort(function (a, b) {
const aname = a.name.toUpperCase(), bname = b.name.toUpperCase();
if ( aname < bname ) return -1;
else if ( aname == bname ) return 0;
else return +1;
});
var selectedIndex = voiceSelect.selectedIndex < 0 ? 0 : voiceSelect.selectedIndex;
voiceSelect.innerHTML = '';
for(i = 0; i < voices.length ; i++) {
var option = document.createElement('option');
option.textContent = voices[i].name + ' (' + voices[i].lang + ')';

if(voices[i].default) {
option.textContent += ' -- DEFAULT';
}

option.setAttribute('data-lang', voices[i].lang);
option.setAttribute('data-name', voices[i].name);
voiceSelect.appendChild(option);
}
voiceSelect.selectedIndex = selectedIndex;
}

populateVoiceList();
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = populateVoiceList;
}
//end select voices

function onClickPlay() {
if(!flag){
flag = true;
utterance = new SpeechSynthesisUtterance(document.querySelector('#texttospeech').textContent);
//utterance.voice = synth.getVoices()[0];

//add voice//
var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
for(i = 0; i < voices.length ; i++) {
//if(voices[i].name === 'Google UK English Female') {
if(voices[i].name === selectedOption) {
utterance.voice = voices[i];
break;
}
}

voiceSelect.onchange = function(){
onClickStop();
onClickPlay();
}
//and add voice

utterance.onend = function(){
flag = false;
};
synth.speak(utterance);

//fix stop after a while bug
let r = setInterval(() => {
console.log(speechSynthesis.speaking);
if (!speechSynthesis.speaking) {
clearInterval(r);
} else {
speechSynthesis.resume();
}
}, 14000);
//end fix stop after a while bug
}
if(synth.paused) { /* unpause/resume narration */
synth.resume();
}
}
function onClickPause() {
if(synth.speaking && !synth.paused){ /* pause narration */
synth.pause();
}
}
function onClickStop() {
if(synth.speaking){ /* stop narration */
/* for safari */
flag = false;
synth.cancel();
}
}
}
else {
msg = document.createElement('h5');
msg.textContent = "Detected no support for Speech Synthesis";
msg.style.textAlign = 'center';
msg.style.backgroundColor = 'red';
msg.style.color = 'white';
msg.style.marginTop = msg.style.marginBottom = 0;
document.body.insertBefore(msg, document.querySelector('#SpeechSynthesis'));
}
}

更新3

我试图用最后选择的声音添加一个 cookie。我添加了几个函数来管理 cookie,并在 onClickPlay() 函数中设置了 cookie。

//add voice//
var selectedOption = voiceSelect.selectedOptions[0].getAttribute('data-name');
for(i = 0; i < voices.length ; i++) {
//if(voices[i].name === 'Google UK English Female') {
if(voices[i].name === selectedOption) {
utterance.voice = voices[i];
setCookie('SpeechSynthesisVoice',voices[i].name,30);
break;
}
}

Firefox 设置 cookie 没有问题,chrome 没有(即使文件在在线服务器上)。

然后我尝试在 populateVoiceList() 函数中将保存在 cookie 中的语音设置为“已选择”:

//get cookie voice
var cookievoice = getCookie('SpeechSynthesisVoice');

//add selcted to option if if cookievoice
if (cookievoice === voices[i].name) {
option.setAttribute('selected', 'selected');
}

有效,我在代码中找到了“selected”,但似乎没有考虑,它总是从列表中的第一个语音开始说话,或者默认语音,我不确定,并且不是那些有“选择”的。

我使用的cookie函数:

//cookie functions
function setCookie(name, value, days) {
var expires = '',
date = new Date();
if (days) {
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = '; expires=' + date.toGMTString();
}
document.cookie = name + '=' + value + expires + '; path=/';
}

function getCookie(name) {
var cookies = document.cookie.split(';'),
length = cookies.length,
i,
cookie,
nameEQ = name + '=';
for (i = 0; i < length; i += 1) {
cookie = cookies[i];
while (cookie.charAt(0) === ' ') {
cookie = cookie.substring(1, cookie.length);
}
if (cookie.indexOf(nameEQ) === 0) {
return cookie.substring(nameEQ.length, cookie.length);
}
}
return null;
}

function eraseCookie(name) {
createCookie(name, '', -1);
}

最佳答案

我没有得到太多帮助,但我设法设置了一个读取网页文本的小型播放器。

我做了一个带有演示的小教程,解释了我做了什么以及它是如何工作的。

https://www.alebalweb-blog.com/85-text-to-speech-player-with-buttons-play-pause-stop-and-voice-choice.html

关于javascript - SpeechSynthesisUtterance 脚本,带有播放、暂停、停止按钮以及语言和语音选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58758819/

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