{"id":23496315,"url":"https://github.com/firestone82/rustytunes","last_synced_at":"2026-05-16T00:08:03.194Z","repository":{"id":259981480,"uuid":"879901533","full_name":"Firestone82/RustyTunes","owner":"Firestone82","description":"Discord music and utility bot written in Rust, a school project in PvR. ","archived":false,"fork":false,"pushed_at":"2024-12-30T18:19:53.000Z","size":1845,"stargazers_count":3,"open_issues_count":11,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-15T13:54:59.611Z","etag":null,"topics":["bot","discord-bot","music-bot","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Firestone82.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-28T18:42:48.000Z","updated_at":"2024-12-30T18:19:56.000Z","dependencies_parsed_at":"2024-12-19T19:27:58.640Z","dependency_job_id":"72becbb2-de21-4f51-a786-00fac61f534a","html_url":"https://github.com/Firestone82/RustyTunes","commit_stats":null,"previous_names":["firestone82/rustytunes"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Firestone82/RustyTunes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Firestone82%2FRustyTunes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Firestone82%2FRustyTunes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Firestone82%2FRustyTunes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Firestone82%2FRustyTunes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Firestone82","download_url":"https://codeload.github.com/Firestone82/RustyTunes/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Firestone82%2FRustyTunes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30071895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T03:25:38.285Z","status":"ssl_error","status_checked_at":"2026-03-04T03:25:05.086Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","discord-bot","music-bot","rust"],"created_at":"2024-12-25T04:12:26.132Z","updated_at":"2026-05-16T00:08:03.187Z","avatar_url":"https://github.com/Firestone82.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg width=\"20%\" src=\"assets/icon-no-bg.png\" align=\"right\" alt=\"Icon\"\u003e\n\u003cbr\u003e\n\n# Project for PvR: Discord MusicBot in Rust\n- Author: Pavel Mikula (MIK0486)\n- Took approximately 40 hours\n\n## Project Theme\nThis project is a Discord bot developed in Rust, designed to play music in Discord voice channels. It uses libraries like `serenity` and `poise` for handling the Discord API, `songbird` for managing audio playback, `yt-dlp` for YouTube track streaming, and integrates with the Spotify Web API for Spotify URLs. The bot supports a full music queue, a local audio library, timed reminders, and several utility commands.\n\n## Project Requirements\n- Rust: The primary programming language for bot logic\n- Serenity + Poise: Discord API wrapper and command framework for Rust\n- Songbird: Voice and audio playback library for Discord\n- yt-dlp: For downloading and streaming audio from YouTube\n- SQLite (via sqlx): Persistent storage for guild settings and reminders\n- Spotify Web API: For resolving Spotify track / playlist URLs\n\n## Installation\n### Prerequisites\n- Installed rust from [rust-lang.org](https://www.rust-lang.org/tools/install)\n- Installed yt-dlp from [github.com/yt-dlp/yt-dlp](https://github.com/yt-dlp/yt-dlp)\n  - `yt-dlp` should be in the system PATH\n- Installed `ffmpeg` (in the system PATH) — used by yt-dlp for post-processing **and** by the bot's loudness analyzer to measure each track's integrated LUFS for cross-track volume normalization\n- YouTube Data API token from [Google Cloud Console](https://developers.google.com/youtube/registering_an_application)\n- Discord bot token from [Discord Developer Portal](https://discord.com/developers/applications)\n- (Optional) Spotify Client ID \u0026 Secret from [Spotify Developer Dashboard](https://developer.spotify.com/dashboard) — required for Spotify URL support\n- Installed CMAKE. Required for the [audiopus_sys](https://github.com/Lakelezz/audiopus_sys) library\n\n### Installation\n1. Clone this repository\n    ```bash\n    git clone https://github.com/Firestone82/RustyTunes.git\n    cd RustyTunes\n    ```\n2. Create a `.env` file in the root directory\n    ```bash\n    cp .env.example .env\n\n    # Edit the .env file with your Discord bot token, YouTube API key,\n    # and (optionally) Spotify client id and secret.\n    ```\n3. Setup database\n    ```bash\n    cargo install sqlx-cli\n    sqlx database create\n    sqlx migrate run\n     ```\n4. Install dependencies\n    ```bash\n   # yt-dlp\n   sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp\n   sudo chmod a+rx /usr/local/bin/yt-dlp\n\n   # ffmpeg (required by yt-dlp and by the loudness normalizer)\n   sudo apt-get install ffmpeg\n\n   # CMAKE\n   sudo apt-get install cmake\n    ```\n5. Build and run the bot\n    ```bash\n    cargo build --release\n    cargo run\n    ```\n\n## Usage\nAll commands are available as both **prefix commands** (default prefix `!`) and **slash commands** (`/`). Use `!help` or `/help` in Discord to list every command, or `!help \u003ccommand\u003e` for details on a specific one.\n\n## Features\n\n### Audio Sources\n- Play tracks and playlists from **YouTube** (direct URL or text search)\n- Play tracks and playlists from **Spotify** (URL — resolved to YouTube for playback)\n- Play files from a **local audio library** stored on the bot host\n- Stream user-uploaded **Discord attachments** (audio files)\n- Stream audio from **arbitrary direct URLs**\n\n### Playback Controls\n- `play \u003cquery|url\u003e` — play a track or playlist from YouTube or Spotify (appends to queue)\n- `playtop \u003cquery|url\u003e` — same as `play` but inserts at the front of the queue\n- `pause` / `resume` — pause and resume the current track\n- `skip [amount]` — skip the current track (or multiple at once)\n- `stop` — stop playback and clear the active track\n- `playing` — show the currently playing track\n- `volume [1-100]` — set the playback volume; append `!` (e.g. `volume 200!`) to opt into the extended 1–500 overdrive range\n- `normalize [on|off]` — toggle session-only cross-track loudness normalization (off by default, applies to every source once enabled, resets on restart)\n- `silent [on|off]` — suppress NowPlaying announcements for the session\n- `join` / `leave` — manually summon or dismiss the bot from your voice channel\n\n### Queue Management\n- `queue` — paginated queue listing (10 tracks per page) with navigation buttons\n- `clear` — remove every track from the queue\n- `remove \u003cindex\u003e` — remove a specific track from the queue by its 1-based index\n- `shuffle` — shuffle the current queue\n- `history` — show the last 10 played tracks with buttons to instantly replay any of them\n\n### Local Audio Library\nThe `local` command groups subcommands for managing audio files saved on the bot host:\n- `local download \u003curl\u003e [name]` — download an audio file from a URL into the library\n- `local upload [name]` — save an uploaded Discord attachment into the library\n- `local list` — list all saved local tracks\n- `local play [name]` — play a saved track by name (with autocomplete and an interactive picker)\n- `local rename \u003ctrack\u003e \u003cnew name\u003e` — rename a saved track\n- `local remove \u003ctrack\u003e` — delete a saved track from the library\n\n### Reminders / Notifications\nThe `notify` command (alias `remind`) lets users schedule timed reminders persisted to the database:\n- `notify me \u003cwhen\u003e \u003cmessage\u003e` — schedule a reminder for yourself\n- `notify you \u003cuser\u003e \u003cwhen\u003e \u003cmessage\u003e` — schedule a reminder for another user\n- `notify list` — list your pending reminders\n- `notify remove \u003cid\u003e` — cancel a pending reminder\n\n### Utility Commands\n- `wakeup \u003cuser\u003e [count]` — drags a user briefly between voice channels to grab their attention (also available as a right-click **WakeUp!** user context menu action)\n- `rename \u003cuser\u003e [new name]` — set another member's nickname (respects role hierarchy)\n- `uwu \u003ctext\u003e` — uwuify the given text\n- `uwu_me \u003ctext\u003e` — uwuify text and post it impersonating the author via webhook\n- `help [command]` — built-in help listing and per-command detail\n\n### Quality-of-Life Behaviour\n- **Auto-leave**: bot automatically leaves the voice channel when it's left alone\n- **Auto-cleanup**: when the bot is kicked, dragged out, or otherwise loses its voice connection, playback state and the queue are cleaned up automatically\n- **Per-guild volume persistence**: the last-set volume is remembered between sessions in SQLite\n- **Cross-track loudness normalization**: opt-in via `!normalize`. When enabled, each cached track's integrated loudness is measured once (EBU R128 via ffmpeg) and a static gain is applied so songs sit at roughly the same perceived loudness without crushing in-song dynamics. Off by default, takes effect immediately on the current track, resets on restart. The target loudness (`NORMALIZE_TARGET_LUFS`, default -10) and gain clamps (`NORMALIZE_MIN_GAIN_DB`, `NORMALIZE_MAX_GAIN_DB`) are tunable via env vars — higher target = louder output\n- **Per-source cache layout**: downloaded audio is filed under `cache/youtube/` or `cache/spotify/` (legacy flat-cached files still play)\n- **Slash + prefix parity**: every command works both ways\n- **Graceful shutdown**: handles SIGINT/SIGTERM (and Ctrl+C on Windows) to disconnect cleanly\n- **Structured logging**: powered by `tracing` with environment-controlled filtering\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirestone82%2Frustytunes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffirestone82%2Frustytunes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffirestone82%2Frustytunes/lists"}