Files
ermnvldmr.com/services/docs/content/ru/quetza/guides/voice-features.md
T

64 lines
2.7 KiB
Markdown

---
title: Интерактивные голосовые функции
weight: 3
---
**Цель:** Реализовать сложные голосовые взаимодействия, которые учитывают границы серверов (гильдий) и управляют временными ресурсами.
## 1. Стратегия ограничения ресурсов
Голосовые функции **ОБЯЗАТЕЛЬНО** должны быть ограничены рамками Гильдии (Guild).
- **Паттерн:** Контроллер поддерживает `Map<GuildID, Player>`.
- **Поведение:**
- **Подключение (Join):** Создать Player для `Гильдии A`, если он еще не существует.
- **Отключение (Leave):** Уничтожить Player и освободить соединения.
- **Изоляция:** Команды в `Гильдии B` никогда не влияют на `Гильдию A`.
## 2. Оркестрация команд
Голосовые функции требуют набора команд, координируемых через Контроллер.
| Команда | Действие | Логика Контроллера |
| :--- | :--- | :--- |
| `/join` | Подключиться к каналу | `createPlayer(guildId, channelId)` |
| `/play` | Добавить трек в очередь | `getPlayer(guildId).enqueue(track)` |
| `/stop` | Отключиться | `destroyPlayer(guildId)` |
## 3. Сохранение состояния
Аудиосессии эфемерны.
- **Временное состояние:** Активный аудиопоток (Теряется при отключении).
- **Постоянное состояние:** Очередь / Плейлист (Сохраняется в Контроллере до перезапуска).
> [!TIP]
> **Устойчивость:** Разделяйте логику _Очереди_ и логику _Голосового соединения_. Это позволяет боту переподключаться без потери плейлиста пользователя.
## 4. Пример реализации
```typescript
// lib/MusicController.ts
class MusicController {
private players = new Map<string, AudioPlayer>();
getPlayer(guildId: string): AudioPlayer {
if (!this.players.has(guildId)) {
this.players.set(guildId, new AudioPlayer());
}
return this.players.get(guildId);
}
destroyPlayer(guildId: string) {
this.players.get(guildId)?.disconnect();
this.players.delete(guildId);
}
}
```
---
**См. также:**
- [Руководство Discord.js Voice](https://discordjs.guide/voice/)