16 KiB
Go Speech - TTS микросервис
Микросервис на Go для преобразования русского текста в речь через Piper TTS с HTTPS API.
Возможности
- HTTP/HTTPS API для синтеза речи
- Веб-интерфейс для удобного использования через браузер
- Поддержка русского языка через Piper TTS
- Выбор из 4 голосов: Ruslan, Irina, Denis, Dmitri
- Локальная генерация речи (без внешних API)
- Возврат аудио в формате OGG
- Встроенный фронтенд в бинарнике (не требует отдельных файлов)
- Кэширование сгенерированных аудио файлов для ускорения повторных запросов
- Автоматическая очистка кэша (удаление файлов старше 3 дней)
- Контейнеризация через Podman/Docker
Требования
- Go 1.21+
- Piper TTS (устанавливается автоматически в Docker образе)
- ffmpeg (для конвертации в OGG)
- SSL сертификаты (самоподписанные для разработки)
Установка и запуск
Локальная разработка
1 Клонируйте репозиторий:
git clone <repository-url>
cd go-speech
2 Установите зависимости:
go mod download
3 Скачайте русскую модель Piper TTS:
mkdir -p models
curl -L https://huggingface.co/rhasspy/piper-voices/resolve/main/ru/ru_RU/denis/medium/ru_RU-denis-medium.onnx -o models/ru_RU-denis-medium.onnx
curl -L https://huggingface.co/rhasspy/piper-voices/resolve/main/ru/ru_RU/denis/medium/ru_RU-denis-medium.onnx.json -o models/ru_RU-denis-medium.onnx.json
4 Установите Piper TTS локально (если запускаете вне Docker):
# Скачайте бинарник с https://github.com/rhasspy/piper/releases
# И поместите в PATH или укажите путь через переменную окружения PIPER_PATH
5 Установите ffmpeg:
# Ubuntu/Debian
sudo apt-get install ffmpeg
# Alpine
apk add ffmpeg
6 Сгенерируйте SSL сертификаты:
./generate-certs.sh
7 Запустите сервис:
go run main.go
Или с переменными окружения:
GO_SPEECH_PORT=8443 \
GO_SPEECH_PIPER_PATH=/usr/local/bin/piper \
GO_SPEECH_MODEL_DIR=./models \
GO_SPEECH_VOICE=ruslan \
GO_SPEECH_FFMPEG_PATH=/usr/bin/ffmpeg \
GO_SPEECH_CERT_FILE=./certs/server.crt \
GO_SPEECH_KEY_FILE=./certs/server.key \
go run main.go
Для использования другого голоса (например, denis, dmitri, irina):
GO_SPEECH_VOICE=denis go run main.go
Запуск через Podman/Docker
1 Соберите образ:
podman build -t go-speech:latest .
2 Скачайте модель (если не включена в образ):
mkdir -p models
curl -L https://huggingface.co/rhasspy/piper-voices/resolve/main/ru/ru_RU/denis/medium/ru_RU-denis-medium.onnx -o models/ru_RU-denis-medium.onnx
curl -L https://huggingface.co/rhasspy/piper-voices/resolve/main/ru/ru_RU/denis/medium/ru_RU-denis-medium.onnx.json -o models/ru_RU-denis-medium.onnx.json
3 Сгенерируйте сертификаты:
./generate-certs.sh
4 Запустите контейнер:
podman run -d \
--name go-speech \
-p 8443:8443 \
-e GO_SPEECH_VOICE=ruslan \
-v $(pwd)/models:/app/models:ro \
-v $(pwd)/certs:/app/certs:ro \
go-speech:latest
Для использования другого голоса:
podman run -d \
--name go-speech \
-p 8443:8443 \
-e GO_SPEECH_VOICE=denis \
-v $(pwd)/models:/app/models:ro \
-v $(pwd)/certs:/app/certs:ro \
go-speech:latest
Запуск как systemd сервис
-
Отредактируйте
go-speech.serviceи укажите правильные пути к моделям и сертификатам -
Скопируйте unit файл:
sudo cp go-speech.service /etc/systemd/system/
3 Перезагрузите systemd:
sudo systemctl daemon-reload
4 Запустите сервис:
sudo systemctl start go-speech
sudo systemctl enable go-speech
5 Проверьте статус:
sudo systemctl status go-speech
Веб-интерфейс
GET /go-speech/front
Встроенный веб-интерфейс для синтеза речи через браузер.
Доступ:
Откройте в браузере:
https://localhost:8443/go-speech/front
GET /go-speech/help
Отображение документации (README.md) в браузере.
Доступ:
https://localhost:8443/go-speech/help
Возможности:
- Выбор голоса из доступных моделей (Ruslan, Irina, Denis, Dmitri)
- Многострочное поле для ввода текста
- Кнопка "Озвучить" - генерирует и проигрывает аудио в браузере
- Кнопка "Скачать" - скачивает файл озвучки
- Минималистичный дизайн
Фронтенд полностью встроен в бинарник и не требует дополнительных файлов.
API
Все API endpoints доступны по префиксу /go-speech/api/v1/
POST /go-speech/api/v1/tts
Преобразует текст в речь и возвращает OGG аудио файл.
Запрос (без указания голоса, используется голос по умолчанию):
curl -X POST https://localhost:8443/go-speech/api/v1/tts \
-H "Content-Type: application/json" \
-d '{"text": "Привет, это тестовый текст"}' \
--insecure \
-o output.ogg
Запрос (с указанием голоса):
curl -X POST https://localhost:8443/go-speech/api/v1/tts \
-H "Content-Type: application/json" \
-d '{"text": "Привет, это тестовый текст", "voice": "irina"}' \
--insecure \
-o output-irina.ogg
Параметры запроса:
text(обязательный) - Текст для озвучки (максимум 5000 символов)voice(опциональный) - Голос для синтеза:ruslan(по умолчанию),irina,denis,dmitri
Ответ:
- Content-Type:
audio/ogg - Body: OGG аудио файл
- Content-Disposition:
inline; filename=speech-{voice}.ogg
Коды ответа:
200- Успех400- Неверный запрос (пустой текст, слишком длинный текст, неверный голос)405- Неверный HTTP метод500- Ошибка сервера
GET /go-speech/api/v1/healthz
Генерирует аудио файл со словом "Окей" и возвращает его. Используется для проверки работоспособности TTS.
Запрос:
curl -k https://localhost:8443/go-speech/api/v1/healthz -o healthz.ogg
Ответ:
- Content-Type:
audio/ogg - Body: OGG аудио файл со словом "Окей"
GET /go-speech/api/v1/health
Проверка работоспособности сервиса.
Запрос:
curl https://localhost:8443/go-speech/api/v1/health --insecure
Ответ:
200 OK- Сервис работает
Переменные окружения
PORT- Порт для HTTPS сервера (по умолчанию: 8443)CERT_FILE- Путь к SSL сертификату (по умолчанию: certs/server.crt)KEY_FILE- Путь к SSL приватному ключу (по умолчанию: certs/server.key)PIPER_PATH- Путь к бинарнику Piper TTS (по умолчанию: /usr/local/bin/piper)MODEL_DIR- Директория с моделями (по умолчанию: models)GO_SPEECH_VOICE- Имя голоса для синтеза речи (по умолчанию: ruslan)- Доступные варианты:
ruslan,denis,dmitri,irina - Путь к модели формируется как:
{MODEL_DIR}/ru_RU-{GO_SPEECH_VOICE}-medium.onnx
- Доступные варианты:
MODEL_PATH- Полный путь к модели Piper TTS (опционально, переопределяет автоматический выбор на основе GO_SPEECH_VOICE)FFMPEG_PATH- Путь к бинарнику ffmpeg (по умолчанию: /usr/bin/ffmpeg)GO_SPEECH_MODE- Режим работы сервера (по умолчанию: debug)release- Режим продакшена (минимальное логирование)- Любое другое значение - Режим разработки (подробное логирование всех операций)
Кэширование
Сервер автоматически кэширует сгенерированные аудио файлы для ускорения обработки повторных запросов.
Как работает кэш
- Директория кэша: Создается автоматически в директории рядом с исполняемым файлом (
./cache/) - Ключ кэша: SHA256 хеш от комбинации имени модели и текста (
SHA256(model_name:text)) - Проверка кэша: При каждом запросе сначала проверяется наличие файла в кэше
- Сохранение: После генерации аудио файл автоматически сохраняется в кэш
- Автоочистка: Фоновая горутина каждые 5 минут удаляет файлы старше 3 дней
Преимущества кэширования
- Ускорение повторных запросов с тем же текстом и голосом
- Снижение нагрузки на систему (не требуется повторная генерация)
- Автоматическое управление размером кэша
Пример работы
# Первый запрос - генерация и сохранение в кэш
curl -X POST https://localhost:8443/tts \
-H "Content-Type: application/json" \
-d '{"text": "Привет", "voice": "irina"}' \
--insecure -o output1.ogg
# Второй запрос с тем же текстом - используется кэш (быстрее)
curl -X POST https://localhost:8443/tts \
-H "Content-Type: application/json" \
-d '{"text": "Привет", "voice": "irina"}' \
--insecure -o output2.ogg
Примечание: Кэш работает автоматически и не требует дополнительной настройки.
Логирование
Сервер поддерживает два режима логирования, управляемые переменной окружения GO_SPEECH_MODE:
Режим разработки (по умолчанию)
Когда GO_SPEECH_MODE не установлена или имеет любое значение кроме release, включается подробное логирование:
- Детальная информация о конфигурации при запуске
- Логирование всех входящих HTTP запросов с параметрами
- Подробная информация о процессе генерации аудио
- Логирование выполнения команд Piper TTS и ffmpeg
- Информация о размерах файлов и времени выполнения операций
- Детальные сообщения об ошибках с контекстом
Пример вывода в режиме разработки:
[INFO] === Запуск Go Speech TTS сервера ===
[DEBUG] Режим отладки: ВКЛЮЧЕН
[DEBUG] Конфигурация:
[DEBUG] PORT: 8443
[DEBUG] PIPER_PATH: /usr/local/bin/piper
[DEBUG] === Обработка TTS запроса ===
[DEBUG] Тело запроса: {"text":"Привет","voice":"irina"}
[DEBUG] === Генерация аудио ===
[DEBUG] Запуск Piper TTS для генерации WAV...
Режим продакшена
Установите GO_SPEECH_MODE=release для минимального логирования:
- Только критичные ошибки и важные события
- Базовая информация о запросах (метод, путь, время выполнения)
- Без детальной отладочной информации
Пример запуска в режиме продакшена:
GO_SPEECH_MODE=release ./go-speech
Структура проекта
go-speech/
├── main.go # Основной HTTP сервер
├── handlers/ # HTTP обработчики
│ └── tts.go # Обработчик TTS запросов
├── tts/ # TTS модуль
│ └── piper.go # Интеграция с Piper TTS
├── internal/ # Внутренние пакеты
│ ├── logger/ # Модуль логирования
│ │ └── logger.go # Логирование с поддержкой режимов
│ └── cache/ # Модуль кэширования
│ └── cache.go # Кэширование аудио файлов
├── cache/ # Директория кэша (создается автоматически)
├── static/ # Статические файлы фронтенда
│ └── index.html # Веб-интерфейс (встраивается в бинарник)
├── models/ # Модели Piper TTS
├── certs/ # SSL сертификаты
├── Dockerfile # Контейнер для Podman/Docker
├── go-speech.service # Systemd unit файл
├── generate-certs.sh # Скрипт генерации сертификатов
└── README.md # Документация
Разработка
Сборка
go build -o go-speech .
Тестирование
# Запустите сервис
go run main.go
# Откройте веб-интерфейс в браузере
# https://localhost:8443/go-speech/front
# Или документацию
# https://localhost:8443/go-speech/help
# Или используйте API напрямую
curl -X POST https://localhost:8443/go-speech/api/v1/tts \
-H "Content-Type: application/json" \
-d '{"text": "Тестовый текст"}' \
--insecure \
-o test.ogg
# С указанием голоса
curl -X POST https://localhost:8443/go-speech/api/v1/tts \
-H "Content-Type: application/json" \
-d '{"text": "Привет, это тестовый текст", "voice": "irina"}' \
--insecure \
-o output-irina.ogg
# Проверка работоспособности
curl -k https://localhost:8443/go-speech/api/v1/healthz -o healthz.ogg
curl https://localhost:8443/go-speech/api/v1/health --insecure
Лицензия
MIT