# 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
