Как использовать Web Speech API в Chrome?

Как использовать SpeechSynthesisUtterance() и window.speechSynthesis.speak() в браузере Chrome?

var msg = new SpeechSynthesisUtterance( "Hello I am browser" );
window.speechSynthesis.speak( msg );

не выводит звук на системные динамики.

Были отмечены проблемы с API. HTML5 SpeechSynthesis API - мусор;

var voices = window.speechSynthesis.getVoices();

записывает пустой массив для идентификатора voices; и только хром, но не хром, якобы поддерживает спецификацию Web Speech API Specification, Web Speech API Demonstration устанавливает значение html element при демонстрации высказывания, озвученного при включенном микрофоне на странице.

По крайней мере, часть кода JavaScript, относящегося к функциональности, очевидно

var langs =
[['Afrikaans',       ['af-ZA']],
 ['Bahasa Indonesia',['id-ID']],
 ['Bahasa Melayu',   ['ms-MY']],
 ['Català',          ['ca-ES']],
 ['Čeština',         ['cs-CZ']],
 ['Dansk',           ['da-DK']],
 ['Deutsch',         ['de-DE']],
 ['English',         ['en-AU', 'Australia'],
                     ['en-CA', 'Canada'],
                     ['en-IN', 'India'],
                     ['en-NZ', 'New Zealand'],
                     ['en-ZA', 'South Africa'],
                     ['en-GB', 'United Kingdom'],
                     ['en-US', 'United States']],
 ['Español',         ['es-AR', 'Argentina'],
                     ['es-BO', 'Bolivia'],
                     ['es-CL', 'Chile'],
                     ['es-CO', 'Colombia'],
                     ['es-CR', 'Costa Rica'],
                     ['es-EC', 'Ecuador'],
                     ['es-SV', 'El Salvador'],
                     ['es-ES', 'España'],
                     ['es-US', 'Estados Unidos'],
                     ['es-GT', 'Guatemala'],
                     ['es-HN', 'Honduras'],
                     ['es-MX', 'México'],
                     ['es-NI', 'Nicaragua'],
                     ['es-PA', 'Panamá'],
                     ['es-PY', 'Paraguay'],
                     ['es-PE', 'Perú'],
                     ['es-PR', 'Puerto Rico'],
                     ['es-DO', 'República Dominicana'],
                     ['es-UY', 'Uruguay'],
                     ['es-VE', 'Venezuela']],
 ['Euskara',         ['eu-ES']],
 ['Filipino',        ['fil-PH']],
 ['Français',        ['fr-FR']],
 ['Galego',          ['gl-ES']],
 ['Hrvatski',        ['hr_HR']],
 ['IsiZulu',         ['zu-ZA']],
 ['Íslenska',        ['is-IS']],
 ['Italiano',        ['it-IT', 'Italia'],
                     ['it-CH', 'Svizzera']],
 ['Lietuvių',        ['lt-LT']],
 ['Magyar',          ['hu-HU']],
 ['Nederlands',      ['nl-NL']],
 ['Norsk bokmål',    ['nb-NO']],
 ['Polski',          ['pl-PL']],
 ['Português',       ['pt-BR', 'Brasil'],
                     ['pt-PT', 'Portugal']],
 ['Română',          ['ro-RO']],
 ['Slovenščina',     ['sl-SI']],
 ['Slovenčina',      ['sk-SK']],
 ['Suomi',           ['fi-FI']],
 ['Svenska',         ['sv-SE']],
 ['Tiếng Việt',      ['vi-VN']],
 ['Türkçe',          ['tr-TR']],
 ['Ελληνικά',        ['el-GR']],
 ['български',       ['bg-BG']],
 ['Pусский',         ['ru-RU']],
 ['Српски',          ['sr-RS']],
 ['Українська',      ['uk-UA']],
 ['한국어',            ['ko-KR']],
 ['中文',             ['cmn-Hans-CN', '普通话 (中国大陆)'],
                     ['cmn-Hans-HK', '普通话 (香港)'],
                     ['cmn-Hant-TW', '中文 (台灣)'],
                     ['yue-Hant-HK', '粵語 (香港)']],
 ['日本語',           ['ja-JP']],
 ['हिन्दी',            ['hi-IN']],
 ['ภาษาไทย',         ['th-TH']]];

for (var i = 0; i < langs.length; i++) {
  select_language.options[i] = new Option(langs[i][0], i);
}
select_language.selectedIndex = 7;
updateCountry();
select_dialect.selectedIndex = 6;
showInfo('info_start');

function updateCountry() {
  for (var i = select_dialect.options.length - 1; i >= 0; i--) {
    select_dialect.remove(i);
  }
  var list = langs[select_language.selectedIndex];
  for (var i = 1; i < list.length; i++) {
    select_dialect.options.add(new Option(list[i][1], list[i][0]));
  }
  select_dialect.style.visibility = list[1].length == 1 ? 'hidden' : 'visible';
}

var create_email = false;
var final_transcript = '';
var recognizing = false;
var ignore_onend;
var start_timestamp;
if (!('webkitSpeechRecognition' in window)) {
  upgrade();
} else {
  start_button.style.display = 'inline-block';
  var recognition = new webkitSpeechRecognition();
  recognition.continuous = true;
  recognition.interimResults = true;

  recognition.onstart = function() {
    recognizing = true;
    showInfo('info_speak_now');
    start_img.src = '/intl/en/chrome/assets/common/images/content/mic-animate.gif';
  };

  recognition.onerror = function(event) {
    if (event.error == 'no-speech') {
      start_img.src = '/intl/en/chrome/assets/common/images/content/mic.gif';
      showInfo('info_no_speech');
      ignore_onend = true;
    }
    if (event.error == 'audio-capture') {
      start_img.src = '/intl/en/chrome/assets/common/images/content/mic.gif';
      showInfo('info_no_microphone');
      ignore_onend = true;
    }
    if (event.error == 'not-allowed') {
      if (event.timeStamp - start_timestamp < 100) {
        showInfo('info_blocked');
      } else {
        showInfo('info_denied');
      }
      ignore_onend = true;
    }
  };

  recognition.onend = function() {
    recognizing = false;
    if (ignore_onend) {
      return;
    }
    start_img.src = '/intl/en/chrome/assets/common/images/content/mic.gif';
    if (!final_transcript) {
      showInfo('info_start');
      return;
    }
    showInfo('');
    if (window.getSelection) {
      window.getSelection().removeAllRanges();
      var range = document.createRange();
      range.selectNode(document.getElementById('final_span'));
      window.getSelection().addRange(range);
    }
    if (create_email) {
      create_email = false;
      createEmail();
    }
  };

  recognition.onresult = function(event) {
    var interim_transcript = '';
    if (typeof(event.results) == 'undefined') {
      recognition.onend = null;
      recognition.stop();
      upgrade();
      return;
    }
    for (var i = event.resultIndex; i < event.results.length; ++i) {
      if (event.results[i].isFinal) {
        final_transcript += event.results[i][0].transcript;
      } else {
        interim_transcript += event.results[i][0].transcript;
      }
    }
    final_transcript = capitalize(final_transcript);
    final_span.innerHTML = linebreak(final_transcript);
    interim_span.innerHTML = linebreak(interim_transcript);
    if (final_transcript || interim_transcript) {
      showButtons('inline-block');
    }
  };
}

function upgrade() {
  start_button.style.visibility = 'hidden';
  showInfo('info_upgrade');
}

var two_line = /\n\n/g;
var one_line = /\n/g;
function linebreak(s) {
  return s.replace(two_line, '<p></p>').replace(one_line, '<br>');
}

var first_char = /\S/;
function capitalize(s) {
  return s.replace(first_char, function(m) { return m.toUpperCase(); });
}

function createEmail() {
  var n = final_transcript.indexOf('\n');
  if (n < 0 || n >= 80) {
    n = 40 + final_transcript.substring(40).indexOf(' ');
  }
  var subject = encodeURI(final_transcript.substring(0, n));
  var body = encodeURI(final_transcript.substring(n + 1));
  window.location.href = 'mailto:?subject=' + subject + '&body=' + body;
}

function copyButton() {
  if (recognizing) {
    recognizing = false;
    recognition.stop();
  }
  copy_button.style.display = 'none';
  copy_info.style.display = 'inline-block';
  showInfo('');
}

function emailButton() {
  if (recognizing) {
    create_email = true;
    recognizing = false;
    recognition.stop();
  } else {
    createEmail();
  }
  email_button.style.display = 'none';
  email_info.style.display = 'inline-block';
  showInfo('');
}

function startButton(event) {
  if (recognizing) {
    recognition.stop();
    return;
  }
  final_transcript = '';
  recognition.lang = select_dialect.value;
  recognition.start();
  ignore_onend = false;
  final_span.innerHTML = '';
  interim_span.innerHTML = '';
  start_img.src = '/intl/en/chrome/assets/common/images/content/mic-slash.gif';
  showInfo('info_allow');
  showButtons('none');
  start_timestamp = event.timeStamp;
}

function showInfo(s) {
  if (s) {
    for (var child = info.firstChild; child; child = child.nextSibling) {
      if (child.style) {
        child.style.display = child.id == s ? 'inline' : 'none';
      }
    }
    info.style.visibility = 'visible';
  } else {
    info.style.visibility = 'hidden';
  }
}

var current_style;
function showButtons(style) {
  if (style == current_style) {
    return;
  }
  current_style = style;
  copy_button.style.display = style;
  email_button.style.display = style;
  copy_info.style.display = 'none';
  email_info.style.display = 'none';
}

приписывается авторам документа.

Хотя не уверены, как это влияет на использование SpeechSynthesisUtterance() и window.speechSynthesis.speak()?

Как загрузить голоса для заполнения window.speechSynthesis.getVoices()?

Как связанный демонстрационный документ реализует функцию преобразования голоса в текст?

Какие обходные пути необходимы для использования Web Speech API в браузере Chrome?

В частности, как преобразовать голос в текст и преобразовать текст в аудиовыход?


person guest271314    schedule 17.05.2017    source источник
comment
SpeechSynthesisUtterance и speak () отлично работают в хромированных окнах7. getVoices () возвращает пустой массив перед Speak (). Но если я попробую speak (), а затем getVoices (), он вернет голоса. Версия 61.0.3125.0 (сборка разработчика) (32-разрядная)   -  person karthick    schedule 09.06.2017
comment
@karthick В настоящее время пробует хром 58 на 32-битном * nix. Можете ли вы создать plnkr plnkr.co, чтобы продемонстрировать шаблон, который вы описываете?   -  person guest271314    schedule 09.06.2017
comment
Вот кодовый код codepen.io/pen/OgMEgK. Изначально массив голосов будет пустым. Но после SpeakSyntesis.speak () он возвращает параметры   -  person karthick    schedule 09.06.2017
comment
возможно, это зависит от ОС   -  person karthick    schedule 09.06.2017
comment
@karthick Да, это может быть так. Здесь при обоих вызовах возвращается пустой массив.   -  person guest271314    schedule 09.06.2017


Ответы (2)


Установите espeak с помощью диспетчера пакетов

$ sudo apt-get install espeak

Запустите Chromium с флагом --enable-speech-dispatcher

$ chromium-browser --enable-speech-dispatcher
person guest271314    schedule 10.07.2017
comment
Это действительно работает для вас? Это не для меня, и когда начинается хром, он жалуется, потому что --enable-speech-dispatcher Unsupported flag has been used - person Ömer Faruk Almalı; 28.01.2019
comment
@ ÖmerFarukAlmalı В каких версиях Chromium / Chrome и в каких ОС вы пробовали Web Speech API? espeak или espeak-ng и speechd установлены? - person guest271314; 30.01.2019
comment
Последний Chromium (81.4044.129), установил espeak, как было предложено, и начал с командной строки ... у меня не работает (в Ubuntu 18.04.4, Linux 4.15.0). - person Jeach; 05.05.2020
comment
Хотя я пользуюсь Firefox, это дало мне подсказку. Установка espeak-ng и speech-dispacher, создание и редактирование файла конфигурации в соответствии с этим обсуждением и наконец, перезагрузка заставила мой Firefox правильно работать с классом SpeechSynthesis. Однако на Chromium он по-прежнему не работает. Протестировано в Arch Linux. - person ynn; 29.05.2020
comment
Работал на хроме 90.0.4430.93 (арка), установил espeak, espeak-ng, speech-dispatcher, запустил хром с chromium --enable-speech-dispatcher. Первый запуск будет иметь неподдерживаемый флаг, это повлияет на стабильность сообщения, но оно все равно сработало - person Kristian; 10.05.2021

  1. Недавно я попытался обернуть свое приложение, использующее SpeechSynthesis, с NWjs.

Правильно работает на Mac (в mac os по умолчанию есть голоса).

Поскольку NWjs использует Chromium в качестве движка браузера, это доказывает, что SpeechSynthesis работает.

IMHO, единственная разница между Chrome и Chromium в том, что Chromium не имеет голосов Google и, следовательно, не будет работать на машине без установленных голосов.

person yurin    schedule 22.01.2020