Files
ermnvldmr.com/services/docs/content/ru/quetza/guides/voice-features.md
T
deytenit b3638f4d63 fix: cyrillic fonts, dev certs, page head, and ru-text typography (#67)
🤖 PR generated for branch `fix/cyrillic-fonts-dev-certs-and-page-head`.

### Changes Summary
- **Fonts**: Add Cyrillic glyph subsets for Lato, EB Garamond, and Fira
Code.
- **Dev**: Support remote Root CA and encrypted dev CA key in
`.env.dev`.
- **UI & Kits**: Add size variant to `Breadcrumbs` component and enlarge
`PageHead` breadcrumbs with tuned collapse scroll threshold.
- **ESLint**: Add `no-hanging-particles` i18n & markdown typography rule
with auto-fixer.
- **Content & i18n**: Apply `ru-text` editorial and typography polish
(em dashes, number ranges, «ё» restoration, non-breaking spaces) across
`services/www` and `services/docs`.
2026-10-25 15:21:09 +03:00

3.0 KiB

title, weight
title weight
Голосовые функции 3

Цель: реализовать голосовое взаимодействие с изоляцией ресурсов по серверам (гильдиям) и корректным управлением аудиосессиями.

1. Изоляция ресурсов

Голосовые функции бота обязательно изолируются на уровне отдельного сервера (гильдии):

  • Архитектурный шаблон: контроллер хранит соответствие 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. Пример реализации

// 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);
  }
}

См. также: