ФронтендJavaScriptHTML / CSS

Голосовые заметки в браузере на JavaScript: Web Speech API

Создаём голосовые заметки в браузере: запрашиваем микрофон, распознаём речь через Web Speech API, показываем черновик и сохраняем текст.

Кодик

Автор

6 мин чтения

голосовые заметки можно освоить на одном небольшом проекте, если сразу видеть вход, действие и результат. SpeechRecognition получает фразы с микрофона и отдаёт промежуточный и финальный текст, который можно превратить в обычную заметку. Ниже вы соберёте работающий пример и проверите обычный и граничный сценарии.

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

1Соберите минимум

найти SpeechRecognition или webkitSpeechRecognition. Не расширяйте проект до первого успешного запуска.

2Увидьте данные

браузер показывает системный запрос микрофона. Проверяйте значение, а не отсутствие ошибки.

3Измените правило

После успеха добавьте выбор языка ru-RU/en-US и ручное редактирование перед сохранением. Так копирование станет практикой.

Как устроен учебный проект голосовые заметки

Кнопка запускает SpeechRecognition, события result обновляют interim и final transcript, а localStorage хранит только подтверждённые строки. Держите ввод, логику и отображение раздельно: тогда каждый этап можно проверить отдельно.

ЭтапДействиеПроверяемый результат
Поддержканайти SpeechRecognition или webkitSpeechRecognitionнеподдерживаемый браузер получает текстовый fallback
Разрешениезапустить распознавание только после кликабраузер показывает системный запрос микрофона
Результатразделить interim и isFinalчерновик меняется, а финальная фраза фиксируется один раз
Хранениедобавить финальный текст в localStorageперезагрузка возвращает заметки без повторного микрофона

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

Путь данных в проекте голосовые заметки
От входных данных до видимого результата. Сначала проверяется вход, затем действие и только потом интерфейс.

Зафиксируйте первый успех Проверьте поддержку конструктора и запускайте recognition только из явного клика. Автоматический запрос микрофона при загрузке ухудшает доверие и может быть заблокирован. Сохраните команду запуска и ожидаемый вывод.

Собираем рабочий пример шаг за шагом

Пример сверялся с актуальной документацией MDN Web Speech API на 19 октября 2026 года. Создайте HTML, CSS и app.js, запустите их через localhost или HTTPS. Для доступа к микрофону нужен безопасный контекст и разрешение пользователя. Проверьте текущую папку через pwd или Get-Location. Вставьте пример целиком, выполните один раз, затем разбирайте по частям.

const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
const status = document.querySelector('#status')
const draft = document.querySelector('#draft')
const notes = document.querySelector('#notes')

if (!SpeechRecognition) {
  status.textContent = 'Распознавание речи не поддерживается. Используйте текстовое поле.'
} else {
  const recognition = new SpeechRecognition()
  recognition.lang = 'ru-RU'
  recognition.interimResults = true
  recognition.continuous = false

  recognition.addEventListener('result', (event) => {
    let interim = ''
    for (let i = event.resultIndex; i < event.results.length; i++) {
      const text = event.results[i][0].transcript.trim()
      if (event.results[i].isFinal) addNote(text)
      else interim += text + ' '
    }
    draft.textContent = interim
  })

  recognition.addEventListener('error', (event) => {
    status.textContent = 'Не удалось распознать речь: ' + event.error
  })

  document.querySelector('#start').addEventListener('click', () => recognition.start())
  document.querySelector('#stop').addEventListener('click', () => recognition.stop())
}

function addNote(text) {
  if (!text) return
  const item = document.createElement('li')
  item.textContent = text
  notes.append(item)
}
Что должно произойти после запуска
  • Промежуточная фраза обновляет черновик, но ещё не создаёт постоянную заметку.
  • Финальный результат добавляется один раз, а ошибка permission-denied отображается рядом с кнопкой.
  • Повторный запуск даёт тот же предсказуемый результат.
  • Пустой ввод получает понятное сообщение вместо падения.

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

Хрупкий и проверяемый вариант голосовые заметки
Что отличает устойчивый проект от случайного запуска. Явные границы делают ошибку локальной и понятной.

Что происходит внутри и почему это работает

Web Speech API описывает интерфейс распознавания, но реализация зависит от браузера. В некоторых браузерах аудио может отправляться в удалённый сервис, поэтому офлайн-работу и приватность нельзя обещать без проверки конкретной реализации. Логику держите отдельно от вывода: функция получает аргумент и возвращает значение, а интерфейс показывает его. Свойство lang влияет на модель распознавания. Язык интерфейса страницы не заменяет явную настройку ru-RU.

ЧастьЗа что отвечаетЧто проверить
Поддержкавыбирает доступный конструктор или fallbackстраница не падает без API
Событияresult, error и end описывают жизненный циклкнопки и статус отражают реальное состояние
Хранениесохраняет только финальный текстчерновик не дублируется после нескольких result

Не вызывайте start повторно, пока предыдущая сессия не завершилась: браузер может выбросить InvalidStateError. Отключайте кнопку старта на период прослушивания и возвращайте её в событии end. Для длинной диктовки продумайте сегменты и явный индикатор, что микрофон активен. Не прячьте поток в одном обработчике: сохраните вход, проверьте его, вызовите операцию и только затем обновите интерфейс.

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

Проверяем проект и добавляем свою функцию

Добавьте редактируемое поле перед сохранением финальной фразы. Пользователь должен исправить распознавание и подтвердить заметку. До правки запишите ожидаемое поведение одним предложением. После граничного теста повторите обычный сценарий.

Проверка своими руками
  1. Сохраните ожидаемый результат: после разрешения микрофона речь появляется в черновике, финальная фраза добавляется в список, отказ в доступе показывает понятное сообщение.
  2. Измените правило: добавьте выбор языка ru-RU/en-US и ручное редактирование перед сохранением. Сначала предскажите итог.
  3. Передайте граничное значение и убедитесь, что приложение не падает.
  4. Верните корректные данные и объясните роли трёх основных частей.
Готово, если выполняются все пункты
  • неподдерживаемый браузер получает текстовый fallback
  • браузер показывает системный запрос микрофона
  • черновик меняется, а финальная фраза фиксируется один раз
  • перезагрузка возвращает заметки без повторного микрофона

Голосовой ввод полезен как альтернативный путь, но обычное текстовое поле остаётся обязательным fallback. Полезная правка проходит от нового ввода до видимого результата.

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

Что запомнить и куда двигаться дальше

Перед реальным использованием объясните, когда включён микрофон, где обрабатывается аудио и что именно сохраняется. Не храните исходную запись, если продукту нужен только текст. Для закрепления откройте в Telegram-боте голос в текст, в todo list на JavaScript и в PWA с локальным хранением.

Как изучить тему в Кодике

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

ШагЧто разобратьМини-проверка
1. ОсноваКнопки, события, DOM-список и localStorageОбъясните вход и выход функции.
2. ИнструментSpeechRecognition, result, error, isFinal и langПовторите команду по памяти.
3. ПроектЧерновик, подтверждение и текстовый fallbackПроверьте два сценария.
4. РефакторингУправление состояниями и приватностьюРазделите ввод, логику и вывод.

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

Только webkit-префикс

Код пропускает стандартный конструктор. Проверяйте оба варианта.

Сохранение каждого interim

Одна фраза появляется много раз. Сохраняйте только isFinal.

Нет статуса микрофона

Пользователь не понимает, идёт ли запись. Показывайте явное состояние.

Обещание офлайн-приватности

Реализация может использовать сетевой сервис. Документируйте ограничение конкретного браузера.

Сверяйтесь с первичной документацией. Команды и ограничения примера проверены по MDN Web Speech API. Если версия инструмента изменилась, официальный источник важнее старого скриншота.

Что получится в итоге

Готовый результат проекта: Голосовые заметки в браузере на JavaScript: Web Speech API
Так выглядит законченный учебный проект: есть понятный вход, видимый результат, защита от неверных данных и место для следующего улучшения.

Короткие ответы
Зачем различать interim и final?

Interim меняется по мере распознавания, а final считается завершённым сегментом для сохранения.

Работает ли Web Speech одинаково во всех браузерах?

Нет. Поддержка, префиксы, сеть и доступные режимы зависят от реализации.

Что проверять первым, если голосовые заметки не запускается?

Версию среды, текущую папку, команду запуска и первую строку ошибки.

Как понять, что проект голосовые заметки работает?

Проверьте основной сценарий, неверный ввод, повторный запуск и один граничный случай.

Можно ли начать с готового кода?

Да. Добейтесь результата, измените одно правило и восстановите ключевую функцию без копирования.

Сделайте один осознанный шаг дальше

Выберите одно улучшение и проведите его от ввода до результата.

Если не хватает основы, перейдите курс JavaScript, затем восстановите ключевую функцию без подсказки.