Речь обрывается в Firefox, когда страница автоматически обновляется, но не в Google Chrome. - PullRequest
0 голосов
/ 23 января 2019

У меня есть проблема, когда в Firefox речь отключается, если страница автоматически обновляется, но в Google Chrome она заканчивает произносить речь, даже если страница автоматически обновляется.Как это исправить, чтобы речь не была обрезана в Firefox, даже если страница автоматически обновляется?

msg = new SpeechSynthesisUtterance("please finish saying this entire sentence.");
window.speechSynthesis.speak(msg);

(function ($) {
  'use strict';
  if (window == window.top) {
    var body = $('body').empty();
    var myframe = $('<iframe>')
      .attr({ src: location.href })
      .css({ height: '95vh', width: '100%' })
      .appendTo(body)
      .on('load', function () {
        var interval;
        interval = 750; 
        setTimeout(function () {
          myframe.attr({ src: location.href });
        }, interval);
      });
  }
})(jQuery);

Ответы [ 5 ]

0 голосов
/ 24 июля 2019

РЕДАКТИРОВАНИЕ: См. Более элегантное решение с обещаниями ниже первоначального ответа!


Ниже приведен обходной путь к несоответствиям браузера, обнаруженным в Firefox, с проверкой synth.speaking в интервалеи только запуск перезагрузки, если он false предотвращает преждевременную обрезку синтезатора:

(Он не работает должным образом в фрагменте SO, я предполагаю, что он не любит iFrames в iFrames иличто угодно, просто скопируйте, вставьте код в файл и откройте его с помощью Firefox!)

<p>I'm in the body, but will be in an iFrame</p>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
	var synth = window.speechSynthesis;
	msg = new SpeechSynthesisUtterance("please finish saying this entire sentence.");
	synth.speak(msg);
	
	(function ($) {
		'use strict';
		if (window == window.top) {
			var body = $('body').empty();
			var myframe = $('<iframe>')
				.attr({ src: location.href })
				.css({ height: '95vh', width: '100%' })
				.appendTo(body)
				.on('load', function () {
					var interval;
					interval = setInterval(function () {
						if (!synth.speaking) {
							myframe.attr({ src: location.href });
							clearInterval(interval);
						}
					}, 750);
				});
		}
	})(jQuery);
</script>

Более сложным решением может быть отсутствие каких-либо setTimeout() или setInterval(), а использование обещаний.Таким образом, страница будет просто перезагружаться всякий раз, когда сообщение будет синтезировано, независимо от того, насколько оно короткое или длинное.Это также предотвратит "двойную" / перекрывающуюся речь при начальной загрузке страницы.Не уверен, поможет ли это в вашем сценарии, но вы идете:

<button id="toggleSpeech">Stop Speaking!</button>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
	if (window == window.top) {
		window.speech = {
			say: function(msg) {
				return new Promise(function(resolve, reject) {
					if (!SpeechSynthesisUtterance) {
						reject('Web Speech API is not supported');
					}
					
					var utterance = new SpeechSynthesisUtterance(msg);
					
					utterance.addEventListener('end', function() {
						resolve();
					});
					
					utterance.addEventListener('error', function(event) {
						reject('An error has occurred while speaking: ' + event.error);
					});
					
					window.speechSynthesis.speak(utterance);
				});
			},
			speak: true,
		};
	}
	
	
	(function($) {
		'use strict';

		if (window == window.top) {
			var body = $('body').empty();
			var myframe = $('<iframe>')
				.attr({ src: location.href })
				.css({ height: '95vh', width: '100%' })
				.appendTo(body)
				.on('load', function () {
					var $iframe = $(this).contents();

					$iframe.find('#toggleSpeech').on('click', function(e) {
						console.log('speaking will stop when the last sentence is done...');
						window.speech.speak = !window.speech.speak;
					});
					
					window.speech.say('please finish saying this entire sentence.')
						.then(function() {
							if ( window.speech.speak ) {
								console.log('speaking done, reloading iframe!');
								myframe.attr({ src: location.href });
							}
						});
				});
		}
	})(jQuery);
</script>

ПРИМЕЧАНИЕ : Chrome (начиная с версии 70) НЕ позволяет немедленно вызывать window.speechSynthesis.speak(new SpeechSynthesisUtterance(msg)), вы получите ошибку speechSynthesis.speak() without user activation is no longer allowed..., большедетали здесь .Таким образом, технически пользователь должен активировать скрипт в Chrome, чтобы он заработал!

0 голосов
/ 24 февраля 2019

Не уверен, почему есть разница в поведении ... guest271314 может быть что-то в его ответе.Тем не менее, вы можете запретить FF останавливать tts, перехватывая событие reload с помощью обработчика onbeforeunload и ожидая окончания произнесения:

msg = new SpeechSynthesisUtterance("say something");
window.speechSynthesis.speak(msg);
window.onbeforeunload = function(e) {
  if(window.speechSynthesis.speaking){
    event.preventDefault();
    msg.addEventListener('end', function(event) {
      //logic to continue unload here
    });
  }
};
0 голосов
/ 20 февраля 2019

У меня есть проблема, когда в Firefox речь отключается, если страница автоматически обновляется, но в Google Chrome она заканчивает произносить речь, даже если страница автоматически обновляется.

Описанное поведение для Firefox является разумной ожидаемой реализацией.

Просмотр исходного кода в Firefox и Chromium, реализация speechSynthesis.speak() основана на сокетном соединении с локальной речьюсервер.Этот сервер в * nix обычно speech-dispatcher или speechd (speech-dispatcher).См. Как программно отправлять команду сокета unix на системный сервер, автоматически запускаемый браузером, или конвертировать JavaScript в C ++ souce-код для Chromium? для описания попытки реализовать синтаксический анализ SSML в Chromium.

В конечном итоге было решено написать собственный код для выполнения этого требования с использованием JavaScript в соответствии со спецификацией W3C SpeechSynthesisSSMLParser после того, как он задавал более одного вопроса на сайтах SE, регистрировал проблемы и ошибки и размещал их в списках рассылки W3Cбез каких-либо доказательств того, что синтаксический анализ SSML когда-либо будет включен как часть API веб-речи.

Как только это соединение инициировано, создается очередь для вызовов на .speak().Даже когда соединение закрыто, Task Manager может по-прежнему отображать активный процесс, зарегистрированный службой.

Процесс в Chromium / Chrome не лишен ошибок, наиболее близких к тому, что описано в вопросе.is

.volume проблемы со свойствами

Наиболее вопиющей проблемой является реализация Chromium / Chrome webkitSpeechReconition, которая записывает аудио пользователя и передает эти аудиоданные в удаленную службу, где транскрипт возвращается в браузер - без явного уведомления пользователя о том, чтопроисходит, отмечен WONT FIX

Соответствующие проблемы W3C Speech API на GitHub


Таким образом, не будет описывать поведение в Firefox как «проблему», а поведение в Chrome как потенциальную «проблему».

Погружение в реализацию W3C Web Speech API в браузерах не является тривиальной задачей.По нескольким причинам.Включая очевидную направленность или доступный вариант коммерческих услуг TTS / SST и проприетарных реализаций синтеза и распознавания речи с закрытым исходным кодом в «смартфонах»;вместо исправления различных проблем с фактическим развертыванием W3C Web Speech API в современных браузерах.

Сопровождающие speechd (речь-диспетчер) очень полезны в отношении серверной части (локальной *)1134 * гнездо).

Не может говорить за сопровождающих Firefox.Предполагается, что маловероятно, что, если будет подана ошибка, относящаяся к запросу функции продолжения выполнения вывода звука .speak() с перезагруженного window, это согласуется с недавними политиками автоматического воспроизведения, реализованными браузерами.Хотя вы все равно можете отправить сообщение об ошибке в Firefox, чтобы спросить, ожидается ли продолжение вывода звука (из любого API или интерфейса) во время перезагрузки текущей window;и если есть какие-либо предпочтения или политики, которые можно установить для переопределения описанного поведения, как предложено в ответе @zip.И получите ответ от самих разработчиков.

Существуют отдельные лица и группы, которые составляют код FOSS, которые активны в домене и готовы помочь в разработке SST / TTS, многие из которых активны в GitHub, что является еще одним вариантом задать вопросы о том, как реализовать то, чтовы пытаетесь достичь именно этого в браузере Firefox.

Помимо запроса к компоненту запроса на функцию, вы можете прочитать исходный код и попытаться создать один или несколько обходных путей.В качестве альтернативы можно использовать meSpeak.js, хотя это не обязательно означает, что Firefox намеренно блокирует аудиовыход во время перезагрузки window.

0 голосов
/ 24 февраля 2019

Экспериментальная технология, вероятно, неправильно обрабатывается Firefox.

Попробуйте SpeechSynthesis.cancel(), прежде чем повторить свой .speak() вызов.

var synth = window.speechSynthesis;
let msg = new SpeechSynthesisUtterance("say something");
synth.cancel();
msg = new SpeechSynthesisUtterance("say something");
synth.speak(msg);
0 голосов
/ 04 февраля 2019

Firefox:

Прежде всего введите и найдите «about: config» в браузере, заполнив его в адресной строке. Это перейдет на другую страницу, где будет всплывающее окно с просьбой принять любой риск, вы должны принять это. Найдите в списке параметр с именем «accessibility.blockautorefresh» и щелкните его правой кнопкой мыши. На экране будут отображаться некоторые параметры, выберите параметр «Переключить» и установите для него значение «Истина», а не «Ложь». Это изменение заблокирует автоматическое обновление в браузере Firefox. Помните, что эта опция обратима!

...