Реализация распознавания речи (Speech-to-Text) в мобильном приложении
Speech-to-Text на мобиле делится на два сценария: онлайн с облаком (лучше качество, нужен интернет) и on-device (работает офлайн, достаточно для большинства продакшн-задач). Выбор определяет не только архитектуру, но и стоимость эксплуатации.
Нативные API: SFSpeechRecognizer и Android STT
iOS SFSpeechRecognizer — встроенный в iOS API, работает начиная с iOS 10. С iOS 13+ поддерживает on-device-режим (requiresOnDeviceRecognition = true) для 11 языков. Для русского — только облачный режим (запросы идут на серверы Apple). Ограничение: 1 минута на запрос, ~1000 запросов в день на устройство без платного соглашения.
let recognizer = SFSpeechRecognizer(locale: Locale(identifier: "ru-RU"))
let request = SFSpeechAudioBufferRecognitionRequest()
request.requiresOnDeviceRecognition = false // для русского — облако
request.shouldReportPartialResults = true
shouldReportPartialResults = true критичен для UX: пользователь видит текст по мере говорения, а не ждёт конца записи.
Android SpeechRecognizer — использует Google Speech Services. Offline-режим доступен через RecognizerIntent.EXTRA_PREFER_OFFLINE = true, но языковые пакеты нужно скачивать отдельно, и они занимают 80–200 MB. Для русского офлайн-пакет доступен, но у пользователя он может не быть установлен — нужна проверка и fallback.
Облачные альтернативы
Когда нативных API недостаточно (кастомный словарь, специализированная терминология, высокая точность):
- OpenAI Whisper — лучшая точность из доступных, multilingual. API — просто POST с аудиофайлом. Latency 1–3 секунды на серверной стороне. Есть мобильная версия Whisper.cpp, компилируется через CMake — работает on-device, ~50–200 MB в зависимости от размера модели.
-
Google Cloud Speech-to-Text v2 — поддерживает streaming через gRPC WebSocket, адаптация под кастомный словарь через
AdaptationAPI. - Яндекс SpeechKit — оптимален для русского языка, streaming через WebSocket.
Streaming vs batch
Batch (запись → стоп → распознавание) проще в реализации, но UX хуже. Streaming — текст появляется по мере говорения.
Streaming на iOS через SFSpeechAudioBufferRecognitionRequest с append(buffer:) из AVAudioEngine:
inputNode.installTap(onBus: 0, bufferSize: 1024, format: format) { buffer, _ in
request.append(buffer)
}
Для Яндекс SpeechKit streaming — WebSocket с chunked audio в PCM 16kHz 16bit. Чанки по 200–400 ms — баланс между latency и overhead.
Кейс: приложение для голосового заполнения форм на складе (оператор диктует данные, не отрывая рук). Нативный Android STT с офлайн-пакетом русского языка. Проблема: специфические SKU-коды («артикул 7788-АБВ») распознавались плохо. Решение: Яндекс SpeechKit с кастомным словарём через PhraseSuggestions — добавили 3000 артикулов. Точность на коде товара выросла с 61% до 89%.
Разрешения и UX
На iOS NSMicrophoneUsageDescription и NSSpeechRecognitionUsageDescription обязательны в Info.plist. Запрос разрешений до первого использования — через AVAudioSession.requestRecordPermission и SFSpeechRecognizer.requestAuthorization. Без успешного запроса вызов startRecording() упадёт без информативной ошибки.
Индикатор записи в UI — всегда. Анимированная волна или пульсирующий индикатор дают пользователю понять, что его слушают.
Сроки
Нативный STT (iOS/Android) с UI — 3–5 дней. Streaming с облачным API и кастомным словарём — 1–2 недели. Стоимость рассчитывается индивидуально.







