Статьи

Создайте голосовой аудиоплеер с API веб-речи

Эта статья была рецензирована Эдвином Рейносо и Марком Брауном . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

Web Speech API — это JavaScript API, который позволяет веб-разработчикам интегрировать распознавание и синтез речи в свои веб-страницы.

Есть много причин для этого. Например, для улучшения восприятия людьми с ограниченными возможностями (особенно пользователями с проблемами зрения или пользователями с ограниченной способностью двигать руками) или чтобы позволить пользователям взаимодействовать с веб-приложением при выполнении другой задачи (например, вождения).

Если вы никогда не слышали об API Web Speech или хотели бы быстро освоиться, тогда было бы неплохо прочитать статьи Аурелио Де Росы « Знакомство с Web Speech API» , « Speech Sythesis API» и « Talking Form» .

Поддержка браузера

Поставщики браузеров только недавно начали реализовывать API распознавания речи и API синтеза речи . Как видите, их поддержка еще далека от совершенства, поэтому, если вы следуете этому учебнику, используйте соответствующий браузер.

Кроме того, API распознавания речи в настоящее время требует подключения к Интернету, поскольку речь передается по проводам, а результаты возвращаются в браузер. Если соединение использует HTTP, пользователь должен разрешить сайту использовать свой микрофон при каждом запросе. Если соединение использует HTTPS, то это необходимо только один раз.

Библиотеки распознавания речи

Библиотеки могут помочь нам справиться со сложностью и обеспечить совместимость. Например, когда другой браузер начинает поддерживать API распознавания речи, нам не нужно беспокоиться о добавлении префиксов поставщиков.

Одна из таких библиотек — Annyang , с которой невероятно легко работать. Расскажи мне больше

Чтобы инициализировать Annyang, мы добавляем их скрипт на наш сайт:

<script src="//cdnjs.cloudflare.com/ajax/libs/annyang/1.6.0/annyang.min.js"></script> 

Мы можем проверить, поддерживается ли API следующим образом:

 if (annyang) { /*logic */ } 

И добавьте команды, используя объект с именами команд в качестве ключей и обратными вызовами в качестве методов. :

 var commands = { 'show divs': function() { $('div').show(); }, 'show forms': function() { $("form").show(); } }; 

Наконец, мы просто добавляем их и запускаем распознавание речи, используя:

 annyang.addCommands(commands); annyang.start(); 

Аудио плеер с голосовым управлением

В этой статье мы будем создавать голосовой аудиоплеер. Мы будем использовать как API-интерфейс синтезатора речи (для информирования пользователей о том, какая песня начинается или что команда не была распознана), так и API-интерфейс распознавания речи (для преобразования голосовых команд в строки, которые будут вызывать различную логику приложения).

Самое замечательное в аудиоплеере, использующем Web Speech API, заключается в том, что пользователи смогут просматривать другие страницы в своем браузере или свернуть браузер и делать что-то еще, но при этом могут переключаться между песнями. Если у нас в списке воспроизведения много песен, мы можем даже запросить конкретную песню, не ища ее вручную (если мы знаем ее название или исполнителя, конечно).

Мы не будем полагаться на стороннюю библиотеку для распознавания речи, поскольку хотим показать, как работать с API без добавления дополнительных зависимостей в наши проекты. Управляемый голосом аудиоплеер будет поддерживать только те браузеры, которые поддерживают атрибут interimResults . Последняя версия Chrome должна быть безопасной ставкой.

Как всегда, вы можете найти полный код на GitHub и демонстрацию на CodePen .

Начало работы — плейлист

Давайте начнем со статического списка воспроизведения. Он состоит из объекта с различными песнями в массиве. Каждая песня — это новый объект, содержащий путь к файлу, имя певца и название песни:

 var data = { "songs": [ { "fileName": "https://www.ruse-problem.org/songs/RunningWaters.mp3", "singer" : "Jason Shaw", "songName" : "Running Waters" }, ... 

Мы должны иметь возможность добавлять новые объекты в массив songs и автоматически включать новую песню в наш аудиоплеер.

Аудио плеер

Теперь мы подходим к самому игроку. Это будет объект, содержащий следующие вещи:

  • некоторые данные настройки
  • методы, относящиеся к пользовательскому интерфейсу (например, заполнение списка песен)
  • методы, относящиеся к Speech API (например, распознавание и обработка команд)
  • методы, относящиеся к манипулированию аудио (например, воспроизведение, пауза, остановка, предыдущая, следующая)

Данные настройки

Это относительно просто.

 var audioPlayer = { audioData: { currentSong: -1, songs: [] }, 

Свойство currentSong ссылается на индекс песни, в которой находится пользователь. Это полезно, например, когда нам нужно воспроизвести следующую / предыдущую песню или остановить / приостановить песню.

Массив songs содержит все песни, которые пользователь прослушал. Это означает, что в следующий раз, когда пользователь прослушает ту же песню, мы можем загрузить ее из массива и не загружать ее.

Вы можете увидеть полный код здесь .

Методы пользовательского интерфейса

Пользовательский интерфейс будет состоять из списка доступных команд, списка доступных дорожек и контекстного окна для информирования пользователя как о текущей операции, так и о предыдущей команде. Я не буду вдаваться в подробности методов пользовательского интерфейса, а предложу краткий обзор. Вы можете найти код для этих методов здесь .

нагрузка

Это перебирает наш ранее объявленный плейлист и добавляет название песни, а также имя исполнителя в список доступных треков.

changeCurrentSongEffect

Это указывает на то, какая песня воспроизводится в данный момент (пометив ее зеленым и добавив рядом наушники), а также те, которые закончили воспроизведение.

Играть песню

Это указывает пользователю, что песня воспроизводится или когда она закончилась. Это делается с помощью метода changeStatusCode , который добавляет эту информацию в поле и информирует пользователя об этом изменении через Speech API.

changeStatusCode

Как упомянуто выше, это обновляет сообщение о состоянии в контекстном окне (например, чтобы указать, что воспроизводится новая песня) и использует метод speak чтобы объявить об этом изменении пользователю.

changeLastCommand

Маленький помощник, который обновляет последний командный блок.

toggleSpinner

Небольшой помощник, чтобы скрыть или показать значок счетчика (который указывает пользователю, что его голосовая команда в настоящее время обрабатывает).

Методы игрока

Игрок будет нести ответственность за то, что вы можете ожидать, а именно: запуск, остановка и приостановка воспроизведения, а также перемещение вперед и назад по дорожкам. Опять же, я не хочу вдаваться в подробности методов, а скорее покажу вам направление нашего репозитория GitHub .

Играть в

Это проверяет, слушал ли пользователь песню еще. Если нет, он запускает песню, в противном случае он просто вызывает метод playSong который мы обсуждали ранее для текущей кэшированной песни. Он находится в audioData.songs и соответствует индексу currentSong .

pauseSong

Это приостанавливает или полностью останавливает (возвращает время воспроизведения в начало песни) песню в зависимости от того, что передано в качестве второго параметра. Он также обновляет код состояния, чтобы уведомить пользователя о том, что песня была остановлена ​​или приостановлена.

стоп

Это либо приостанавливает, либо останавливает песню на основе ее первого и единственного параметра:

предыдущая

Это проверяет, кэширована ли предыдущая песня, и если да, она приостанавливает текущую песню, уменьшает значение currentSong и снова воспроизводит текущую песню. Если новая песня отсутствует в массиве, она делает то же самое, но сначала загружает песню из имени файла / пути, соответствующего уменьшенному индексу currentSong .

следующий

Если пользователь прослушал песню раньше, этот метод пытается приостановить ее. Если в нашем объекте data (т.е. в нашем списке воспроизведения) есть следующая песня, она загружает ее и воспроизводит. Если следующей песни нет, он просто меняет код состояния и сообщает пользователю, что он достиг последней песни.

searchSpecificSong

Это принимает ключевое слово в качестве аргумента и выполняет линейный поиск по названиям песен и исполнителям, прежде чем воспроизводить первое совпадение.

Методы API речи

Speech API удивительно прост в реализации. На самом деле, для того, чтобы веб-приложение могло общаться с пользователями, требуется всего две строки кода:

 var utterance = new SpeechSynthesisUtterance('Hello'); window.speechSynthesis.speak(utterance); 

Здесь мы создаем объект utterance который содержит текст, который мы хотим произнести. Интерфейс speechSynthesis (который доступен в объекте окна) отвечает за обработку этого объекта utterance и управление воспроизведением результирующей речи.

Попробуйте и попробуйте это в вашем браузере. Это так просто!

разговаривать

Мы можем увидеть это в действии в нашем методе talk, который читает вслух сообщение, переданное в качестве аргумента:

 speak: function(text, scope) { var message = new SpeechSynthesisUtterance(text.replace("-", " ")); message.rate = 1; window.speechSynthesis.speak(message); if (scope) { message.onend = function() { scope.play(); } } } 

Если есть второй аргумент ( scope ), мы вызываем метод play для scope (который будет объектом Audio) после завершения воспроизведения сообщения.

processCommands

Этот метод не так увлекателен. Он получает команду в качестве параметра и вызывает соответствующий метод для ответа на нее. Он проверяет, хочет ли пользователь воспроизвести определенную песню с регулярным выражением, в противном случае он вводит оператор switch для проверки различных команд. Если ни один из них не соответствует полученной команде, он информирует пользователя о том, что команда не была понята.

Вы можете найти код для этого здесь .

Связывая вещи вместе

К настоящему времени у нас есть объект data представляющий наш список воспроизведения, а также объект audioPlayer представляющий самого проигрывателя. Теперь нам нужно написать код для распознавания и обработки пользовательского ввода. Обратите внимание, что это будет работать только в браузерах webkit.

Код для общения пользователей с вашим приложением такой же простой, как и раньше:

 var recognition = new webkitSpeechRecognition(); recognition.onresult = function(event) { console.log(event) } recognition.start(); 

Это предложит пользователю разрешить странице доступ к своему микрофону. Если вы разрешите доступ, вы можете начать говорить, и когда вы остановите событие onresult вы получите доступ к результатам захвата речи в виде объекта JavaScript.

Справка: API распознавания речи в HTML5

Мы можем реализовать это в нашем приложении следующим образом:

 if (window['webkitSpeechRecognition']) { var speechRecognizer = new webkitSpeechRecognition(); // Recognition will not end when user stops speaking speechRecognizer.continuous = true; // Process the request while the user is speaking speechRecognizer.interimResults = true; // Account for accent speechRecognizer.lang = "en-US"; speechRecognizer.onresult = function (evt) { ... } speechRecognizer.onend = function () { ... } speechRecognizer.start(); } else { alert("Your browser does not support the Web Speech API"); } 

Как видите, мы проверяем наличие webkitSpeechRecognition в объекте window . Если это так, то мы можем пойти дальше, в противном случае мы сообщаем пользователю, что браузер его не поддерживает. Если все хорошо, тогда мы устанавливаем несколько вариантов. Из этих lang есть интересный, который может улучшить результаты распознавания, исходя из того, откуда вы родом.

Затем мы объявляем обработчики для onresult и onend событий перед тем, как начать с метода start.

Обработка результата

Есть несколько вещей, которые мы хотим сделать, когда распознаватель речи получает результат, по крайней мере, в контексте текущей реализации распознавания речи и наших потребностей. Каждый раз, когда есть результат, мы хотим сохранить его в массиве и установить тайм-аут на ожидание в течение трех секунд, чтобы браузер мог собирать любые дальнейшие результаты. После истечения трех секунд мы хотим использовать собранные результаты и перебрать их в обратном порядке (более новые результаты имеют больше шансов быть точными) и проверить, содержит ли распознанная расшифровка одну из наших доступных команд. Если это так, мы выполняем команду и перезапускаем распознавание речи. Мы делаем это потому, что ожидание окончательного результата может занять до минуты, из-за чего наш аудиоплеер кажется совершенно не отвечающим и бессмысленным, так как было бы быстрее просто нажать на кнопку.

 speechRecognizer.onresult = function (evt) { audioPlayer.toggleSpinner(true); results.push(evt.results); if (!timeoutSet) { setTimeout(function() { timeoutSet = false; results.reverse(); try { results.forEach(function (val, i) { var el = val[0][0].transcript.toLowerCase(); if (currentCommands.indexOf(el.split(" ")[0]) !== -1) { speechRecognizer.abort(); audioPlayer.processCommands(el); audioPlayer.toggleSpinner(); results = []; throw new BreakLoopException; } if (i === 0) { audioPlayer.processCommands(el); speechRecognizer.abort(); audioPlayer.toggleSpinner(); results = []; } }); } catch(e) {return e;} }, 3000) } timeoutSet = true; } 

Поскольку мы не используем библиотеку, мы должны написать больше кода для настройки нашего распознавателя речи, просматривая каждый результат и проверяя, соответствует ли его транскрипт заданному ключевому слову.

Наконец, мы возобновляем распознавание речи, как только оно заканчивается:

 speechRecognizer.onend = function () { speechRecognizer.start(); } 

Вы можете увидеть полный код этого раздела здесь .

Вот и все. Теперь у нас есть аудиоплеер, который полностью функционален и управляется голосом Я призываю загрузить код с Github и поиграть с ним, или ознакомьтесь с демонстрацией CodePen . Я также сделал доступной версию, которая обслуживается через HTTPS .

Вывод

Надеюсь, что это практическое руководство послужило хорошим введением в то, что возможно с помощью Web Speech API. Я думаю, что мы увидим рост использования этого API, так как реализации стабилизируются и добавляются новые функции. Например, я вижу YouTube будущего с полностью голосовым управлением, где мы можем смотреть видео разных пользователей, воспроизводить конкретные песни и перемещаться между песнями только с помощью голосовых команд.

Есть также много других областей, в которых API веб-речи может принести улучшения или открыть новые возможности. Например, просмотр электронной почты, навигация по веб-сайтам или поиск в Интернете — все с вашим голосом.

Используете ли вы этот API в своих проектах? Я хотел бы услышать от вас в комментариях ниже.