Добавление функции паузы и воспроизведения в Speech Synthesis API - PullRequest
0 голосов
/ 03 января 2019

Я новичок в JavaScript и пытаюсь добавить кнопку паузы, связав кнопку с synth.pause(speakText);, где const synth = window.speechSynthesis; и const speakText = new SpeechSynthesisUtterance(textInput.value);.

Я не могу сделать speakText доступным для функции pause, так как я создаю свой объект speakText в моей функции speak (). Я попытался сделать speakText глобальной переменной, вызвав ее конструктор за пределами функции, но это заставляет говорить () выдавать ошибку.

Есть идеи, как мне этого добиться?

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;
});

1 Ответ

0 голосов
/ 03 января 2019

[.. Как ..] добавить кнопку паузы, связав кнопку с synth.pause (speakText);

Дешевый ответ будет иметь вызов кнопки speechSynthesis.pause() (который не принимает аргументов) - потому что synth является просто копией глобального свойства window.speechSynthesis.

Лучшим решением является создание контроллера, который предоставляет интерфейс методов и свойств внешним вызывающим и инкапсулирует его собственные внутренние операции.

Вы затронули проблему здесь:

Я не могу сделать speakText доступным для функции pause, так как я создаю свой объект speakText в своей функции speak ().

, что означает, что существует проблема проектирования структуры кода.Но есть и другая проблема: синтезатор речи не имеет состояний «воспроизведение», «пауза» и «остановка».Он имеет два взаимоисключающих состояния «play» и «pause» и полностью независимое условие «queue empty».

Я не предлагаю исправлять опубликованный код - хотя я, конечно, пытался.Вот что я в итоге выяснил, что происходит - это экспериментальный код, но, надеюсь, подкаст поможет!

"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/

...