Автоматичні субтитри до відео — задача, з якою стикаються розробники додатків для соціальних мереж, освітніх платформ і сервісів відеомонтажу. Користувачі хочуть швидко отримувати точні субтитри, а не вводити їх вручну. Ми реалізуємо генерацію субтитрів на основі Whisper від OpenAI, але не обмежуємося простим викликом API. Потрібно правильно витягти аудіо з відео, синхронізувати таймкоди до мілісекунд, відрендерити субтитри (як overlay, так і вбудовані), а також надати редактор для виправлення помилок розпізнавання. Наш 5-річний досвід у мобільній розробці (30+ проектів) гарантує, що рішення буде працювати стабільно і швидко, а також впишеться у ваш UI/UX. Зниження витрат на транскрипцію та прискорення виходу додатка на ринок — ось результат.
Як вибрати між on-device та API транскрипцією?
Whisper через OpenAI API — найпростіший шлях. Відправляємо аудіо (до 25 MB), отримуємо JSON з segments (таймкоди + текст):
POST https://api.openai.com/v1/audio/transcriptions
model=whisper-1&response_format=verbose_json×tamp_granularities[]=word
verbose_json з word-гранулярністю дає таймкод кожного слова — потрібно для синхронізації субтитрів. Час обробки: ~10-секундний кліп — 2–4 сек, хвилина відео — 10–20 сек.
Whisper on-device — реально для iOS 16+ через WhisperKit (swift-transformers). Модель whisper-small — 244 MB, швидкість ~0.3× реального часу на iPhone 14 (тобто хвилина аудіо = 3 хвилини обробки). whisper-tiny — 77 MB, 0.7× реального часу, але точність помітно гірша. Для російської мови — гірше, ніж для англійської.
На Android: whisper.cpp через JNI, або openai-whisper-tflite — але це складніше в збірці. Простіше для більшості додатків — API.
| Параметр | Whisper API | Whisper on-device |
|---|---|---|
| Швидкість | ~5-15 сек/хв відео | ~0.3-0.7× реального часу |
| Точність | Висока (особливо en) | Середня (нижча для ru) |
| Інтернет | Потрібен | Не потрібен |
| Приватність | Аудіо йде на сервер | Повна локальність |
| Ціна | Плата за використання | Безкоштовно (на пристрої) |
Як витягти аудіо з відео на клієнті?
Перед відправкою в Whisper потрібно витягти аудіодоріжку — відправляти все відео надлишково:
// iOS: AVAssetExportSession для витягування аудіо
func extractAudio(from videoURL: URL) async throws -> URL {
let asset = AVURLAsset(url: videoURL)
guard let exportSession = AVAssetExportSession(
asset: asset, presetName: AVAssetExportPresetAppleM4A
) else { throw SubtitleError.exportFailed }
let outputURL = FileManager.default.temporaryDirectory
.appendingPathComponent(UUID().uuidString + ".m4a")
exportSession.outputURL = outputURL
exportSession.outputFileType = .m4a
await exportSession.export()
return outputURL
}
m4a/mp3 в 3–5 разів менше оригінального відео — швидше завантажується і дешевше по API.
Сегменти субтитрів: обробка на клієнті
Whisper verbose_json повертає segments з start, end, text. Нарізаємо по 5–7 слів на субтитр для читабельності:
// Android: розбивка на субтитри
data class SubtitleCue(val start: Double, val end: Double, val text: String)
fun segmentsToSubtitles(words: List<WhisperWord>, maxWords: Int = 7): List<SubtitleCue> {
val cues = mutableListOf<SubtitleCue>()
var chunk = mutableListOf<WhisperWord>()
for (word in words) {
chunk.add(word)
if (chunk.size >= maxWords || word.word.endsWith(".") || word.word.endsWith("!")) {
cues.add(SubtitleCue(
start = chunk.first().start,
end = chunk.last().end,
text = chunk.joinToString(" ") { it.word.trim() }
))
chunk.clear()
}
}
if (chunk.isNotEmpty()) {
cues.add(SubtitleCue(chunk.first().start, chunk.last().end,
chunk.joinToString(" ") { it.word.trim() }))
}
return cues
}
Рендеринг субтитрів: overlay чи вбудовані?
Overlay під час відтворення — UILabel/TextView поверх AVPlayerLayer/ExoPlayer. Оновлюємо текст по таймеру через player.currentTime(). Просто, не модифікує вихідний файл.
Вбудовані субтитри — FFmpeg subtitles фільтр, зберігає субтитри в пікселях відео. Постійно видні при будь-якому відтворенні:
ffmpeg -i input.mp4 -vf "subtitles=subs.srt:force_style='FontName=Arial,FontSize=20,PrimaryColour=&HFFFFFF,OutlineColour=&H000000,Bold=1'" output.mp4
Для Stories/Reels потрібні вбудовані субтитри — при шарінгу overlay загубиться. Для внутрішнього плеєра додатка — overlay достатній.
| Критерій | Overlay | Вбудовані (burned-in) |
|---|---|---|
| Сумісність | Тільки у вашому плеєрі | Будь-який плеєр |
| Редагування після експорту | Так (змінюєте текст) | Ні (фіксовані у відео) |
| Розмір відео | Не збільшується | Збільшується (ре-кодинг) |
| Час рендерингу | Миттєво | ~1x реального часу |
| Підходить для | Внутрішній перегляд | Шарінг, Stories, Reels |
Редактор субтитрів
Часто користувач хоче виправити помилки транскрипції. Мінімальний редактор:
- Список SubtitleCue в RecyclerView/List
- Tap на елемент → TextField для редагування тексту
- Drag/resize для зсуву таймкодів
- Preview у відеоплеєрі з оновленими субтитрами в реальному часі
Зручний UX: при редагуванні тексту — автоматично коригувати кінець попереднього / початок наступного субтитру.
Експорт SRT/VTT
SRT — стандартний формат для експорту:
1
00:00:01,200 --> 00:00:03,450
Привіт, це тестовий текст
2
00:00:03,800 --> 00:00:06,100
Другий субтитр тут
На мобілі пишемо в FileManager.default.temporaryDirectory, шаримо через UIActivityViewController/FileProvider.
SRT і VTT — прості текстові формати з таймкодами. VTT підтримує стилі. Обидва широко підтримуються на всіх платформах.
OpenAI Whisper API — основа нашого рішення.
Як ми це робимо: кейс з освітньою платформою
На одному з проектів для освітньої платформи ми інтегрували Whisper API для автоматичної генерації субтитрів до відеолекцій. Основна проблема була в точності синхронізації для російської мови — on-device рішення давало занадто багато помилок. Ми обрали API, налаштували витягування аудіо через AVAssetExportSession (для iOS) і MediaExtractor (для Android), реалізували розбивку на субтитри по 5-7 слів та вбудований редактор. Результат: час обробки 10-хвилинного відео скоротився з 5 хвилин до 30 секунд, а вартість транскрипції знизилася на 40% за рахунок оптимізації стиснення аудіо.
Що входить в реалізацію
- Інтеграція Whisper API або on-device транскрипції
- Витягування аудіо з відео
- Розбивка на субтитри з таймкодами
- Вибір типу рендерингу (overlay або вбудовані)
- Вбудований редактор субтитрів
- Експорт в SRT/VTT
- Тестування та оптимізація продуктивності
- Документація та інструкція для користувача
Етапи реалізації: покроково
- Аналіз — визначаємо вимоги до транскрипції (мова, точність, приватність), обираємо стек.
- Проектування — архітектура модуля субтитрів, UX редактора.
- Інтеграція — підключення Whisper API або on-device моделі, витягування аудіо.
- Реалізація — розбивка на субтитри, рендеринг, редактор, експорт.
- Тестування — перевірка точності синхронізації, продуктивності, чуйності інтерфейсу.
- Деплой — публікація в сторах, налаштування моніторингу.
Терміни та вартість
Базова інтеграція з Whisper API та overlay плеєром — 3–4 дні. Повний функціонал з on-device транскрипцією, редактором та вбудованими субтитрами — 2–3 тижні. Вартість розраховується індивідуально, зв'яжіться з нами для консультації — оцінимо ваш проект протягом дня. Замовте аудит поточного рішення або отримайте безкоштовну консультацію.







