JS30. Задание 20 Native Speech Recognition


Демо: https://js3020.github.io/
Код: https://github.com/js3020/js3020.github.io

Невероятно интересное задание - распознавание речи. То, что раньше казалось невозможным или осуществимым в далёком будущем, сейчас доступно каждому. Причём средствами самого браузера. Разумеется, если это браузер webkit, то есть Хром и все остальные хромоподобные браузеры. В Firefox распознавание речи не работает.


Распознавание голоса и чтение текста в браузере в 3 строки на JavaScript: демонстрация и примеры кода

SpeechRecognition - экспериментальное JavaScript API для распознавания голоса в браузере mdn
Есть и другое API под названием speechSynthesis, которое позволяет озвучивать человеческим голосом любой текст

С точки зрения клиента схема работы Speech Recognition довольно проста — это «черная коробка», которая автоматически обрабатывает произнесенные слова и на выходе дает обычную строку, с которой вы сможете работать в дальнейшем:

// Создаем распознаватель
// На данный момент функция работает только с префиксом webkit

var recognizer = new webkitSpeechRecognition();

// Ставим опцию, чтобы распознавание происходило непрерывно ещё до того, как пользователь закончит говорить и возвращало промежуточные результаты
// По умолчанию свойство возвращает только один результат 

recognizer.interimResults = true;

// Какой язык будем распознавать?
// Если свойство не указано, язык берётся из HTML кода значение атрибута lang , или настройки языка агента текущего пользователя.

recognizer.lang = 'ru-Ru';

// Используем колбек для обработки результатов

recognizer.onresult = function (event) {
  var result = event.results[event.resultIndex];
  if (result.isFinal) {
    alert('Вы сказали: ' + result[0].transcript);
  } else {
    console.log('Промежуточный результат: ', result[0].transcript);
  }
};


// Начинаем слушать микрофон и распознавать голос

recognizer.start();

Ещё проще написать код для озвучивания текста

speechSynthesis.speak(
  new SpeechSynthesisUtterance("Здесь текст")
);


источник

1. Первая строка кода

window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;

Нам нужно получить доступ SpeechRecognitionв к окну браузера. Chrome требует webkit префикса, поэтому пишем оба варианта:
2. Далее мы создадим новый экземпляр распознавания речи.

var rec = new SpeechRecognition();
rec.interimResults = true;


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

3. Основная часть сделана.
Теперь нам нужно вывести полученный текст на экран.

var words = document.querySelector(".words");
var p = document.createElement("p");
words.appendChild(p);


rec.addEventListener("result", function(e) {
    var text = Array.from(e.results)
    .map(result => result[0])
    .map(result => result.transcript)
    .join('');
   
    p.innerHTML = text;
});


Разбираем код построчно:

1) var words = document.querySelector(".words");

получили доступ к полю для ввода текста - words;

2) var p = document.createElement("p");

создали абзац;

3) words.appendChild(p);

добавили этот абзац полю words;

4) rec.addEventListener("result", function(e)

создали слушатель, который реагирует на ввод текста:




5)    var text = Array.from(e.results)
    .map(result => result[0])
    .map(result => result.transcript)
    .join('');


создали переменную, в которую передали результат работы SpeechRecognition;
передаём в неё части текста
распознаём их
и преобразуем в строку

6) p.innerHTML = text;

добавляем этот текст абзацу

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



rec.addEventListener("end", function(e) {
    if (p.innerHTML) {
        p = document.createElement("p");
        words.appendChild(p);
    }


5. Добавим две кнопки. Одна из них будет запускать распознавание речи, вторая - очищать поле ввода

var start = document.getElementById("start");
var clear = document.getElementById("clear");

start.addEventListener("click", function() {
    rec.start();
    this.disabled = true;
    this.innerHTML = "LISTENING...";
});

clear.addEventListener("click", function() {
    words.innerHTML = "";
    p = document.createElement("p");
    words.appendChild(p);
});


Код полностью:

window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;

var words = document.querySelector(".words");
var start = document.getElementById("start");
var clear = document.getElementById("clear");

var rec = new SpeechRecognition();
rec.interimResults = true;

var p = document.createElement("p");
words.appendChild(p);

start.addEventListener("click", function() {
    rec.start();
    this.disabled = true;
    this.innerHTML = "LISTENING...";
});

clear.addEventListener("click", function() {
    words.innerHTML = "";
    p = document.createElement("p");
    words.appendChild(p);
});

rec.addEventListener("result", function(e) {
    var text = Array.from(e.results)
    .map(result => result[0])
    .map(result => result.transcript)
    .join('');
   
    p.innerHTML = text;
});

rec.addEventListener("end", function(e) {
    if (p.innerHTML) {
        p = document.createElement("p");
        words.appendChild(p);
    }
    rec.start();
});