User Tools

Site Tools


musicbot

This is an old revision of the document!


🎡 Ambient Lo-Fi Discord Music Bot – Installation & Usage

This bot plays ambient lo-fi music automatically in your Discord voice channel. It starts with shuffle, continues playing without stopping, and can be controlled via simple commands.

πŸ“¦ Requirements

  • Python 3.10 or newer
  • FFmpeg installed (`sudo apt install ffmpeg`)
  • A Discord Bot Token
  • MP3 files placed in the `music/` directory
  • Optional: systemd for autostart on boot

πŸ› οΈ Installation

  • Clone or copy the bot code into a directory, e.g. `/var/www/mbot/`
  • Create a `music/` folder and add your MP3 tracks
  • Install required Python packages:

`pip install discord`

πŸ” Insert Your Bot Token

Open `bot.py` and replace:

`bot.run("your-bot-token-here")`

with your actual Discord bot token.

πŸ€– Creating a Discord Bot

  • Click New Application, give it a name
  • Go to Bot tab β†’ click Add Bot
  • Under Privileged Gateway Intents, enable:
    1. Message Content Intent
    2. Server Members Intent
  • Copy the token and paste it into `bot.py`

πŸ”— Invite the Bot to Your Server

Go to the OAuth2 β†’ URL Generator tab:

  • Scopes: `bot`
  • Bot Permissions:
    1. Connect
    2. Speak
    3. Send Messages
    4. Read Message History

Copy the generated URL and open it in your browser to invite the bot.

πŸš€ Starting the Bot

To start manually: `python3 ./bot.py`

Or set up a systemd service:

sudo adduser musikbot
sudo chown -R musikbot:musikbot /var/www/mbot

Autostart on server start

sudo nano /etc/systemd/system/musicbot.service
[Unit]
Description=Discord Music Bot
After=network.target

[Service]
ExecStart=/usr/bin/python3 /var/www/mbot/bot.py
WorkingDirectory=/var/www/mbot
Restart=always
User=musikbot

[Install]
WantedBy=multi-user.target

Enable and start the service: `sudo systemctl daemon-reload` `sudo systemctl enable musicbot` `sudo systemctl start musicbot`

🎧 Discord Commands

  • `!join` – Bot joins your voice channel and starts shuffle playback
  • `!leave` – Bot leaves the voice channel
  • `!list` – Lists all available MP3 files
  • `!play [filename]` – Plays a specific file or a random one if none is given
  • `!next` – Skips to the next track
  • `!shuffle` – Shuffles the playlist and starts playback
  • `!pause` – Pauses playback
  • `!resume` – Resumes playback
  • `!stop` – Stops playback
  • `!help` – Displays all available commands

🧠 Notes

  • The bot plays continuously without stopping after each track
  • Volume is set to 100%
  • Make sure the bot has β€œSpeak” permissions in the voice channel
  • Works best in standard voice channels (not Stage Channels)

πŸ“‚ Folder Structure

/var/www/mbot/
β”œβ”€β”€ bot.py
β”œβ”€β”€ .env
β”œβ”€β”€ music/
β”‚   β”œβ”€β”€ track1.mp3
β”‚   β”œβ”€β”€ track2.mp3

πŸ“‚ .env

DISCORD_TOKEN=your token here

πŸ“‚ bot.py

import discord
from discord.ext import commands
import os
import random
from dotenv import load_dotenv
 
# πŸ” Token laden
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
 
# 🎯 Gezielte Intents
intents = discord.Intents.default()
intents.message_content = True
intents.voice_states = True
 
# πŸ€– Bot-Setup
bot = commands.Bot(command_prefix="!", intents=intents, help_command=None)
 
# πŸ“ Musikverzeichnis & Steuerung
MUSIC_DIR = "music"
playlist = []
current_index = -1
autoplay_enabled = True
 
# πŸš€ Bot ist bereit
@bot.event
async def on_ready():
    print(f"🎡 Bot ist online als {bot.user}")
 
# πŸ” Wrapper fΓΌr asynchrone Wiedergabe
def play_next_track_wrapper(ctx):
    async def inner():
        await play_next_track(ctx)
    bot.loop.create_task(inner())
 
# ▢️ NΓ€chsten Track abspielen
async def play_next_track(ctx):
    global playlist, current_index, autoplay_enabled
    vc = ctx.voice_client
    if not vc or not vc.is_connected() or not playlist or not autoplay_enabled:
        return
 
    current_index = (current_index + 1) % len(playlist)
    filepath = os.path.join(MUSIC_DIR, playlist[current_index])
    source = discord.FFmpegPCMAudio(filepath, options="-filter:a volume=1.0")
    vc.play(source, after=lambda e: play_next_track_wrapper(ctx))
 
    embed = discord.Embed(
        title="▢️ NΓ€chster Track",
        description=playlist[current_index],
        color=discord.Color.blue()
    )
    await ctx.send(embed=embed)
 
# πŸ”€ Shuffle starten
async def start_shuffle(ctx):
    global playlist, current_index, autoplay_enabled
    vc = ctx.voice_client
    if not vc or not vc.is_connected():
        await ctx.send("❌ Bot ist nicht im Sprachkanal.")
        return
 
    autoplay_enabled = True
    playlist = [f for f in os.listdir(MUSIC_DIR) if f.endswith(".mp3")]
    if not playlist:
        await ctx.send("πŸ“ Keine Musikdateien vorhanden.")
        return
 
    random.shuffle(playlist)
    current_index = 0
    filepath = os.path.join(MUSIC_DIR, playlist[current_index])
    source = discord.FFmpegPCMAudio(filepath, options="-filter:a volume=1.0")
    vc.play(source, after=lambda e: play_next_track_wrapper(ctx))
 
    embed = discord.Embed(
        title="πŸ”€ Shuffle gestartet",
        description=playlist[current_index],
        color=discord.Color.green()
    )
    await ctx.send(embed=embed)
 
# πŸ“‘ Sprachkanal beitreten
@bot.command()
async def join(ctx):
    member = ctx.author
    if member.voice and member.voice.channel:
        channel = member.voice.channel
        if not ctx.voice_client:
            await channel.connect()
        await ctx.send(f"βœ… Verbunden mit {channel.name}")
        await start_shuffle(ctx)
    else:
        await ctx.send("❌ Du bist in keinem Sprachkanal.")
 
# πŸ‘‹ Sprachkanal verlassen
@bot.command()
async def leave(ctx):
    if ctx.voice_client:
        await ctx.voice_client.disconnect()
        await ctx.send("πŸ‘‹ Bot hat den Sprachkanal verlassen.")
    else:
        await ctx.send("❌ Bot ist nicht verbunden.")
 
# πŸ“ƒ Liste der Musikdateien
@bot.command()
async def list(ctx):
    files = [f for f in os.listdir(MUSIC_DIR) if f.endswith(".mp3")]
    if not files:
        await ctx.send("πŸ“ Keine Musikdateien gefunden.")
    else:
        msg = "\n".join(f"{i+1}. {f}" for i, f in enumerate(files))
        await ctx.send(f"🎢 Verfügbare Tracks:\n{msg}")
 
# ▢️ Musik abspielen
@bot.command()
async def play(ctx, filename=None):
    global playlist, current_index, autoplay_enabled
    vc = ctx.voice_client
    if not vc or not vc.is_connected():
        await ctx.send("❌ Bot ist nicht im Sprachkanal. Nutze zuerst !join.")
        return
 
    autoplay_enabled = True
    if filename:
        filepath = os.path.join(MUSIC_DIR, filename)
        if not os.path.isfile(filepath):
            await ctx.send("❌ Datei nicht gefunden.")
            return
        playlist = [filename]
        current_index = 0
    else:
        playlist = [f for f in os.listdir(MUSIC_DIR) if f.endswith(".mp3")]
        if not playlist:
            await ctx.send("πŸ“ Keine Musikdateien vorhanden.")
            return
        current_index = random.randint(0, len(playlist) - 1)
 
    filepath = os.path.join(MUSIC_DIR, playlist[current_index])
    source = discord.FFmpegPCMAudio(filepath, options="-filter:a volume=1.0")
    vc.play(source, after=lambda e: play_next_track_wrapper(ctx))
 
    embed = discord.Embed(
        title="▢️ Spiele",
        description=playlist[current_index],
        color=discord.Color.orange()
    )
    await ctx.send(embed=embed)
 
# ⏭️ NÀchsten Track manuell starten
@bot.command()
async def next(ctx):
    global autoplay_enabled
    vc = ctx.voice_client
    if not vc or not vc.is_connected():
        await ctx.send("❌ Bot ist nicht im Sprachkanal.")
        return
 
    autoplay_enabled = True
    vc.stop()
    await ctx.send("⏭️ NÀchster Track wird gespielt.")
 
# ⏹️ Wiedergabe stoppen und Autoplay deaktivieren
@bot.command()
async def stop(ctx):
    global autoplay_enabled
    vc = ctx.voice_client
    if vc and vc.is_playing():
        autoplay_enabled = False
        vc.stop()
        await ctx.send("⏹️ Wiedergabe gestoppt und Autoplay deaktiviert.")
    else:
        await ctx.send("❌ Keine Wiedergabe aktiv.")
 
# ⏸️ Wiedergabe pausieren
@bot.command()
async def pause(ctx):
    vc = ctx.voice_client
    if vc and vc.is_playing():
        vc.pause()
        await ctx.send("⏸️ Wiedergabe pausiert.")
    else:
        await ctx.send("❌ Keine Wiedergabe aktiv.")
 
# ▢️ Wiedergabe fortsetzen
@bot.command()
async def resume(ctx):
    vc = ctx.voice_client
    if vc and vc.is_paused():
        vc.resume()
        await ctx.send("▢️ Wiedergabe fortgesetzt.")
    else:
        await ctx.send("❌ Nichts zum Fortsetzen.")
 
# ℹ️ Hilfe anzeigen
@bot.command()
async def help(ctx):
    embed = discord.Embed(
        title="🎡 Musikbot Befehle",
        color=discord.Color.purple()
    )
    embed.add_field(name="!join", value="Bot tritt deinem Sprachkanal bei und startet Shuffle", inline=False)
    embed.add_field(name="!leave", value="Bot verlΓ€sst den Sprachkanal", inline=False)
    embed.add_field(name="!list", value="Zeigt alle verfΓΌgbaren MP3-Dateien", inline=False)
    embed.add_field(name="!play [Dateiname]", value="Spielt eine bestimmte Datei oder zufΓ€llig", inline=False)
    embed.add_field(name="!next", value="Spielt den nΓ€chsten Track", inline=False)
    embed.add_field(name="!shuffle", value="Mischt die Playlist und startet Wiedergabe", inline=False)
    embed.add_field(name="!pause", value="Pausiert die Wiedergabe", inline=False)
    embed.add_field(name="!resume", value="Setzt die Wiedergabe fort", inline=False)
    embed.add_field(name="!stop", value="Stoppt die Wiedergabe und deaktiviert Autoplay", inline=False)
    await ctx.send(embed=embed)
 
# πŸš€ Bot starten
bot.run(TOKEN)

πŸ›Ÿ Support & Extensions

You can expand the bot anytime – with volume control, queue management, or even a web interface. For questions or ideas, feel free to reach out!

musicbot.1758273517.txt.gz Β· Last modified: by miko

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki