РУКОВОДСТВО

Озвучка текста в Rust офлайн

В Rust есть крейты-обёртки над движками речи операционной системы: для доступности это нормально, но голоса роботизированные и разные на каждой платформе; есть и облачные SDK с оплатой за символы. Игре, боту или консольной утилите, которым нужен один естественный голос везде, не подходит ни то ни другое.

Это руководство показывает, как вызывать бесплатный движок SuperClonica из Rust через локальный HTTP-сервер: естественные голоса, WAV-файлы, которые остаются у вас, и несколько строк с reqwest.

Способы говорить из Rust

Для озвучки в стиле экранного диктора подходят системные голоса; для голоса продукта или игры нужен движок.

  • Крейты-обёртки над системными голосами: офлайн и легко, но роботизированно и по-разному в Windows, macOS и Linux.
  • Облачные SDK: естественные голоса, но аккаунт, ключ, оплата за символы и ваш текст на чужих серверах.
  • SuperClonica: локальный HTTP-сервер с естественными голосами, голосами персонажей и своими, офлайн, везде, где работает Docker.
  • Он говорит на 31 языке; китайский пока не поддерживается.

Послушайте голоса бесплатно онлайн

Прежде чем писать код, откройте страницу любого голоса, впишите фразу от 30 до 100 символов, выберите язык и нажмите «Озвучить». Через несколько секунд вы услышите голос, который может быть у вашего приложения, без регистрации.

Запуск сервера речи

Видеокарта NVIDIA ускоряет работу с образом cuda, но не обязательна.

  • Запустите сервер на любом процессоре: docker run -d -p 8000:8000 -v superclonica-models:/models superclonica/superclonica:cpu.
  • Первый запуск скачивает модель Supertonic 3, около 385 МБ, в том; GET /health покажет, когда сервер готов.
  • POST /synthesize принимает JSON с полями text, voice, lang, seed и normalize и отвечает 16-битным моно-WAV.
  • voice — стандартное имя от M1 до M5 и от F1 до F5 или JSON-содержимое файла голоса.

Вызов из Rust

С крейтом reqwest и его фичей blocking, внутри функции, которая возвращает Result, запрос занимает несколько строк: let voice = std::fs::read_to_string("voice.json")?; let body = format!(r#"{{"text": "Привет из Rust!", "lang": "ru", "seed": 7, "voice": {voice}}}"#); let wav = reqwest::blocking::Client::new().post("http://localhost:8000/synthesize").header("Content-Type", "application/json").body(body).send()?.bytes()?; std::fs::write("hello.wav", wav)?; В асинхронном коде так же используйте асинхронный клиент reqwest. Для стандартного голоса отправьте "voice": "F1" вместо файла. Тот же текст, голос и seed всегда дают тот же звук, поэтому кешируйте файлы для повторяющихся фраз; serde_json помогает аккуратно собирать большие запросы.

Привычки для продакшена

Используйте один клиент reqwest и задавайте таймаут. Не открывайте порт 8000 в интернет как есть: задайте SUPERCLONICA_API_KEY и передавайте его как Bearer-токен или держите сервер в частной сети. Если запросов много одновременно, запустите больше копий модели через SUPERCLONICA_LANES и замерьте на своём железе: в наших тестах короткая фраза занимала 0,12 с на RTX 5070 Ti и 0,43 с на четырёх потоках процессора.