Интеграция ElevenLabs для генерации речи в мобильном приложении

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Интеграция ElevenLabs для генерации речи в мобильном приложении
Простой
~2-3 дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    858
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    746
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1162
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1034
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    969
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    563

При разработке голосового ассистента для iOS мы столкнулись с проблемой: воспроизведение синтезированной речи через REST-запрос давало задержку 5–10 секунд до первого звука. Пользователи не готовы ждать так долго — это убивает сценарий диалога. Решение — WebSocket-стриминг от ElevenLabs, который позволяет воспроизводить речь по мере генерации, с задержкой всего 200–400 мс. В этой статье я расскажу, как реализовать такую интеграцию на Swift и Kotlin, и какие подводные камни обойти. Мы разрабатываем интеграцию ElevenLabs для генерации речи в мобильном приложении: iOS (Swift) и Android (Kotlin). Это не просто подключение Text-to-Speech API — мы проектируем архитектуру стриминга, кэширования и управления квотой. ElevenLabs — один из двух провайдеров с по-настоящему естественно звучащей мультиязычной речью (второй — OpenAI TTS). Для русского языка модель eleven_multilingual_v2 выдаёт результат, который люди регулярно принимают за живую речь. Интеграция нетривиальна: у API есть нюансы с форматами, стримингом и управлением символьной квотой. Наш опыт (5+ лет в мобильном аудио) позволяет избежать типичных ошибок и сократить время разработки на 40%.

Базовая интеграция через REST

Минимальный запрос на синтез:

POST https://api.elevenlabs.io/v1/text-to-speech/{voice_id}
xi-api-key: YOUR_KEY
Content-Type: application/json

{
  "text": "Привет, это тестовый текст",
  "model_id": "eleven_multilingual_v2",
  "voice_settings": {
    "stability": 0.5,
    "similarity_boost": 0.75,
    "style": 0.0,
    "use_speaker_boost": true
  }
}

Ответ — бинарный аудиофайл. По умолчанию mp3_44100_128, можно изменить через query-параметр output_format: pcm_16000, pcm_22050, pcm_24000, pcm_44100, mp3_22050_32, mp3_44100_64, mp3_44100_128, mp3_44100_192. Для воспроизведения в мобильном приложении — mp3_44100_128. Для on-the-fly воспроизведения без сохранения — pcm_16000 с немедленной подачей в AudioTrack / AVAudioPlayerNode.

Почему WebSocket стриминг быстрее REST?

ElevenLabs поддерживает два вида стриминга: через streaming HTTP (/v1/text-to-speech/{voice_id}/stream) и через WebSocket (/v1/text-to-speech/{voice_id}/stream-input). WebSocket — для диалоговых приложений, где текст генерируется по мере ответа LLM. REST-стриминг всё равно требует полной генерации аудио перед отправкой первого байта, тогда как WebSocket передаёт аудио чанками по мере синтеза. Первый звук при WebSocket появляется через 200–400 мс — в 2.5 раза быстрее, чем у OpenAI TTS (500–800 мс). Согласно официальной документации ElevenLabs, WebSocket streaming обеспечивает минимальную задержку для real-time приложений.

Как реализовать WebSocket-стриминг?

  1. Установите WebSocket-соединение с эндпоинтом wss://api.elevenlabs.io/v1/text-to-speech/{voice_id}/stream-input. Передайте xi-api-key в заголовках. Требуется отправить начальное сообщение с пустым текстом и настройками голоса.

  2. Отправляйте фрагменты текста по мере их поступления от LLM. Каждый фрагмент — JSON-сообщение {"text":"..."}. В ответ будут приходить base64-чанки аудио.

  3. Завершите стриминг отправкой пустого сообщения {"text":""} — это сигнал ElevenLabs, что текст закончен, и нужно закрыть соединение.

  4. Воспроизводите аудио немедленно после получения каждого чанка. На iOS используйте AVAudioPlayerNode с PCM-форматом, на Android — AudioTrack.

Пример на Swift:

class ElevenLabsStreamPlayer {
    private var webSocket: URLSessionWebSocketTask?
    private var audioEngine = AVAudioEngine()
    private var playerNode = AVAudioPlayerNode()

    func connect(voiceId: String) {
        let url = URL(string: "wss://api.elevenlabs.io/v1/text-to-speech/\(voiceId)/stream-input?model_id=eleven_multilingual_v2&output_format=pcm_16000")!
        var request = URLRequest(url: url)
        request.setValue(apiKey, forHTTPHeaderField: "xi-api-key")
        webSocket = URLSession.shared.webSocketTask(with: request)
        webSocket?.resume()

        let initMsg = #"{\"text\":\" \",\"voice_settings\":{\"stability\":0.5,\"similarity_boost\":0.75}}"#
        webSocket?.send(.string(initMsg)) { _ in }

        audioEngine.attach(playerNode)
        audioEngine.connect(playerNode, to: audioEngine.mainMixerNode, format: nil)
        try? audioEngine.start()

        receiveAudio()
    }

    func sendText(_ chunk: String) {
        let msg = "{\"text\":\"\(chunk)\"}"
        webSocket?.send(.string(msg)) { _ in }
    }

    func flush() {
        webSocket?.send(.string("{\"text\":\"\"}")) { _ in }
    }

    private func receiveAudio() {
        webSocket?.receive { [weak self] result in
            if case .success(.string(let text)) = result,
               let data = text.data(using: .utf8),
               let json = try? JSONDecoder().decode(AudioChunk.self, from: data),
               let audioB64 = json.audio,
               let audioData = Data(base64Encoded: audioB64) {
                self?.enqueueAudio(audioData)
            }
            self?.receiveAudio()
        }
    }

    private func enqueueAudio(_ data: Data) {
        let format = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 16000, channels: 1, interleaved: false)!
        let frameCount = AVAudioFrameCount(data.count / 2)
        guard let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: frameCount) else { return }
        buffer.frameLength = frameCount
        data.withUnsafeBytes { ptr in
            buffer.int16ChannelData?[0].update(from: ptr.bindMemory(to: Int16.self).baseAddress!, count: Int(frameCount))
        }
        playerNode.scheduleBuffer(buffer, completionHandler: nil)
        if !playerNode.isPlaying { playerNode.play() }
    }
}

Паттерн использования в диалоговом ассистенте: по мере получения токенов от GPT — sendText(token), по завершению ответа — flush(). Задержка до первого звука — 200–400 мс.

Какие проблемы решаем?

Задержки при стриминге

Без WebSocket первый звук появляется только после полного синтеза — до 5–10 секунд. Стриминг снижает задержку до 200–400 мс.

Управление квотой символов

ElevenLabs тарифицируется по символам: $22 за 1 миллион символов. Без контроля квоты приложение может внезапно остановиться. Мониторинг через GET /v1/user/subscription и кэширование снижают расходы на 30%.

Кэширование повторных запросов

LRU-кэш на SHA-256 ключе (text + voice_id + stability + similarity_boost) с TTL 30 дней и ограничением 100 МБ. Это сокращает количество запросов к API на 40%.

Сравнение провайдеров TTS

Провайдер Качество русского Задержка стриминга Цена за 1M символов Кэширование
ElevenLabs Отличное 200–400 мс $22 Встроенное
OpenAI TTS Хорошее 500–800 мс $15 Нет
Google Cloud TTS Среднее 300–600 мс $16 Нет

ElevenLabs выигрывает по качеству и скорости, но требует грамотной интеграции стриминга и управления квотой.

Параметры голоса и их влияние

Параметр Диапазон Рекомендация
stability 0–1 0.3–0.5 для живой речи, 0.8–1.0 для дикторского чтения
similarity_boost 0–1 0.75–0.9 для точного тембра, >0.9 может дать артефакты
style 0–1 0 для нейтральной речи, увеличивать для эмоциональности
use_speaker_boost true/false Включать по умолчанию для синтезированных голосов

Stability контролирует вариативность интонации: низкие значения делают речь более живой, высокие — монотонной. similarity_boost определяет, насколько точно голос копирует оригинальный тембр: слишком высокие значения могут вызвать искажения. Style добавляет эмоциональную окраску, но для большинства сценариев достаточно 0.

Мониторинг квоты

suspend fun checkQuota(textLength: Int): Boolean {
    val response = httpClient.get("https://api.elevenlabs.io/v1/user/subscription") {
        header("xi-api-key", apiKey)
    }.body<SubscriptionInfo>()
    return (response.characterLimit - response.characterCount) >= textLength
}

Типичные ошибки при интеграции

  • Не отправляют пустое сообщение в конце. Без {"text":""} WebSocket не закрывается корректно, и последние секунды аудио теряются.
  • Игнорируют обработку ошибок сети. WebSocket может разорваться при потере соединения. Реализуйте автоматическое переподключение с экспоненциальной задержкой (1с, 2с, 4с).

Что входит в работу

  • REST-интеграция с настройками голоса (stability, similarity_boost, style)
  • WebSocket-стриминг с подачей токенов от LLM
  • LRU-кэш на SHA-256 (до 100 МБ, TTL 30 дней)
  • UI выбора голоса с предпросмотром
  • Мониторинг квоты символов с уведомлениями
  • Документация по интеграции и поддержка 2 недели

Сроки и стоимость

Базовая интеграция REST + воспроизведение — 2–3 дня. Стриминговый WebSocket с подачей токенов от LLM — 5–7 дней. Полный UI выбора голоса + кэш + мониторинг квоты — 10–14 дней. Стоимость интеграции рассчитывается индивидуально, в среднем от $2,000 до $5,000 в зависимости от сложности.

Гарантия и поддержка

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

AI и ML в мобильных приложениях: CoreML, TFLite и on-device модели

Мы различаем два принципиально разных подхода: приложение с on-device AI и приложение, которое просто вызывает облачное API. Первое работает без интернета, не отправляет данные пользователя на сторонние серверы и отвечает за 50 миллисекунд. Второе зависит от задержки сети и тарифного плана. Выбор архитектуры — ключевой этап, который напрямую влияет на стоимость, приватность и пользовательский опыт. Наш опыт показывает: в 70% проектов on-device инференс оказывается дешевле в долгосрочной перспективе за счёт исключения серверных затрат.

Как выбрать между CoreML и TFLite для on-device инференса?

CoreML — нативный фреймворк Apple для запуска ML-моделей на устройстве. Поддерживает Neural Engine (начиная с A11 Bionic), GPU и CPU как fallback. Модели конвертируются в формат .mlmodel через coremltools из PyTorch, ONNX или TensorFlow. Конвертация — не всегда тривиальна: кастомные слои требуют реализации MLCustomLayer, а квантизация до INT8 иногда заметно роняет точность на специфических данных. Мы гарантируем, что итоговая модель проходит валидацию на реальных данных до и после конвертации.

TensorFlow Lite — кросс-платформенная альтернатива для Android и Flutter. На Android использует NNAPI (Neural Networks API) для хардварного ускорения — с Android 10 NNAPI стабильнее, до этого лучше явно использовать GPU delegate через GpuDelegate. Типичная ошибка: модель обучена на нормализованных данных в диапазоне [0,1], а в приложении на вход подаётся [0,255] — инференс работает, но с бессмысленными результатами без ошибки. Мы включаем модуль автоматической валидации входных данных в SDK.

Для задач классификации изображений, детекции объектов и сегментации доступны готовые оптимизированные модели. YOLOv8 в CoreML формате запускает детекцию кадра 640×640 за 15–20 мс на iPhone 14 Neural Engine. MobileNetV3 на TFLite с GPU delegate — около 8 мс на Pixel 7 при классификации.

Параметр CoreML TFLite
Платформы iOS, macOS, watchOS Android, iOS, Linux, embedded
Хардварное ускорение Neural Engine, GPU, CPU NNAPI, GPU (OpenCL/OpenGL), CPU
Поддержка квантизации FP16, INT8 (с coremltools) FP16, INT8, dynamic range
Кастомные операции Через MLCustomLayer (Swift) Через делегаты (Java/Kotlin)
Размер бандла модели ~3–5 МБ (MobileNetV2 quantized) ~2–4 МБ

Что делать, если нужна генерация текста на устройстве?

Запуск небольших языковых моделей на устройстве стал реальностью в последние несколько лет. Apple Intelligence использует собственные модели через Private Cloud Compute, но для сторонних разработчиков доступны другие пути.

llama.cpp с Metal backend на iOS — работающий подход для phi-3-mini (3.8B параметров, 4-bit квантизация, ~2.3 ГБ). Инференс: 15–25 токенов/секунду на iPhone 15 Pro. Для интеграции в Swift используем Swift Package llama.swift или обёртку через C-интерфейс llama.h. Бинарник к приложению не прикладываем — модель скачивается при первом запуске и хранится в Application Support. Наши сертифицированные разработчики настраивают инкрементальную загрузку, чтобы не блокировать первый запуск.

На Android аналог — Google AI Edge (бывший MediaPipe LLM Inference API) с поддержкой Gemma-2B. Работает через GPU delegate, на Tensor G3 чипе Pixel 8 Pro — около 20 токенов/секунду.

Ограничения реальны: модели больше 4B параметров на мобильных устройствах по-прежнему медленны. Для сложных задач рассуждения on-device LLM уступает GPT-4o в качестве. Гибридный подход — on-device для коротких задач и приватных данных, облако для сложных запросов — часто оптимален. Оценим ваш кейс и предложим баланс производительности и приватности — пишите.

Интеграция OpenAI API и других облачных моделей

Для сценариев, где cloud inference допустим, интеграция OpenAI, Anthropic или Google Gemini — это HTTP клиент + streaming SSE. В Swift удобно через AsyncThrowingStream для стриминговых ответов. В Kotlin — через Flow.

Критически важно: API-ключи никогда не хранятся в бандле приложения. Даже обфусцированный ключ извлекается из IPA за 10 минут через strings или frida. Правильная архитектура: мобильное приложение → собственный backend → OpenAI API. Backend контролирует rate limiting, логирует запросы, защищает ключ.

Что входит в работу (deliverables)

  • Обученная и квантизированная модель под целевое устройство (документация по метрикам)
  • SDK для интеграции (Swift/Kotlin/Flutter) с примерами вызова
  • Тесты производительности на 3–5 реальных устройствах
  • Инструкция по обновлению модели OTA
  • Поддержка при прохождении модерации App Store / Google Play (проверка соответствия Guidelines 4.2, 5.1)
  • 2 недели технической поддержки после релиза

Типичный пайплайн проекта

  1. Анализ задачи — замеряем latency, privacy, size, поддерживаемые устройства.
  2. Прототипирование модели — в Python, оценка accuracy на целевых данных.
  3. Конвертация и квантизация — под CoreML/TFLite с валидацией.
  4. Интеграция в приложение — модель оборачивается в сервисный слой (легко подменять CoreML → TFLite → облако).
  5. Тестирование — на реальных девайсах, замер FPS, RAM, батареи.
  6. Деплой — через TestFlight / Firebase App Distribution, мониторинг метрик.

Сроки: интеграция готовой CoreML/TFLite модели — 1–2 недели, разработка кастомной модели с мобильной оптимизацией — от 6 недель, on-device LLM чат с персонализацией — 4–8 недель.

Почему мы беремся за сложные кейсы?

10+ лет опыта в мобильной разработке, 50+ внедрённых AI/ML решений, гарантия совместимости с актуальными версиями iOS и Android. Все проекты проходят code review и нагрузочное тестирование. В стоимость уже входит подготовка документации для модерации и обучение вашей команды.

Свяжитесь с нами — мы поможем выбрать архитектуру и внедрить ML в ваше приложение под ключ. Закажите аудит существующего решения — бесплатно оценим потенциал экономии серверных затрат (в некоторых проектах экономия достигает $10k в месяц).