Музыкальный бот для голосовых каналов Discord
Если вы ставили музыкального бота года три назад и с тех пор не трогали — он почти наверняка сломался. YouTube несколько раз за последние годы менял механизм подписи и выдачи потоков, старые связки на голом ytdl-core или древнем lavaplayer без патчей сыплют 403 и обрывают трек через пять секунд после старта. Разберём, что реально работает сейчас, как поднять бота самому на Lavalink, чем это отличается от готового сервиса и на что обратить внимание с правами на воспроизведение — тема скользкая, но обходить её молчанием было бы нечестно.
Содержание
Почему старые музыкальные боты сломались
YouTube не даёт стабильного публичного API для получения аудиопотока — все музыкальные боты так или иначе идут в обход, эмулируя поведение официального клиента (веб, Android, iOS) и расшифровывая подпись signatureCipher на лету. Раз в несколько месяцев YouTube меняет алгоритм обфускации, и все библиотеки, которые не обновляются активно, отваливаются разом: то 410 Gone, то бесконечный 403 Forbidden, то трек грузится, но обрывается на середине.
Вторая, более свежая проблема — PoToken (proof-of-origin token). С 2024 года YouTube всё активнее требует его для части клиентских типов: без токена сервер либо режет битрейт до почти нерабочего, либо сразу отдаёт ошибку. PoToken генерируется через эмуляцию браузерного окружения (BotGuard/JS-челлендж), и библиотеки, которые не умеют его выпускать, для многих видео просто перестают работать — особенно для музыки с активной защитой от ботов.
Отсюда практический вывод: любой проект, который не обновлялся последние полгода-год (включая многие туториалы в интернете), скорее всего не взлетит из коробки. Дальше — что реально держится на плаву.
Lavalink — ядро, на котором сейчас строят рабочих ботов
Lavalink — отдельный Java-сервер для стриминга аудио, к которому бот подключается по WebSocket и просто просит "играй этот трек". Сам Lavalink не занимается взломом YouTube — это делают плагины поверх него, и именно плагины сейчас обновляются быстрее всего, потому что за ними стоит активное сообщество, а не один разработчик.
Связка, которая на практике работает стабильно:
- Lavalink v4 — сам аудио-сервер (последняя мажорная ветка, старые v3-конфиги и часть плагинов с ней несовместимы).
- youtube-source (плагин от topi314) — заменяет встроенную в старый lavaplayer YouTube-экстракцию, которая официально признана нерабочей и удалена из ядра Lavalink начиная с v4. Плагин умеет несколько клиентских стратегий (WEB, ANDROID_MUSIC, TVHTML5EMBEDDED и т.д.) и поддерживает PoToken через отдельный генератор.
- LavaSrc — добавляет резолвинг ссылок Spotify, Apple Music, Deezer и Yandex Music: сам трек с этих площадок не стримится (у них нет публичного стрим-API для ботов), но плагин находит по названию и исполнителю совпадение на YouTube/SoundCloud и играет оттуда. Это стоит понимать сразу — "плей по ссылке Spotify" не значит "стрим со Spotify".
Если делать бота с нуля и без Lavalink кажется избыточным, для небольших серверов подойдёт discord-player (npm install discord-player @discord-player/extractor) — обёртка на discord.js, которая тоже использует youtube-source под капотом через discord-player-youtubei, но не требует отдельного Java-процесса. Плюс — проще развернуть на одном VPS вместе с самим ботом. Минус — меньше гибкости при масштабировании на несколько серверов и отсутствие балансировки между нодами, которую даёт Lavalink.
Нужен игровой сервер?
MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.
Создать серверУстановка Lavalink-сервера на VPS
Понадобится Java 17+ и отдельная директория под сервер. Если бот ещё не поднят вообще — начните с базовой установки Discord-бота на VPS, музыкальный функционал добавляется поверх уже живущего 24/7 процесса.
sudo apt update && sudo apt install -y openjdk-17-jre-headless
mkdir -p /opt/lavalink/plugins && cd /opt/lavalink
wget https://github.com/lavalink-devs/Lavalink/releases/latest/download/Lavalink.jar
Скачайте jar-файлы плагинов youtube-source и LavaSrc с их GitHub Releases в /opt/lavalink/plugins/, затем настройте application.yml:
server:
port: 2333
lavalink:
server:
password: "сложный_пароль_сервера"
sources:
youtube: false # встроенный источник отключаем — его больше нет в v4
soundcloud: true
plugins:
- dependency: "dev.lavalink.youtube:youtube-plugin:1.11.4"
- dependency: "com.github.topi314.lavasrc:lavasrc-plugin:4.4.0"
plugins:
youtube:
enabled: true
clients: ["WEB", "ANDROID_MUSIC", "TVHTML5EMBEDDED"]
lavasrc:
providers:
- "ytsearch:\"%ISRC%\""
- "ytsearch:%QUERY%"
spotify:
clientId: "ваш_spotify_client_id"
clientSecret: "ваш_spotify_client_secret"
Версии плагинов уточняйте на момент установки — обновляются часто, и старая версия youtube-source может снова упереться в свежую блокировку. Запуск:
java -jar Lavalink.jar
Для автозапуска — отдельный systemd-юнит lavalink.service с Restart=on-failure: на нагруженных инстансах после долгого аптайма у Lavalink случается течь памяти, и плановый перезапуск не помешает.
Бот на discord.js + lavalink-client: базовые команды
Сторона Discord-бота — обычный discord.js-проект, который просто отправляет команды на Lavalink через клиентскую библиотеку lavalink-client:
npm install discord.js lavalink-client dotenv
const { Client, GatewayIntentBits } = require('discord.js');
const { LavalinkManager } = require('lavalink-client');
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates],
});
client.lavalink = new LavalinkManager({
nodes: [{
authorization: process.env.LAVALINK_PASSWORD,
host: '127.0.0.1',
port: 2333,
id: 'main',
}],
sendToShard: (guildId, payload) => client.guilds.cache.get(guildId)?.shard?.send(payload),
client: { id: process.env.CLIENT_ID },
});
client.on('raw', (d) => client.lavalink.sendRawData(d));
client.once('ready', () => client.lavalink.init({ id: client.user.id }));
Команда /play:
async function play(interaction) {
const query = interaction.options.getString('запрос');
const voiceChannel = interaction.member.voice.channel;
if (!voiceChannel) {
return interaction.reply({ content: 'Зайдите в голосовой канал.', ephemeral: true });
}
const player = client.lavalink.createPlayer({
guildId: interaction.guildId,
voiceChannelId: voiceChannel.id,
textChannelId: interaction.channelId,
selfDeaf: true,
});
await player.connect();
const res = await player.search({ query, source: 'ytsearch' }, interaction.user);
if (!res.tracks.length) {
return interaction.reply({ content: 'Ничего не найдено.', ephemeral: true });
}
await player.queue.add(res.tracks[0]);
if (!player.playing) await player.play();
await interaction.reply(`Добавлено в очередь: **${res.tracks[0].info.title}**`);
}
Остальные команды — /skip (player.skip()), /queue (список player.queue.tracks), /volume (player.setVolume(n), 0–150), /pause//resume, /stop (player.destroy()). Их логика тривиальна — сложный код уже внутри Lavalink, задача бота — дёргать нужные методы по слэш-командам. Подход к структуре команд и правам такой же, как в статье про Discord-бота для управления игровым сервером — регистрация через SlashCommandBuilder, ограничение по ролям там, где нужно (например, /stop не всем подряд на большом сервере).
Самостоятельный хостинг vs готовый сервис
Ниша "музыка в Discord" плотно занята готовыми ботами (Jockie Music, FredBoat в его нынешнем виде, десятки менее известных SaaS). Вопрос "писать своё или подключить готовое" зависит от того, что вам реально нужно:
| Свой бот на Lavalink | Готовый SaaS-бот | |
|---|---|---|
| Настройка | Час-два на первый запуск, дальше свободная кастомизация | Пять минут, добавил через инвайт-ссылку |
| Лимиты очереди/треков | Нет — сами решаете | Часто есть бесплатный лимит, платная подписка снимает |
| Уникальные команды под ваш сервер | Легко добавить (плейлисты сообщества, интеграция с RCON-статусом сервера) | Только то, что предусмотрел разработчик бота |
| Надёжность апдейтов при поломке YouTube | Ваша ответственность — следить за релизами youtube-source | Ответственность разработчика бота (но и зависимость от него) |
| Стоимость | VPS ~$5-10/мес (можно тот же, где крутится игровой сервер, если ресурсов хватает) | Часто бесплатно с рекламой/лимитами, премиум $3-10/мес |
| Приватность и контроль данных | Полный — всё на вашей инфраструктуре | Данные и логи на серверах стороннего сервиса |
Практичный ориентир: для небольшого дружеского сервера готовый бот избавляет от возни. Для игрового комьюнити, где музыкальный бот — часть общей инфраструктуры (тот же VPS, что и игровой сервер плюс бот со статистикой), свой инстанс на Lavalink окупается независимостью от чужих даунтаймов и лимитов — особенно если структура голосовых каналов сервера уже продумана, как в статье про структуру каналов Discord-сообщества.
Права на воспроизведение музыки в голосовом канале
Это тот пункт, где стоит быть честным, а не делать вид, что вопроса не существует. Технически музыкальный бот, который тянет аудио с YouTube в обход официального API, работает не по условиям использования YouTube — там прямо запрещено извлекать поток за пределами их собственных приложений. На практике для приватных некоммерческих Discord-серверов это массово игнорируемая серая зона: миллионы ботов так работают годами, и претензии со стороны правообладателей на уровне отдельного небольшого сервера — редкость.
Риски скорее технические, чем юридические, и они реальны:
- Ваш IP может получить троттлинг или временный бан от YouTube, если бот активно используется — это проявляется как раз в виде тех самых
403. Отдельный VPS с чистым IP под Lavalink снижает риск по сравнению с ботом, запущенным из дома на том же IP, с которого вы сами смотрите YouTube. - Аккаунт, если используется OAuth/cookie-авторизация (некоторые сборки youtube-source позволяют войти под YouTube-аккаунтом для более стабильного доступа) — рискует получить ограничение самого аккаунта, а не только IP. Заводите под это отдельный аккаунт, не привязанный к личному.
- Spotify/Apple Music/Deezer официально не дают транслировать чужой трек третьим лицам — поэтому LavaSrc и подобные плагины ищут совпадение на YouTube, а не стримят напрямую с этих сервисов. Ссылка на Spotify — просто удобный способ найти трек по метаданным, не более.
- Если сервер публичный, крупный и потенциально коммерческий (донаты, реклама, монетизация) — риски выше, и стоит рассматривать честные альтернативы: официальные Spotify/YouTube Music виджеты со ссылкой вместо стрима внутри канала, либо лицензированные библиотеки роялти-фри музыки для фонового звука.
Универсального "безопасного на 100%" решения тут нет — это компромисс, который выбирает администратор сервера сам, оценивая масштаб и риски. Технический совет один: не размещайте музыкального бота на том же аккаунте/IP, который вы бережёте для чего-то важного.
Нужен игровой сервер?
MAATRIX GAMES — 45+ игр, деплой за минуты, DDoS-защита, автобэкапы. Тарифы от 399 ₽/мес.
Создать серверЧастые вопросы
Можно ли обойтись без Lavalink и просто скачивать треки через yt-dlp перед проигрыванием?
Технически да, но это медленнее (нужно сначала докачать файл целиком или в буфер) и требует держать yt-dlp актуальным вручную — та же проблема с поломками, что и у старых библиотек, только без готовых плагинов-фиксов сообщества Lavalink.
Почему бот подключается к голосовому каналу, но звука нет?
Чаще всего не хватает ffmpeg в системе (для Lavalink не нужен — он сам транскодирует, но нужен для discord-player) либо не установлен пакет @discordjs/opus или opusscript на стороне Node.js-бота.
Ошибка This video is unavailable для трека, который отлично играет в браузере.
Обычно возрастное ограничение или региональная блокировка на стороне YouTube для клиента, который эмулирует youtube-source. Попробуйте другой clients в конфиге плагина (ANDROID_MUSIC часто обходит то, что блокирует WEB) — универсального клиента, который проходит везде, не существует.
Нужен ли отдельный VPS под Lavalink или можно на том же, где крутится игровой сервер?
Можно на том же — Lavalink не требователен к CPU (транскодирование аудио лёгкое), важнее свободная память под JVM (от 512 МБ) и то, что игровой сервер не упрётся в лимиты по сети из-за параллельного стриминга музыки на нагруженном комьюнити.
LavaSrc обязателен, если нужен только YouTube без Spotify-ссылок?
Нет, для чистого YouTube достаточно youtube-source. LavaSrc ставьте, только если реально нужны ссылки со Spotify/Apple Music/Deezer/Yandex Music как удобный ввод для пользователей.