Files
go-speech/README.md
2025-11-25 15:08:04 +06:00

444 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 Клонируйте репозиторий:
```bash
git clone <repository-url>
cd go-speech
```
2 Установите зависимости:
```bash
go mod download
```
3 Скачайте русскую модель Piper TTS:
```bash
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):
```bash
# Скачайте бинарник с https://github.com/rhasspy/piper/releases
# И поместите в PATH или укажите путь через переменную окружения PIPER_PATH
```
5 Установите ffmpeg:
```bash
# Ubuntu/Debian
sudo apt-get install ffmpeg
# Alpine
apk add ffmpeg
```
6 Сгенерируйте SSL сертификаты:
```bash
./generate-certs.sh
```
7 Запустите сервис:
```bash
go run main.go
```
Или с переменными окружения:
```bash
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`):
```bash
GO_SPEECH_VOICE=denis go run main.go
```
### Запуск через Podman/Docker
1 Соберите образ:
```bash
podman build -t go-speech:latest .
```
2 Скачайте модель (если не включена в образ):
```bash
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 Сгенерируйте сертификаты:
```bash
./generate-certs.sh
```
4 Запустите контейнер:
```bash
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
```
Для использования другого голоса:
```bash
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 сервис
1. Отредактируйте `go-speech.service` и укажите правильные пути к моделям и сертификатам
2. Скопируйте unit файл:
```bash
sudo cp go-speech.service /etc/systemd/system/
```
3 Перезагрузите systemd:
```bash
sudo systemctl daemon-reload
```
4 Запустите сервис:
```bash
sudo systemctl start go-speech
sudo systemctl enable go-speech
```
5 Проверьте статус:
```bash
sudo systemctl status go-speech
```
## Веб-интерфейс
### GET /go-speech/front
Встроенный веб-интерфейс для синтеза речи через браузер.
**Доступ:**
Откройте в браузере:
``` text
https://localhost:8443/go-speech/front
```
### GET /go-speech/help
Отображение документации (README.md) в браузере.
**Доступ:**
``` text
https://localhost:8443/go-speech/help
```
**Возможности:**
- Выбор голоса из доступных моделей (Ruslan, Irina, Denis, Dmitri)
- Многострочное поле для ввода текста
- Кнопка "Озвучить" - генерирует и проигрывает аудио в браузере
- Кнопка "Скачать" - скачивает файл озвучки
- Минималистичный дизайн
Фронтенд полностью встроен в бинарник и не требует дополнительных файлов.
## API
Все API endpoints доступны по префиксу `/go-speech/api/v1/`
### POST /go-speech/api/v1/tts
Преобразует текст в речь и возвращает OGG аудио файл.
**Запрос (без указания голоса, используется голос по умолчанию):**
```bash
curl -X POST https://localhost:8443/go-speech/api/v1/tts \
-H "Content-Type: application/json" \
-d '{"text": "Привет, это тестовый текст"}' \
--insecure \
-o output.ogg
```
**Запрос (с указанием голоса):**
```bash
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.
**Запрос:**
```bash
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
Проверка работоспособности сервиса.
**Запрос:**
```bash
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 дней
### Преимущества кэширования
- Ускорение повторных запросов с тем же текстом и голосом
- Снижение нагрузки на систему (не требуется повторная генерация)
- Автоматическое управление размером кэша
### Пример работы
```bash
# Первый запрос - генерация и сохранение в кэш
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
- Информация о размерах файлов и времени выполнения операций
- Детальные сообщения об ошибках с контекстом
**Пример вывода в режиме разработки:**
``` text
[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` для минимального логирования:
- Только критичные ошибки и важные события
- Базовая информация о запросах (метод, путь, время выполнения)
- Без детальной отладочной информации
**Пример запуска в режиме продакшена:**
```bash
GO_SPEECH_MODE=release ./go-speech
```
## Структура проекта
``` text
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 # Документация
```
## Разработка
### Сборка
```bash
go build -o go-speech .
```
### Тестирование
```bash
# Запустите сервис
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