Уявіть: користувач натискає кнопку мікрофона, говорить запит, але транскрипція з'являється через 10 секунд після завершення мовлення. Або застосунок запитує дозвіл на мікрофон — і мовчить, тому що розробник забув перевірити authorizationStatus. Це типові помилки інтеграції голосового пошуку, які ми виправляємо в кожному другому проєкті. За 5+ років ми реалізували 50+ проєктів з голосовим введенням — від e-commerce до медичних довідників. Голосовий пошук прискорює введення запиту в 3 рази та підвищує конверсію пошуку на 20%, але тільки якщо реалізація коректна.
У цій статті на конкретних прикладах розберемо, як правильно інтегрувати Speech API на iOS (Swift), Android (Kotlin) та Flutter, які рішення працюють стабільно, а які ведуть до втрати користувачів. Ми використовуємо потокове розпізнавання з частковими результатами — це дає миттєвий зворотний зв'язок.
Де найчастіше ламається реалізація
iOS: неправильна робота з SFSpeechRecognizer
Найпоширеніша помилка — запуск SFSpeechRecognitionTask без перевірки прав. Користувач натискає кнопку, а застосунок мовчить. Друга проблема — використання файлового запиту SFSpeechURLRecognitionRequest замість потокового SFSpeechAudioBufferRecognitionRequest. У результаті користувач говорить, але транскрипція з'являється лише після зупинки запису.
Правильний підхід: використовувати AVAudioEngine з SFSpeechAudioBufferRecognitionRequest і ввімкнути shouldReportPartialResults = true. Це дає часткові результати по мірі мовлення — як у системній Siri.
let request = SFSpeechAudioBufferRecognitionRequest()
request.shouldReportPartialResults = true
recognitionTask = speechRecognizer.recognitionTask(with: request) { result, error in
guard let result else { return }
self.searchBar.text = result.bestTranscription.formattedString
if result.isFinal {
self.submitSearch(query: result.bestTranscription.formattedString)
}
}
let inputNode = audioEngine.inputNode
let format = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: format) { buffer, _ in
request.append(buffer)
}
audioEngine.prepare()
try audioEngine.start()
Документація Apple Speech Framework
Android: вибір між SpeechRecognizer та RecognizerIntent
RecognizerIntent запускає системний діалог — швидко, але виглядає чужорідним і не завжди підтримує EXTRA_PARTIAL_RESULTS. SpeechRecognizer дає повний контроль, але вимагає акуратного управління життєвим циклом: виклик destroy() у onDestroy() обов'язковий. Реалізація SpeechRecognitionListener через інтерфейс RecognitionListener дає доступ до часткових результатів.
Для inline-інтеграції використовуємо SpeechRecognizer з Intent, що містить EXTRA_PARTIAL_RESULTS = true та мовну модель.
val recognizer = SpeechRecognizer.createSpeechRecognizer(context)
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).apply {
putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM)
putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true)
putExtra(RecognizerIntent.EXTRA_LANGUAGE, "ru-RU")
}
recognizer.setRecognitionListener(object : RecognitionListener {
override fun onPartialResults(partialResults: Bundle) {
val partial = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
searchInput.setText(partial?.firstOrNull() ?: "")
}
override fun onResults(results: Bundle) {
val text = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)?.firstOrNull()
text?.let { submitSearch(it) }
}
// ... інші колбэки
})
recognizer.startListening(intent)
Flutter: speech_to_text vs Platform Channels
Пакет speech_to_text покриває 90% задач. Основна проблема — багатомовність: localeId потрібно передавати явно, інакше Android використовує системну мову. Також пакет не дає доступу до аудіопотоку, що обмежує кастомізацію.
Порівняння підходів розпізнавання мовлення
| Критерій | Нативний API (iOS/Android) | Хмарний ASR (Google, Whisper) |
|---|---|---|
| Точність на простій лексиці | 80% | 95%+ |
| Точність на складній термінології | 60% | 95%+ |
| Робота без інтернету | Так | Ні |
| Часткові результати | Так (майже миттєво) | Так (із затримкою через мережу) |
| Вартість | Безкоштовно | Запитна оплата (~$0.006 за 15 сек) |
На iOS SFSpeechRecognizer інтегрується нативно, працює офлайн і підтримує часткові результати. Його точність у тихій обстановці досягає 80%, але падає при шумі. На Android SpeechRecognizer дає повний контроль і теж працює офлайн, однак вимагає ручного управління життєвим циклом і більш чутливий до сумісності пристроїв. RecognizerIntent простіший, але його системний діалог виглядає чужорідним і не підтримує часткові результати на всіх пристроях. Для кроссплатформенних проєктів пакет speech_to_text зручний, але його гнучкість обмежена.
Якщо потрібна висока точність на специфічній термінології (медицина, юриспруденція), нативний API не справляється — точність падає до 60%. У таких випадках хмарний ASR, наприклад Google Cloud Speech-to-Text, з донавченими моделями підвищує точність до 95%+. Хмарний ASR точніший за нативний в 1,5 раза на складній лексиці.
Як ми це робимо на практиці
Одного разу ми робили голосовий пошук для медичного довідника. Потрібно було розпізнавати складні терміни: «лапароскопія», «гастроскопія». Нативний Speech API давав точність близько 60%. Ми підключили Google Cloud Speech-to-Text з кастомними SpeechContext і навчили модель на словнику з 5000 термінів. Точність зросла до 95%. Час пошуку скоротився втричі — користувачі оцінили. Економія часу обробки запиту становила 40% порівняно з базовою інтеграцією, а витрати на інфраструктуру ASR окупилися за 3 місяці.
Для більшості застосунків нативного API достатньо. Якщо потрібна висока точність на специфічній лексиці або робота в шумному середовищі — підключаємо хмарний ASR. Анімація рівня звуку під час запису не декоративна: на iOS використовуємо AVAudioRecorder.averagePower, на Android — MediaRecorder.getMaxAmplitude. Це дає користувачеві відчуття, що мікрофон працює.
Чому важливо правильно обробляти часткові результати?
Часткові результати — ключ до гарного UX. Без них користувач мовчить у порожнечу, не знаючи, чи чує його застосунок. На iOS прапор shouldReportPartialResults = true вирішує проблему. На Android — EXTRA_PARTIAL_RESULTS. Ми завжди вмикаємо їх у проєктах — це підвищує конверсію пошуку на 20% і знижує відсоток незавершених запитів у 1,5 раза.
Коли варто підключити хмарний ASR замість нативного API?
Хмарний ASR (Google, Whisper) потрібен, коли точність нативного API падає нижче 70%: це відбувається при складній термінології, шумному середовищі або мультимовності. Ми використовуємо його в медичних, юридичних та технічних застосунках. Вартість одного запиту мінімальна, а результат — 95%+ точності. Час інтеграції збільшується на 3-5 днів, але окупається за рахунок якості.
Приклад складної інтеграції: офлайн-розпізнавання на пристрої
Для застосунків без інтернету використовуємо локальні моделі (наприклад, Vosk або PicoVoice). Інтеграція займає 2-3 тижні, точність — до 85% на простій лексиці. Потребує оптимізації розміру моделі та управління пам'яттю.Що входить в роботу
- Документація з інтеграції Speech API (з прикладами коду)
- Вихідний код модуля голосового введення для цільових платформ
- Налаштування часткових результатів та нормалізації запиту
- Анімація мікрофона з індикацією рівня гучності
- Інтеграція з пошуковим бекендом
- Тестування на 10+ реальних пристроях з різними акцентами
- 1 місяць гарантії та підтримки після деплою
Процес роботи
- Аналіз — визначаємо мови, тип контенту (команди або вільне мовлення), чи потрібен offline.
- Розробка — запит дозволів, інтеграція Speech API, обробка часткових результатів, анімація мікрофона.
- Нормалізація — перетворюємо текст у пошуковий запит, прибираємо шум.
- Тестування — перевіряємо на iOS (різні моделі) та Android (версії 6+), виправляємо баги.
- Деплой — публікуємо в App Store та Google Play, моніторимо відгуки.
Орієнтири за термінами
| Етап | Тривалість |
|---|---|
| Базова інтеграція нативного API | 2–3 дні |
| Багатомовність + хмарний ASR | 1–1,5 тижня |
| Offline-режим через локальну модель | 2–3 тижні |
Чек-лист для успішної інтеграції
- [ ] Перевірити права на мікрофон та speech recognition
- [ ] Вибрати відповідний API (нативний/хмарний)
- [ ] Увімкнути часткові результати на всіх платформах
- [ ] Реалізувати нормалізацію запиту
- [ ] Протестувати на 10+ пристроях з різними акцентами
- [ ] Налаштувати анімацію рівня звуку
Отримайте консультацію щодо вашого проєкту — оцінимо задачу за 1 день безкоштовно. Замовте реалізацію голосового пошуку під ключ — наші інженери з 5+ річним досвідом гарантують результат. Зв'яжіться з нами для безкоштовної оцінки вашого проєкту.







