javascript - 向 Speech Synthesis API 添加暂停和播放功能

标签 javascript text-to-speech

我是 JavaScript 的新手,我正在尝试通过将按钮链接到 synth.pause(speakText); 添加暂停按钮,其中 const synth = window.speechSynthesis;const speakText = new SpeechSynthesisUtterance(textInput.value);

我无法让暂停函数访问 speakText,因为我在我的 speak() 函数中构建了我的 speakText 对象。我尝试通过在函数外部调用其构造函数来使 speakText 成为全局变量,但这会导致 speak() 抛出错误。

关于如何实现这一目标的任何想法?

JS代码:

//Speak
const speak = () => {
  //Check to see if already speaking
  if (synth.speaking && state === "play") {
    console.error("Already speaking");
    state = "paused";
    console.log("state: " + state);
    return;
  }
  //Make sure there is some input
  if (textInput.value !== "" && state === "stop") {
    const speakText = new SpeechSynthesisUtterance(textInput.value);
    state = "play";

    //Speak error
    speakText.onerror = e => {
      console.log("Something went wrong!");
    };

    //Selected voice
    const selectedVoice = voiceSelect.selectedOptions[0].getAttribute(
      "data-name"
    );

    //Loop through voices to set the correct voice
    voices.forEach(voice => {
      if (selectedVoice === voice.name) {
        speakText.voice = voice;
      }
    });

    //Set the rate and pitch
    speakText.rate = rate.value;
    speakText.pitch = pitch.value;

    //Speak end
    speakText.onend = e => {
      console.log("Done Speaking");
      state = "stop";
    };

    speakController(speakText);
  }
};

const speakController = speakText => {
  console.log("state: " + state);
  if (state === "play") {
    synth.speak(speakText);
  } else if (state === "pause") {
    synth.pause(speakText);
  } else if (state === "stop") {
    synth.cancel(speakText);
  }
};

//----------EVENT LISTENERS----------
var state = "stop";

// Text form submit
textForm.addEventListener("submit", e => {
  e.preventDefault();
  speak();
  textInput.blur();
});

//Pause button
pauseButton.addEventListener("onClick", e => {
  e.preventDefault();
  speakController;
});

最佳答案

[..How..] to add a pause button by linking a button to synth.pause(speakText);

廉价的答案是让按钮调用 speechSynthesis.pause()(它不带参数)——因为 synth 只是全局的副本window.speechSynthesis 属性。

更好的解决方案是创建一个 Controller ,它向外部调用者公开方法和属性的接口(interface),并封装其自己的内部工作。

你在这里提到了这个问题:

I can't make speakText accessible to the pause function since I construct my speakText object in my speak() function.

这意味着存在代码结构设计问题。但是还有一个问题:语音合成器没有“播放”、“暂停”和“停止”的状态。它有“播放”和“暂停”两个相互排斥的状态,以及一个完全独立的“队列空”状态。

我不建议修复发布的代码 - 尽管我确实尝试过。这是我最终确定发生了什么的结果 - 这是实验代码,但希望播客能有所帮助!

"use strict";
const tr = {
	queue: null,
	pause: null,
	play:  null,
	cancel:  null,
	defaultRate: 1.1,
	defaultPitch: 1,
	// voice selection to do;
};
function createTextReader( tr) {
	let synth = window.speechSynthesis; // abbreviation
	let Utter = SpeechSynthesisUtterance; // abbreviation
	// queue
	tr.queue = (text, rate, pitch, voiceIndex) => {
		let utter = new Utter();
		utter.text = text;
		utter.rate = rate || tr.defaultRate || 1;
		utter.pitch = pitch || tr.defaultPitch || 1;
		// voice selection to do
		// if( voiceParam) ....
		synth.speak( utter);
	};
	tr.pause = () => synth.pause();
	tr.play = () => synth.resume();
	tr.cancel = () => synth.cancel();
}
window.addEventListener( "DOMContentLoaded", function (e) {
createTextReader( tr)}, false);
window.addEventListener("unload", e=>tr.cancel(), false);
<textarea cols=40 rows=4 id="queueText">
Press "queue text" to add text area content to the text reader. Press it multiple times to add text more than once.

Press "pause" to pause reading.

Press "play" to start or resume reading queued text from the speech synthesizer's fifo queue. Play mode is in effect at startup - but you could pause the reader before queuing text.

Press "cancel" to stop reading and empty the queue. It does not change pause versus play mode. If the reader is paused when cancel is clicked, it remains so afterwards.

This voice is the default voice in this browser, and may be different in another. More code is needed for voice selection. If you visit MDN's speech synthesis example on git hub, view page source and click on the link to "script.js" you can see how they do it.

Oh, and don't forget to cancel speech synthesis on window unload.

Thanks for listening!
</textarea><br>
<button type="button" onclick="tr.queue(queueText.value)">queue text</button>
<p>
<button type="button" onclick="tr.pause()">pause</button>
<button type="button" onclick="tr.play()">play</button>
<button type="button" onclick="tr.cancel()">cancel</button>
<p>

引用的 MDN 页面的链接是 https://mdn.github.io/web-speech-api/speak-easy-synthesis/

关于javascript - 向 Speech Synthesis API 添加暂停和播放功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54014865/

相关文章:

android - 在说文本时淡入和淡出音乐

android - 更改 Android 的 Text To Speech 的默认语音

javascript - 如何将 PHP smarty 模板与 Vue.js 集成?

javascript - 如何在 TypeScript 中捕获 "this"

php - 使用 jQuery 加载函数作为绝对路径

javascript - 在VS2010中构建ASP.NET项目时可以使用YUI压缩吗

javascript - 获取计算样式并省略默认值

objective-c - NSSpeechSynthesizer 和轨道持续时间

c# - SpeechSynthesizer 中的持续内存泄漏

c# - SpeechSynthesizer 无法获取所有已安装的语音