summaryrefslogtreecommitdiffhomepage
path: root/.rules
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-04-02 02:22:36 +0900
committerAdam Malczewski <[email protected]>2026-04-02 02:22:36 +0900
commit738732db20d827c4a305434a82c6464f3ebaf65d (patch)
treebaa0c9eddc72660342d3d3266ed5262f100030a3 /.rules
downloadmusic-bot-738732db20d827c4a305434a82c6464f3ebaf65d.tar.gz
music-bot-738732db20d827c4a305434a82c6464f3ebaf65d.zip
project setupHEADmain
Diffstat (limited to '.rules')
-rw-r--r--.rules/plan/research.md619
1 files changed, 619 insertions, 0 deletions
diff --git a/.rules/plan/research.md b/.rules/plan/research.md
new file mode 100644
index 0000000..5ff33dd
--- /dev/null
+++ b/.rules/plan/research.md
@@ -0,0 +1,619 @@
+# Discord Music Bot Development — Tool Research Report
+
+> **Query:** What tools are needed to develop a Discord bot that streams YouTube audio to voice channels, with queue management via user commands — preferring JavaScript/TypeScript.
+
+---
+
+## Executive Summary
+
+Building a Discord music bot that streams YouTube audio to voice channels in 2025 requires a carefully chosen stack due to YouTube's frequently changing API restrictions and the deprecation of several once-popular libraries. The recommended modern stack centers on **Discord.js v14** (Discord API framework), **@discordjs/voice** (low-level voice layer), a high-level music framework (**discord-player** or **DisTube**), and a YouTube extraction backend using **youtubei.js** (via `discord-player-youtubei` extractor or DisTube's plugin system). For large-scale or production bots, **Lavalink v4** (a Java-based audio server) offers superior performance. TypeScript is natively supported by all recommended libraries and is strongly advisable.
+
+---
+
+## Architecture Overview
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│ Discord API (WebSocket + REST) │
+└────────────────────────┬────────────────────────────────────────┘
+ │
+ ┌────────▼────────┐
+ │ discord.js │ ← Bot framework (JS/TS)
+ │ v14 │
+ └────────┬────────┘
+ │
+ ┌──────────────┴───────────────┐
+ │ │
+ ┌────────▼──────────┐ ┌──────────▼──────────┐
+ │ Music Framework │ │ @discordjs/voice │
+ │ (discord-player │───────▶│ (low-level voice │
+ │ OR DisTube) │ │ connections) │
+ └────────┬──────────┘ └──────────┬──────────┘
+ │ │
+ ┌────────▼──────────┐ ┌──────────▼──────────┐
+ │ YouTube Extractor│ │ Audio Processing │
+ │ (youtubei.js / │ │ FFmpeg + Opus │
+ │ yt-dlp) │ │ (encoding/decoding)│
+ └───────────────────┘ └─────────────────────┘
+
+ ─── OR, for large bots ───
+
+┌──────────────────────────────────────────────────────────────────┐
+│ Lavalink v4 (Java server) │
+│ Lavaplayer + youtube-source plugin → streams audio via WS │
+│ Node.js client: lavalink-client npm package │
+└──────────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## Component 1: Discord Bot Framework — Discord.js v14
+
+**Repository:** [discordjs/discord.js](https://github.com/discordjs/discord.js)
+**NPM:** `discord.js`
+**Language:** TypeScript (ships `.d.ts` declarations)
+
+Discord.js is the overwhelmingly dominant Discord API library for Node.js, offering complete coverage of the Discord REST API and Gateway WebSocket events.[^1] v14 introduced native TypeScript support, slash command builders, interaction handling, and the `GatewayIntentBits` enum.
+
+### Required Intents for a Music Bot
+
+```typescript
+import { Client, GatewayIntentBits } from 'discord.js';
+
+const client = new Client({
+ intents: [
+ GatewayIntentBits.Guilds, // required for slash commands
+ GatewayIntentBits.GuildVoiceStates, // required for voice channel management
+ GatewayIntentBits.GuildMessages, // for prefix commands (if used)
+ GatewayIntentBits.MessageContent, // PRIVILEGED: required to read message content
+ ],
+});
+```
+
+> **Note:** `MessageContent` is a **privileged intent** — it must be enabled manually in the [Discord Developer Portal](https://discord.com/developers/applications). For a slash-command-only bot, it's not needed.
+
+### Slash Command Structure
+
+Modern bots use slash commands (`/play`, `/skip`, `/queue`, etc.) registered via the REST API. The recommended structure:
+
+```
+src/
+ commands/
+ play.ts
+ skip.ts
+ queue.ts
+ stop.ts
+ events/
+ ready.ts
+ interactionCreate.ts
+ deploy-commands.ts
+ index.ts
+```
+
+---
+
+## Component 2: Voice Layer — @discordjs/voice
+
+**Repository:** [discordjs/voice](https://github.com/discordjs/voice)
+**NPM:** `@discordjs/voice`
+
+This is the **official, low-level Discord voice library** from the discord.js team.[^2] It handles:
+- Joining and leaving voice channels
+- Creating and managing audio players
+- Creating audio resources from streams
+- Subscribing voice connections to audio players
+
+It is the backbone used by all higher-level music frameworks (DisTube, discord-player).
+
+### Key APIs
+
+```typescript
+import {
+ joinVoiceChannel,
+ createAudioPlayer,
+ createAudioResource,
+ AudioPlayerStatus,
+ VoiceConnectionStatus,
+} from '@discordjs/voice';
+```
+
+### Required Peer Dependencies
+
+From the official README[^2], you need to install one option from each category:
+
+| Category | Recommended | Alternatives | Purpose |
+|---|---|---|---|
+| **Opus** | `@discordjs/opus` | `opusscript`, `mediaplex` | Audio encoding (Opus codec for Discord) |
+| **Encryption** | `sodium-native` | `sodium`, `libsodium-wrappers`, `tweetnacl` | Encrypting voice data |
+| **FFmpeg** | System FFmpeg | `ffmpeg-static` (npm) | Media transcoding |
+
+```bash
+npm install @discordjs/voice @discordjs/opus sodium-native
+# Install FFmpeg: sudo apt install ffmpeg (Linux) or brew install ffmpeg (Mac)
+# OR: npm install ffmpeg-static
+```
+
+> **Important:** As of 2024, Node.js 16+ is required by `@discordjs/voice`; Node.js 20+ is recommended for modern discord.js projects.[^3]
+
+---
+
+## Component 3: Music Frameworks (High-Level Abstractions)
+
+Rather than building queue management, audio resource handling, and track searching from scratch, use one of these frameworks that sit on top of `@discordjs/voice`.
+
+### Option A: discord-player (Recommended for TypeScript/Flexibility)
+
+**Repository:** [Androz2091/discord-player](https://github.com/Androz2091/discord-player)
+**NPM:** `discord-player` + `@discord-player/extractor`
+**Docs:** [discord-player.js.org](https://discord-player.js.org)
+
+discord-player is a robust, TypeScript-first music framework providing:[^4]
+- Built-in queue management with repeat, shuffle, volume control
+- 64+ built-in audio filter presets
+- Extensible Extractor API (pluggable source backends)
+- `useMainPlayer()` hooks for clean code patterns
+- Automatic voice state handling
+- IP rotation support
+- Object-oriented design with events system
+
+```bash
+npm install discord-player @discord-player/extractor mediaplex
+```
+
+```typescript
+import { Player } from 'discord-player';
+import { DefaultExtractors } from '@discord-player/extractor';
+import { YoutubeiExtractor } from 'discord-player-youtubei';
+
+const player = new Player(client);
+await player.extractors.loadMulti(DefaultExtractors);
+// Register the YouTube extractor (see Component 4 below)
+await player.extractors.register(YoutubeiExtractor, {});
+
+player.events.on('playerStart', (queue, track) => {
+ queue.metadata.channel.send(`▶️ Now playing: **${track.cleanTitle}**`);
+});
+```
+
+**Play command example:**
+```typescript
+import { useMainPlayer } from 'discord-player';
+
+const player = useMainPlayer();
+const { track } = await player.play(voiceChannel, query, {
+ nodeOptions: { metadata: interaction },
+});
+await interaction.followUp(`✅ Enqueued: **${track.cleanTitle}**`);
+```
+
+> **Note:** discord-player v6+ uses `discord-voip` (a fork of `@discordjs/voice`) as its internal voice layer.[^4]
+
+---
+
+### Option B: DisTube (Batteries-Included)
+
+**Repository:** [skick1234/DisTube](https://github.com/distubejs/distube)
+**NPM:** `distube`
+**Docs:** [distube.js.org](https://distube.js.org)
+
+DisTube is a high-level, all-in-one music bot library offering more out-of-the-box functionality:[^5]
+- Built-in queue, playlist, and voice connection management
+- 20+ built-in audio filters (bassboost, nightcore, echo, karaoke, etc.)
+- Plugin system supporting YouTube, Spotify, SoundCloud, Bandcamp, and 700+ other sites
+- Full TypeScript support
+- Requires `discord.js v14` and `@discordjs/voice`
+
+```bash
+npm install distube @discordjs/voice @discordjs/opus
+```
+
+```javascript
+import { DisTube } from 'distube';
+
+const distube = new DisTube(client, { emitNewSongOnly: true });
+
+distube.on('playSong', (queue, song) =>
+ queue.textChannel?.send(`▶️ Playing \`${song.name}\` - \`${song.formattedDuration}\``)
+);
+
+// Play command handler
+distube.play(message.member!.voice.channel!, query, {
+ message,
+ textChannel: message.channel,
+ member: message.member!,
+});
+```
+
+### Option A vs. B Comparison
+
+| Feature | discord-player | DisTube |
+|---|---|---|
+| Abstraction Level | Medium-High | High |
+| TypeScript Quality | Excellent | Good |
+| Queue Management | Built-in | Built-in |
+| Audio Filters | 64+ presets | 20+ built-in |
+| Plugin/Extractor System | Extractor API | Plugin system |
+| Customizability | High | Moderate |
+| Ease of Setup | Moderate | Simple |
+| Supports 700+ sites | Via extractors | Via plugins (yt-dlp plugin) |
+| Community Size | Large | Large |
+| Voice Library | `discord-voip` (fork) | `@discordjs/voice` |
+
+**Recommendation:** Use **discord-player** for TypeScript-first, flexible development. Use **DisTube** if you want maximum out-of-the-box features with minimal setup.
+
+---
+
+## Component 4: YouTube Audio Extraction — The Critical Piece
+
+YouTube is the most complex component due to frequent API changes and the **deprecation of ytdl-core** in August 2024.[^6]
+
+### ⚠️ What NOT to Use Anymore
+
+| Library | Status | Reason |
+|---|---|---|
+| `ytdl-core` | **Deprecated (Aug 2024)** | No longer maintained; frequently broken |
+| `@distube/ytdl-core` | **Deprecated** | Maintenance stopped; recommends migration to youtubei.js |
+| `play-dl` | **Archived (Jun 2025)** | Repository archived; no new updates |
+
+### ✅ Current Recommended Options
+
+#### Option 1: `discord-player-youtubei` (Best for discord-player)
+
+**Repository:** [retrouser955/discord-player-youtubei](https://github.com/retrouser955/discord-player-youtubei)
+**NPM:** `discord-player-youtubei`
+
+Built on top of `youtubei.js` (YouTube's InnerTube API), this extractor plugin is the current community standard for discord-player YouTube support.[^7]
+
+```bash
+npm install discord-player-youtubei
+```
+
+```typescript
+import { YoutubeiExtractor } from 'discord-player-youtubei';
+
+// Register once at startup - not in every command
+await player.extractors.register(YoutubeiExtractor, {
+ // Optional: authenticate with YouTube account for higher rate limits
+ // authentication: 'OAUTH_TOKEN'
+});
+```
+
+#### Option 2: `youtubei.js` (LuanRT) — Direct Usage
+
+**Repository:** [LuanRT/YouTube.js](https://github.com/LuanRT/YouTube.js)
+**NPM:** `youtubei.js`
+**Docs:** [ytjs.dev](https://ytjs.dev)
+
+A full JavaScript client for YouTube's private InnerTube API. Enables searching, metadata fetching, and stream URL extraction. Used under the hood by `discord-player-youtubei` and referenced as the recommended successor to `ytdl-core`.[^6]
+
+#### Option 3: `yt-dlp` (via subprocess — Most Robust)
+
+**Binary:** [yt-dlp/yt-dlp](https://github.com/yt-dlp/yt-dlp) (Python, installed separately)
+**Node wrapper:** `yt-dlp-wrap` npm package
+
+`yt-dlp` is a Python CLI tool that is the most actively maintained YouTube downloader. It handles YouTube's anti-bot measures most robustly.[^8] It can be called from Node.js as a subprocess:
+
+```typescript
+import { spawn } from 'child_process';
+import { createAudioResource, StreamType } from '@discordjs/voice';
+
+function getYtDlpStream(url: string) {
+ const proc = spawn('yt-dlp', [
+ '-f', 'bestaudio',
+ '--no-playlist',
+ '-o', '-', // output to stdout
+ url,
+ ], { stdio: ['ignore', 'pipe', 'ignore'] });
+
+ return createAudioResource(proc.stdout, {
+ inputType: StreamType.Arbitrary,
+ });
+}
+```
+
+> **Note:** Requires `yt-dlp` binary to be installed on the host system (`pip install yt-dlp` or system package manager). Can also be used via DisTube's `@distube/yt-dlp` plugin.
+
+#### Option 4: DisTube YouTube Plugin
+
+For DisTube users, the official `@distube/youtube` plugin or the `@distube/yt-dlp` plugin handles YouTube extraction natively within the DisTube ecosystem.[^5]
+
+---
+
+## Component 5: Lavalink — For Production/Large-Scale Bots
+
+**Repository:** [lavalink-devs/Lavalink](https://github.com/lavalink-devs/Lavalink)
+**Docs:** [lavalink.dev](https://lavalink.dev)
+**Version:** v4 (stable)
+
+Lavalink is a **standalone Java audio server** that offloads all audio processing from your bot's Node.js process.[^9] It communicates with your bot over WebSocket and is used in production by major bots (FredBoat, Dyno, etc.).
+
+### Why Lavalink?
+
+- **Performance**: Audio transcoding happens in a separate JVM process — your bot stays fast
+- **Scalability**: Supports multiple nodes for horizontal scaling
+- **Seeking**: Built-in seeking support
+- **Volume control**: Precise volume control
+- **Filters**: Equalizer, timescale, tremolo, vibrato, rotation, distortion filters
+- **YouTube support**: Via the official `youtube-source` plugin for Lavaplayer[^10]
+
+### Requirements
+
+- **Java 17 LTS or newer** (runs as a separate process)
+- Your Node.js bot connects as a client via WebSocket
+
+### Setup Overview
+
+1. **Download** the Lavalink JAR from [GitHub Releases](https://github.com/lavalink-devs/Lavalink/releases)
+2. **Configure** `application.yml`:
+```yaml
+server:
+ port: 2333
+lavalink:
+ server:
+ password: "your-strong-password"
+plugins:
+ youtube:
+ enabled: true
+ clients: ["MUSIC", "ANDROID_VR", "WEB", "WEBEMBEDDED"]
+```
+3. **Run**: `java -jar Lavalink.jar`
+4. **Connect** your Node.js bot using `lavalink-client`:
+
+```bash
+npm install lavalink-client
+```
+
+```typescript
+import { LavalinkManager } from 'lavalink-client';
+
+client.lavalink = new LavalinkManager({
+ nodes: [{
+ authorization: 'your-strong-password',
+ host: 'localhost',
+ port: 2333,
+ id: 'main-node',
+ }],
+ sendToShard: (guildId, payload) =>
+ client.guilds.cache.get(guildId)?.shard?.send(payload),
+ client: { id: process.env.CLIENT_ID!, username: 'MusicBot' },
+});
+
+client.on('raw', d => client.lavalink.sendRawData(d));
+client.on('ready', () => client.lavalink.init({ ...client.user! }));
+```
+
+### Node.js Lavalink Clients
+
+| Package | Notes |
+|---|---|
+| `lavalink-client` | Most actively maintained; full TypeScript support |
+| `shoukaku` | Performant, popular choice |
+| `lavacord` | Lightweight; [lavacord.js.org](https://lavacord.js.org) |
+| `moonlink.js` | Alternative with good TS support |
+
+### Lavalink YouTube Source Plugin
+
+The official [`youtube-source`](https://github.com/lavalink-devs/youtube-source) plugin for Lavaplayer uses multiple InnerTube clients to maximize success rate against YouTube's anti-bot measures.[^10] Configure in `application.yml` as shown above.
+
+---
+
+## Component 6: Development Toolchain
+
+### TypeScript Setup
+
+```bash
+npm install -D typescript @types/node ts-node tsup
+```
+
+**Recommended `tsconfig.json`:**
+```json
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "commonjs",
+ "lib": ["ES2022"],
+ "outDir": "./dist",
+ "rootDir": "./src",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "resolveJsonModule": true
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "dist"]
+}
+```
+
+**Build tool:** Use **`tsup`** (fast, zero-config TypeScript bundler) or plain `tsc`.
+
+### Environment Variables
+
+Use **`dotenv`** for managing secrets:
+```bash
+npm install dotenv
+```
+
+```
+# .env
+DISCORD_TOKEN=your_bot_token
+CLIENT_ID=your_application_id
+GUILD_ID=optional_test_guild_id
+```
+
+### Project Scaffolding Options
+
+| Template | Description |
+|---|---|
+| [KevinNovak/Discord-Bot-TypeScript-Template](https://github.com/KevinNovak/Discord-Bot-TypeScript-Template) | Production-ready TS template with PM2/Docker support |
+| [MericcaN41/discordjs-v14-template-ts](https://github.com/MericcaN41/discordjs-v14-template-ts) | Handlers, MongoDB, permissions, cooldowns |
+
+---
+
+## Component 7: Persistence & State Management
+
+For queue persistence across restarts or advanced features:
+
+| Need | Tool |
+|---|---|
+| Simple key-value / queue state | **Redis** (`ioredis` npm) |
+| Relational data (playlists, server settings) | **PostgreSQL** via `pg` or **SQLite** via `better-sqlite3` |
+| ORM | **Prisma** (excellent TypeScript support) |
+| In-memory only (simplest) | Native `Map<string, Queue>` (no persistence) |
+
+For most bots, an in-memory `Map` per guild is sufficient for queue state. Persist only playlists/settings to a database.
+
+---
+
+## Component 8: Deployment & Hosting
+
+### Minimum Hardware Requirements
+
+- **RAM:** 512 MB minimum; 1 GB recommended (2+ GB if running Lavalink on the same host)
+- **CPU:** 1 vCPU minimum
+- **OS:** Ubuntu 22.04+ LTS recommended
+- **Java:** Required only if running Lavalink on the same host (Java 17+)
+
+### Process Management
+
+**PM2** (simpler, Node.js-native):
+```bash
+npm install -g pm2
+pm2 start dist/index.js --name music-bot
+pm2 save && pm2 startup
+```
+
+**Docker** (more portable, production-grade):
+```dockerfile
+FROM node:20-alpine
+WORKDIR /app
+RUN apk add --no-cache ffmpeg python3 py3-pip && pip3 install yt-dlp
+COPY package*.json ./
+RUN npm ci --only=production
+COPY dist/ ./dist/
+CMD ["node", "dist/index.js"]
+```
+
+Use `docker-compose.yml` to run the bot + Lavalink together.
+
+### Hosting Providers
+
+| Provider | Type | Notes |
+|---|---|---|
+| DigitalOcean Droplet | VPS | $6/mo for 1GB RAM; full control |
+| Linode/Akamai | VPS | Similar to DigitalOcean |
+| Hetzner Cloud | VPS | Cheapest per-GB in EU |
+| Railway.app | PaaS | Easy deploy, free tier available |
+| Fly.io | PaaS | Free tier with containers |
+| VPS self-hosted | VPS | Maximum control |
+
+> **Avoid serverless platforms** (Lambda, Vercel) — Discord bots require persistent WebSocket connections.
+
+---
+
+## Full Recommended Stack Summary
+
+### For a Starter/Personal Bot (Simpler)
+
+```bash
+npm install discord.js @discordjs/voice discord-player @discord-player/extractor \
+ discord-player-youtubei mediaplex ffmpeg-static sodium dotenv
+npm install -D typescript @types/node ts-node tsup
+```
+
+| Layer | Choice |
+|---|---|
+| Discord API | `discord.js` v14 |
+| Voice | `@discordjs/voice` (via discord-player internally) |
+| Music Framework | `discord-player` v6+ |
+| YouTube Backend | `discord-player-youtubei` (uses `youtubei.js`) |
+| Opus Encoding | `mediaplex` |
+| FFmpeg | `ffmpeg-static` or system install |
+| Encryption | `sodium` |
+| Language | TypeScript |
+| Deployment | PM2 on a VPS |
+
+### For a Production Bot (Large Scale)
+
+```bash
+npm install discord.js lavalink-client dotenv
+npm install -D typescript @types/node tsup
+# On server: Java 17+, then run Lavalink JAR
+```
+
+| Layer | Choice |
+|---|---|
+| Discord API | `discord.js` v14 |
+| Voice/Streaming | Lavalink v4 (Java server) + `lavalink-client` |
+| YouTube Backend | Lavalink `youtube-source` plugin |
+| Language | TypeScript |
+| Deployment | Docker Compose (bot + Lavalink) on VPS |
+
+---
+
+## Legal & ToS Considerations
+
+> ⚠️ **Important:** Streaming YouTube audio directly to Discord may violate [YouTube's Terms of Service](https://www.youtube.com/static?template=terms), specifically Section 5.B which prohibits downloading content except through YouTube's explicitly permitted mechanisms.
+
+Key considerations:
+- **Private bots** (in your own server) face significantly less legal risk than public bots
+- Two of the largest music bots — **Groovy** and **Rythm** — were shut down in 2021 following legal pressure from YouTube/Google
+- YouTube's Music API and official embeds are the ToS-compliant alternatives
+- Bots using Spotify typically use Spotify's search to find the song name, then stream the YouTube equivalent (since Spotify doesn't provide audio streams)
+- Consider using **SoundCloud** or other platforms with permissive APIs as alternatives or fallbacks
+
+---
+
+## Key Repositories Summary
+
+| Repository | Purpose | Language |
+|---|---|---|
+| [discordjs/discord.js](https://github.com/discordjs/discord.js) | Discord API client library | TypeScript |
+| [discordjs/voice](https://github.com/discordjs/voice) | Discord voice connections | TypeScript |
+| [Androz2091/discord-player](https://github.com/Androz2091/discord-player) | High-level music framework | TypeScript |
+| [skick1234/DisTube](https://github.com/distubejs/distube) | All-in-one music library | TypeScript |
+| [retrouser955/discord-player-youtubei](https://github.com/retrouser955/discord-player-youtubei) | YouTube extractor for discord-player | TypeScript |
+| [LuanRT/YouTube.js](https://github.com/LuanRT/YouTube.js) | InnerTube API client | TypeScript |
+| [lavalink-devs/Lavalink](https://github.com/lavalink-devs/Lavalink) | Audio server for large bots | Java |
+| [lavalink-devs/youtube-source](https://github.com/lavalink-devs/youtube-source) | YouTube plugin for Lavalink | Java |
+| [lavalink-devs/lavalink-client](https://github.com/lavalink-devs/lavalink-client) | Node.js Lavalink client | TypeScript |
+| [yt-dlp/yt-dlp](https://github.com/yt-dlp/yt-dlp) | YouTube downloader CLI | Python |
+
+---
+
+## Confidence Assessment
+
+| Finding | Confidence | Notes |
+|---|---|---|
+| discord.js v14 is the standard | **Very High** | Unambiguous community consensus |
+| `ytdl-core` is deprecated (Aug 2024) | **Very High** | Confirmed via npm README + GitHub |
+| `play-dl` is archived (Jun 2025) | **Very High** | Confirmed via GitHub repo status |
+| `discord-player-youtubei` is recommended | **High** | Multiple community sources + GitHub |
+| `discord-player` uses `discord-voip` fork | **High** | Confirmed via official README[^4] |
+| Lavalink v4 is stable | **Very High** | Confirmed via official README[^9] |
+| Lavalink youtube-source uses InnerTube | **Very High** | Confirmed via repo README[^10] |
+| `mediaplex` is recommended over `@discordjs/opus` for discord-player | **High** | Stated in discord-player README[^4] |
+| Legal risks around YouTube streaming | **High** | Based on precedent (Groovy/Rythm) + YouTube ToS |
+
+---
+
+## Footnotes
+
+[^1]: [discordjs/discord.js](https://github.com/discordjs/discord.js) — Official Discord.js repository; docs at [discord.js.org](https://discord.js.org)
+
+[^2]: [discordjs/voice README.md](https://github.com/discordjs/voice/blob/main/README.md) — Lists all required optional dependencies (encryption, Opus, FFmpeg)
+
+[^3]: [discordjs/voice installation docs](https://discordjs.guide/voice) — Node.js 16+ required; 20+ recommended
+
+[^4]: [Androz2091/discord-player README.md](https://github.com/Androz2091/discord-player/blob/master/README.md) — Full setup instructions, mediaplex recommendation, FFmpeg notes
+
+[^5]: [skick1234/DisTube README.md](https://github.com/distubejs/distube/blob/main/README.md) — Official README; plugin architecture; install `distube @discordjs/voice @discordjs/opus`
+
+[^6]: [ytdl-core deprecation discussion](https://stackoverflow.com/questions/78824388/ytdl-core-is-returning-a-stream-with-nothing-in-it) — Community discussion on ytdl-core being broken; `@distube/ytdl-core` points to `youtubei.js` as successor; [npm @distube/ytdl-core](https://www.npmjs.com/package/@distube/ytdl-core)
+
+[^7]: [retrouser955/discord-player-youtubei GitHub](https://github.com/retrouser955/discord-player-youtubei) — YouTube extractor built on youtubei.js for discord-player v6/v7
+
+[^8]: [yt-dlp PyPI](https://pypi.org/project/yt-dlp/) — Most actively maintained YouTube downloader; regularly updated against YouTube's bot detection
+
+[^9]: [lavalink-devs/Lavalink README.md](https://github.com/lavalink-devs/Lavalink/blob/master/README.md) — v4 is stable; Java 17 required; used by FredBoat, Dyno in production
+
+[^10]: [lavalink-devs/youtube-source README.md](https://github.com/lavalink-devs/youtube-source) — YouTube plugin for Lavaplayer using multiple InnerTube clients for robustness