Skip to content

Repository files navigation

Mutty 🎙️

ReactTypeScriptLiveKitTauriDocker

Mutty — open-source платформа для голосового общения в реальном времени, построенная на базе LiveKit. Включает веб и десктоп-клиенты с коллаборативными модулями и AI-ботом.

Проект оригинально начат как Voice App, затем ребрендирован в Mutty.


Возможности

  • Голосовая связь в реальном времени (WebRTC, низкая задержка)
  • Discord-подобные голосовые каналы
  • Шаринг экрана со звуковыми сигналами (start/stop chime)
  • Плавающие окна — коллаборативный whiteboard (tldraw) и shared notepad
  • Бот-агент со встроенным AI через OpenRouter — стримит YouTube/Twitch/SoundCloud и отвечает в чате
  • Чат с вложениями изображений, drag-and-drop, превью твитов
  • Кроссплатформенность — веб (React) + десктоп (Tauri + Rust)
  • Self-hosted — полностью под твоим контролем

Лицензии сторонних сервисов

tldraw (whiteboard)

Whiteboard использует tldraw — коммерческую библиотеку с платной лицензией.

  • Для локальной разработки — ключ не нужен, оценочный режим работает полностью.
  • Для production — если whiteboard используется активно, получите бесплатный Hobby license на tldraw.dev/r/pricing (для личных/некоммерческих проектов).
  • Как указать ключ:
    1. Получите ключ на сайте tldraw
    2. Добавьте в .env:
      TLDRAW_LICENSE_KEY=your_key_here
    3. Перезапустите frontend (pnpm dev) — ключ встроится автоматически.
Без ключаС ключом
Оценочный режимПолный функционал
Водянит "tldraw" на canvas (subtle watermark)Без водянок

Архитектура

┌─────────────────────┐ ┌──────────────────────────────┐
│ Web/Desktop │◄───────►│ Backend (Token Server) │
│ React + Vite │ HTTP │ Node.js / tsx │
│ :1420 / :1421 │ │ :4000 │
└──────────┬──────────┘ └──────────────┬───────────────┘
│ │
│ WebSocket / WebRTC │ HTTP (внутри Docker)
▼ ▼
┌───────────────────────────────────────────────────┐
│ LiveKit Server │
│ livekit-server:latest │
│ :7880 (WS) / :7881 (TCP) / :7882 (UDP) │
└──────────────────────┬────────────────────────────┘
│
WebSocket (внутри Docker)
▼
┌───────────────────────────────────────────────────┐
│ Agent Server (Python бот) │
│ livekit-agents + OpenRouter AI │
│ :8081 │
└───────────────────────────────────────────────────┘

Монорепо (pnpm workspace)

Voice-app/
├── backend/ # Token Server (Node.js + tsx)
├── packages/
│ ├── web/ # Веб-клиент (React + Vite)
│ ├── desktop/ # Десктоп (Tauri v2 + Rust)
│ └── shared/ # Shared компоненты (React hooks, UI, collab)
├── agent-server/ # Python бот
└── livekit/ # Конфиги LiveKit

Модули

1. LiveKit Server

  • Ядро WebRTC-инфраструктуры (Go), образ livekit/livekit-server:latest
  • Медиа-маршрутизация, сигнализация, управление комнатами
  • Порты:
    • 7880 — WebSocket (сигнализация)
    • 7881 — TCP (fallback для WebRTC)
    • 7882 — UDP (RTC, медиа)
  • Конфиг:livekit/livekit.prod.yaml (production)
  • Ключи: блок keys в YAML должен совпадать с LIVEKIT_API_KEY / LIVEKIT_API_SECRET из .env

2. Backend (Token Server)

  • Стек: TypeScript + tsx + livekit-server-sdk v2 + dotenv
  • За что отвечает: выдача JWT-токенов LiveKit для аутентификации в комнатах
  • Порт:4000
  • Ключевые env:
    • LIVEKIT_WS_URL — URL, отдаваемый браузеру (localhost или твой домен)
    • LIVEKIT_API_URL — авто-вычисляется из WS-URL (ws/http/)
    • TOKEN_CORS_ORIGINS — origins через запятую (пусто = [*])
    • TOKEN_ROOM_MAX_LENGTH / TOKEN_IDENTITY_MAX_LENGTH / TOKEN_TTL

3. Web Client (packages/web)

  • Стек: React + TypeScript + Vite + Tailwind CSS + shadcn/ui + LiveKit SDK + React Router
  • Порт:1420 (dev)
  • Фичи:
    • Голос/видео, screen share
    • Чат с вложениями изображений, drag-and-drop
    • Коллаборативный whiteboard (tldraw + LiveKit data channels)
    • Shared notepad (LiveKit data channels)
    • Floating windows — drag, resize, minimize

4. Desktop Client (packages/desktop)

  • Стек: Tauri v2 (React frontend + Rust backend)
  • Порт:1421 (dev)
  • Фичи:
    • Все фичи веб-клиента
    • Глобальные горячие клавиши (настраиваемые через UI, работают даже когда окно не в фокусе)
    • Трей (сворачивание в системный луч)
    • Звуки шаринга экрана (start/stop chime)
    • Agent controls — меню управления ботом (режимы, качество, очередь, громкость)
    • Сплэш-скрин при запуске

5. Shared (packages/shared)

  • Стек: React + TypeScript
  • Что внутри:
    • floating/ — система плавающих окон (drag, resize, z-index, minimize)
    • collab/ — синхронизация через LiveKit data channels (Yjs для whiteboard, JSON-reducer для notes)
    • components/livekit/ — UI компоненты комнаты (control bar, settings, chat)
    • hooks/ — React hooks (audio settings, camera, screen share, hotkeys)
    • modules/tldraw/ — tldraw-интеграция с коллаборацией
    • modules/notes/ — shared notepad с экспортом в .txt

6. Agent Server (Python бот)

  • Стек: Python 3.11 + livekit-agents + yt-dlp + ffmpeg
  • Порт:8081
  • Модульная архитектура:
    • src/core/agent.py — основной оркестратор
    • src/chat/ — чат-шлюз и парсер команд
    • src/media/ — стриминг, очередь воспроизведения, резолвер URL
    • src/llm/ — OpenRouter провайдер + промпты (AI-ассистент, поиск, плейлисты)
    • src/memory/ — SQLite memory store (история разговоров)
  • Команды в чате (без "!"):
    • <url> — воспроизвести ссылку (YouTube / Twitch / SoundCloud / Telegram)
    • add <url> / queue <url> — добавить в очередь
    • skip / next — пропустить трек
    • queue / list — показать очередь
    • clear — очистить очередь
    • стоп / stop — остановить
    • pause / resume — пауза / продолжить
    • repeat — повтор текущего трека
    • аудио <url> — только звук
    • видео <url> — видео + звук
    • youtube <запрос> / soundcloud <запрос> — поиск
    • ai <вопрос> / jarvis <вопрос> / бот <вопрос> — AI-ассистент
    • playlist <описание> / плейлист <описание> — AI генерирует плейлист
  • AI через OpenRouter:
    • Установи OPENROUTER_API_KEY в env
    • Бот отвечает на вопросы, может искать и играть музыку по запросу
    • Генерирует плейлисты по описанию (например, "lofi для программирования")
    • Помнит контекст разговора (SQLite per room)

Быстрый старт

1. Клон

git clone https://github.com/Gaigen/Voice-app.git
cd Voice-app

2. Зависимости

pnpm install

3. Настрой .env

cp .env.example .env
# LiveKit ключи (в проде — ОБЯЗАТЕЛЬНО свои!)LIVEKIT_API_KEY=devkeyLIVEKIT_API_SECRET=secret# URL для браузера (локально = localhost)VITE_LIVEKIT_URL=ws://localhost:7880VITE_TOKEN_ENDPOINT=http://localhost:4000/api/token# Token ServerLIVEKIT_WS_URL=ws://livekit:7880LIVEKIT_PUBLIC_WS_URL=ws://localhost:7880# Опционально# OPENROUTER_API_KEY=sk-or-v1-...# AGENT_MEDIA_PROXY=http://proxy:8080# AGENT_VIDEO_FPS=30# AGENT_VIDEO_QUALITY=720p

4. Запуск (Docker — всё вместе)

# Собрать и запустить все сервисы
docker-compose up -d --build

5. Запуск (Dev — только инфра, фронт локально)

# 1. Инфраструктура в Docker
docker-compose -f docker-compose.dev.yml up -d
# 2. Веб-клиент локальноcd packages/web
pnpm dev # http://localhost:1420# 3. Десктоп локальноcd packages/desktop
pnpm tauri dev # http://localhost:1421 + Tauri window

6. Открой приложение

СервисURLОписание
Web Clienthttp://localhost:1420Веб-интерфейс
Desktop Clientpnpm tauri devНативное окно
Token Serverhttp://localhost:4000API выдачи токенов (/health)
LiveKit WSws://localhost:7880WebSocket (сигнализация)
LiveKit Adminhttp://localhost:7880HTTP API LiveKit
Agent Serverhttp://localhost:8081YouTube/стриминг бот

Горячие клавиши

Веб (packages/web)

КомбоДействие
Ctrl + BОткрыть/закрыть Whiteboard
Ctrl + NОткрыть/закрыть Notes

Десктоп (packages/desktop)

Комбо (дефолт)ДействиеНастраиваемый
Ctrl + BWhiteboard toggle
Ctrl + NNotes toggle
Ctrl + MMute/unmute mic
Ctrl + FFull mute toggle
MouseBack(опционально)

Настройка — в Settings → Hotkeys. Работает глобально, даже когда окно свёрнуто (Windows).


Перенос на сервер (Production)

1. Смени ключи

В .env и livekit/livekit.prod.yaml — задай реальные ключи.

2. Публичный адрес

# С HTTPSVITE_LIVEKIT_URL=wss://example.com/livekitVITE_TOKEN_ENDPOINT=https://example.com/api/tokenLIVEKIT_WS_URL=wss://example.com/livekit# Без HTTPS (по IP)VITE_LIVEKIT_URL=ws://YOUR_SERVER_IP:7880VITE_TOKEN_ENDPOINT=http://YOUR_SERVER_IP:4000/api/token

3. Пересобери фронтенд

docker-compose build --no-cache frontend
docker-compose up -d

4. Reverse proxy + HTTPS

МаршрутБэкенд
/web :80
/api/tokenbackend :4000
/livekitlivekit :7880

5. Фаервол

ПортНазначение
80 / 443HTTP/HTTPS через reverse proxy
7880WebSocket (LiveKit)
7881TCP fallback (WebRTC)
7882/UDPМедиа (WebRTC)

6. TURN

Для пользователей за симметричным NAT — настрой TURN в livekit.prod.yaml.


Структура проекта

Voice-app/
├── docker-compose.yml # Production
├── docker-compose.dev.yml # Development (LiveKit + Backend)
├── .env.example # Шаблон переменных
├── pnpm-workspace.yaml # pnpm monorepo
│
├── backend/ # Token Server (Node.js + tsx)
│ ├── Dockerfile
│ ├── src/index.ts
│ ├── package.json
│ └── tsconfig.json
│
├── packages/
│ ├── web/ # Веб-клиент (React + Vite)
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ └── ...
│ │ ├── package.json
│ │ └── vite.config.ts
│ │
│ ├── desktop/ # Десктоп (Tauri v2)
│ │ ├── src/
│ │ │ ├── App.tsx
│ │ │ ├── components/
│ │ │ └── hooks/
│ │ ├── src-tauri/ # Rust код
│ │ │ ├── src/main.rs # Глобальные хоткеи, трей
│ │ │ └── tauri.conf.json
│ │ └── package.json
│ │
│ └── shared/ # Shared компоненты
│ ├── src/
│ │ ├── floating/ # Плавающие окна (drag, resize)
│ │ ├── collab/ # Коллаб-синхронизация (Yjs, LiveKit)
│ │ ├── components/livekit/ # UI комнаты
│ │ ├── modules/
│ │ │ ├── tldraw/ # tldraw + LiveKit data channels
│ │ │ └── notes/ # Shared notepad + export .txt
│ │ ├── hooks/ # React hooks
│ │ └── config.ts # Shared константы
│ └── package.json
│
├── agent-server/ # Python бот
│ ├── Dockerfile
│ ├── main.py # Entrypoint
│ ├── requirements.txt
│ └── src/
│ ├── core/agent.py # Оркестратор
│ ├── chat/ # Чат-шлюз, парсер команд
│ ├── media/ # Стриминг, очередь, резолвер
│ ├── llm/ # OpenRouter AI
│ └── memory/ # SQLite store
│
└── livekit/ # Конфиги LiveKit
└── livekit.prod.yaml

Troubleshooting

Контейнеры не стартуют

docker-compose logs -f # смотри логи
docker-compose ps # статус

Фронтенд не подключается к LiveKit

  • Проверь VITE_LIVEKIT_URL в .env (должен = ws://localhost:7880)
  • Пересобрей: docker-compose build --no-cache frontend && docker-compose up -d

WebRTC не работает

  • UDP порт 7882 должен быть открыт
  • Для внешних подключений — настрой TURN
  • Без HTTPS WebRTC работает только на localhost

Ошибка токенов

  • LIVEKIT_API_KEY / LIVEKIT_API_SECRET в .env и livekit/livekit.prod.yaml должны совпадать
  • Healthcheck бэкенда: http://localhost:4000/health

Бот не отвечает / не стримит

  • Проверь OPENROUTER_API_KEY (опционально, без него AI-фичи не работают, но стриминг да)
  • Проверь AGENT_MEDIA_PROXY если yt-dlp не достаёт YouTube
  • Логи: docker-compose logs -f agent-server

Лицензия

MIT

About

Mutty — open-source voice communication platform. Real-time rooms, collaborative tldraw whiteboard, AI bot, screen sharing. Self-hosted, privacy-first. Web + Desktop.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages