Несколько недель назад я кратко обсудил НЛП и связанные с ним технологии. При работе с естественным языком необходимо учитывать два различных, но дополняющих друг друга аспекта: автоматическое распознавание речи ( ASR ) и преобразование текста в речь ( TTS ). В статье « Знакомство с API веб-речи» я рассмотрел API веб-речи, API-интерфейс, обеспечивающий функции речевого ввода и вывода текста в речь в веб-браузере. Возможно, вы заметили, что я только представил, как реализовать распознавание речи на веб-сайте, а не синтез речи. В этой статье мы восполним пробел, описывающий API для синтеза речи .
Распознавание речи дает пользователям, особенно людям с ограниченными возможностями, возможность предоставлять информацию на веб-сайт. Вспоминая примеры использования, которые я выделил:
На веб-сайте пользователи могут перемещаться по страницам или заполнять поля формы с помощью своего голоса. Пользователи также могут взаимодействовать со страницей во время вождения, не отрывая глаз от дороги. Это не тривиальные случаи использования.
Итак, мы можем видеть его как канал от пользователя к сайту. Синтез речи происходит наоборот, предоставляя веб-сайтам возможность предоставлять информацию пользователям, читая текст. Это особенно полезно для слепых и, в целом, для людей с нарушениями зрения.
Синтез речи имеет столько же вариантов использования, сколько и распознавание речи. Подумайте о системах, реализованных в некоторых новых автомобилях, которые читают ваши тексты или электронные письма, чтобы вам не пришлось отвлекаться от дороги. Люди с нарушениями зрения, использующие компьютеры, знакомы с такими программами, как JAWS, которые читают все, что есть на рабочем столе, что позволяет им выполнять задачи. Эти приложения хороши, но они стоят больших денег. Благодаря API синтеза речи мы можем помочь людям, использующим наши веб-сайты, независимо от их инвалидности.
В качестве примера представьте, что вы пишете пост в своем блоге (как я делаю сейчас), и чтобы улучшить его читабельность, вы разбили его на несколько абзацев. Разве это не хороший шанс использовать API для синтеза речи? Фактически, мы могли бы запрограммировать наш веб-сайт таким образом, чтобы, когда пользователь наводит курсор на текст (или фокусируется на нем), на экране появляется значок динамика. Если пользователь щелкает значок, мы вызываем функцию, которая будет синтезировать текст данного абзаца. Это нетривиальное улучшение. Более того, у нас, как у разработчиков, накладные расходы очень низкие, а у пользователей — нет. Основная реализация этой концепции показана в бункере JS ниже.
Теперь, когда мы знаем больше о вариантах использования этого API, давайте узнаем о его методах и свойствах.
Методы и свойства
API синтезирования речи определяет интерфейс, называемый SpeechSynthesis
, структура которого представлена здесь . Как и в предыдущей статье, эта статья не охватывает все свойства и методы, описанные в спецификации. Причина в том, что это слишком сложно, чтобы быть освещенным в одной статье. Однако мы объясним достаточно элементов, чтобы вы могли легко понять те, которые не охвачены.
Объект SpeechSynthesisUtterance
Первый объект, о котором нам нужно узнать — это объект SpeechSynthesisUtterance
. Он представляет высказывание (то есть текст), на котором будет говорить синтезатор. Этот объект довольно гибкий и может быть настроен несколькими способами. Помимо текста, мы можем установить язык, используемый для произнесения текста, скорости и даже высоты тона. Ниже приведен список его свойств:
-
text
— строка, которая определяет высказывание (текст), который будет синтезирован. -
lang
— строка, представляющая язык синтеза речи для высказывания (например, «en-GB» или «it-IT»). -
voiceURI
— Строка, которая задает голос синтеза речи и местоположение службы синтеза речи, которую веб-приложение желает использовать. -
volume
— число, представляющее объем для текста. Он варьируется от 0 (минимум) до 1 (максимум) включительно, и значение по умолчанию равно 1. -
rate
— число, представляющее скорость речи для высказывания. Это относительно скорости по умолчанию для голоса. Значение по умолчанию равно 1. Значение 2 означает, что произнесение будет произнесено с удвоенной скоростью по умолчанию. Значения ниже 0,1 или выше 10 не допускаются. -
pitch
— число, представляющее высоту речи для высказывания. Он варьируется от 0 (минимум) до 2 (максимум) включительно. Значением по умолчанию является 1.
Чтобы создать экземпляр этого объекта, мы можем либо передать текст для синтеза в качестве аргумента конструктора, либо опустить текст и установить его позже. Следующий код является примером первого сценария.
Второй случай, который создает SpeechSynthesisUtterance
и затем назначает параметры, показан ниже.
Некоторые методы, предоставляемые этим объектом:
-
onstart
- устанавливает обратный вызов, который запускается при запуске синтеза. -
onpause
- Устанавливает обратный вызов, который запускается, когда синтез речи приостановлен. -
onresume
- устанавливает обратный вызов, который запускается при возобновлении синтеза. -
onend
- Устанавливает обратный вызов, который запускается при завершении синтеза.
Объект SpeechSynthesisUtterance
позволяет нам задавать произносимый текст, а также настраивать способ его произнесения. На данный момент мы создали только объект, представляющий высказывание. Нам все еще нужно привязать его к синтезатору.
Объект SpeechSynthesis
Объект SpeechSynthesis
не нуждается в SpeechSynthesis
экземпляра. Он принадлежит объекту window
и может использоваться напрямую. Этот объект предоставляет несколько методов, таких как:
-
speak()
- принимает объектSpeechSynthesisUtterance
качестве единственного параметра. Этот метод используется для синтеза высказывания. -
stop()
- немедленно прекращает процесс синтеза. -
pause()
-pause()
процесс синтеза. -
resume()
- Возобновляет процесс синтеза.
Другой интересный метод - getVoices()
. Он не принимает никаких аргументов и используется для получения списка (массива) голосов, доступных для конкретного браузера. Каждая запись в списке содержит такую информацию, как name
, мнемоническое имя, чтобы дать разработчикам подсказку о голосе (например, «Google US English»), lang
, язык голоса (например, it-IT) и voiceURI
, местоположение службы синтеза речи для этого голоса.
Важное примечание : в Chrome и Safari свойство voiceURI
называется voice
. Итак, демо, которое мы voiceURI
в этой статье, использует voiceURI
вместо voiceURI
.
Совместимость браузера
К сожалению, на момент написания статьи единственными браузерами, которые поддерживают API для синтеза речи, являются Chrome 33 с полной поддержкой и Safari для iOS 7 с частичной поддержкой.
демонстрация
В этом разделе представлена простая демонстрация API синтеза речи. Эта страница позволяет вам вводить текст и синтезировать его. Кроме того, можно установить скорость, высоту звука и язык, который вы хотите использовать. Вы также можете в любой момент остановить, приостановить или возобновить синтез текста, используя соответствующие кнопки.
Прежде чем присоединять слушателя к кнопкам, поскольку поддержка этого API очень ограничена, мы выполняем тест для реализации. Как обычно, тест очень прост и состоит из следующего кода:
if (window.SpeechSynthesisUtterance === undefined) { // Not supported } else { // Read my text }
Если тест не пройден, мы показываем пользователю сообщение «API не поддерживается». Как только поддержка подтверждена, мы динамически загружаем голоса, доступные в специальном окне выбора, помещенном в разметку. Обратите внимание, что метод getVoices()
в Chrome имеет проблему ( # 340160 ). Поэтому я создал обходной путь для этого с помощью setInterval()
. Затем мы прикрепляем обработчик для каждой кнопки, чтобы они могли вызывать свое конкретное действие (воспроизведение, остановка и т. Д.).
Демонстрационная версия кода доступна здесь . Кроме того, эта демонстрация вместе со всеми другими, которые я создал до сих пор, доступна в моем демо- хранилище HTML5 API .
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Speech Synthesis API Demo</title> <style> * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } body { max-width: 500px; margin: 2em auto; padding: 0 0.5em; font-size: 20px; } h1, .buttons-wrapper { text-align: center; } .hidden { display: none; } #text, #log { display: block; width: 100%; height: 5em; overflow-y: scroll; border: 1px solid #333333; line-height: 1.3em; } .field-wrapper { margin-top: 0.2em; } .button-demo { padding: 0.5em; display: inline-block; margin: 1em auto; } </style> </head> <body> <h1>Speech Synthesis API</h1> <h3>Play area</h3> <form action="" method="get"> <label for="text">Text:</label> <textarea id="text"></textarea> <div class="field-wrapper"> <label for="voice">Voice:</label> <select id="voice"></select> </div> <div class="field-wrapper"> <label for="rate">Rate (0.1 - 10):</label> <input type="number" id="rate" min="0.1" max="10" value="1" step="any" /> </div> <div class="field-wrapper"> <label for="pitch">Pitch (0.1 - 2):</label> <input type="number" id="pitch" min="0.1" max="2" value="1" step="any" /> </div> <div class="buttons-wrapper"> <button id="button-speak-ss" class="button-demo">Speak</button> <button id="button-stop-ss" class="button-demo">Stop</button> <button id="button-pause-ss" class="button-demo">Pause</button> <button id="button-resume-ss" class="button-demo">Resume</button> </div> </form> <span id="ss-unsupported" class="hidden">API not supported</span> <h3>Log</h3> <div id="log"></div> <button id="clear-all" class="button-demo">Clear all</button> <script> // Test browser support if (window.SpeechSynthesisUtterance === undefined) { document.getElementById('ss-unsupported').classList.remove('hidden'); ['button-speak-ss', 'button-stop-ss', 'button-pause-ss', 'button-resume-ss'].forEach(function(elementId) { document.getElementById(elementId).setAttribute('disabled', 'disabled'); }); } else { var text = document.getElementById('text'); var voices = document.getElementById('voice'); var rate = document.getElementById('rate'); var pitch = document.getElementById('pitch'); var log = document.getElementById('log'); // Workaround for a Chrome issue (#340160 - https://code.google.com/p/chromium/issues/detail?id=340160) var watch = setInterval(function() { // Load all voices available var voicesAvailable = speechSynthesis.getVoices(); if (voicesAvailable.length !== 0) { for(var i = 0; i < voicesAvailable.length; i++) { voices.innerHTML += '<option value="' + voicesAvailable[i].lang + '"' + 'data-voice-uri="' + voicesAvailable[i].voiceURI + '">' + voicesAvailable[i].name + (voicesAvailable[i].default ? ' (default)' : '') + '</option>'; } clearInterval(watch); } }, 1); document.getElementById('button-speak-ss').addEventListener('click', function(event) { event.preventDefault(); var selectedVoice = voices.options[voices.selectedIndex]; // Create the utterance object setting the chosen parameters var utterance = new SpeechSynthesisUtterance(); utterance.text = text.value; utterance.voice = selectedVoice.getAttribute('data-voice-uri'); utterance.lang = selectedVoice.value; utterance.rate = rate.value; utterance.pitch = pitch.value; utterance.onstart = function() { log.innerHTML = 'Speaker started' + '<br />' + log.innerHTML; }; utterance.onend = function() { log.innerHTML = 'Speaker finished' + '<br />' + log.innerHTML; }; window.speechSynthesis.speak(utterance); }); document.getElementById('button-stop-ss').addEventListener('click', function(event) { event.preventDefault(); window.speechSynthesis.cancel(); log.innerHTML = 'Speaker stopped' + '<br />' + log.innerHTML; }); document.getElementById('button-pause-ss').addEventListener('click', function(event) { event.preventDefault(); window.speechSynthesis.pause(); log.innerHTML = 'Speaker paused' + '<br />' + log.innerHTML; }); document.getElementById('button-resume-ss').addEventListener('click', function(event) { event.preventDefault(); if (window.speechSynthesis.paused === true) { window.speechSynthesis.resume(); log.innerHTML = 'Speaker resumed' + '<br />' + log.innerHTML; } else { log.innerHTML = 'Unable to resume. Speaker is not paused.' + '<br />' + log.innerHTML; } }); document.getElementById('clear-all').addEventListener('click', function() { log.textContent = ''; }); } </script> </body> </html>
Вывод
В этой статье мы рассмотрели API синтеза речи. Это API для синтеза текста и улучшения общего опыта пользователей наших веб-сайтов, особенно с нарушениями зрения. Как мы уже видели, этот API предоставляет несколько объектов, методов и свойств, но его не очень сложно использовать. К сожалению, в настоящее время его поддержка браузера очень слабая, и Chrome и Safari являются единственными браузерами, которые поддерживают его.
Надеемся, что за этим последует больше браузеров, что позволит вам реально рассмотреть возможность его использования на вашем сайте. Я решил Не забудьте поиграть с демоверсией и оставить комментарий, если статья вам понравилась. Я бы очень хотел услышать ваше мнение.