commit b7c9e76a02fd7d791304f0ecd8b8caccc07638e6 Author: Thomas Date: Sun Jun 15 15:37:24 2025 +0200 init repo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f907246 --- /dev/null +++ b/.gitignore @@ -0,0 +1,50 @@ +# Python specific +__pycache__/ +*.py[cod] +*.pyo +*.pyd +*.so + +# Environment variables +.env + +# Virtual environments +venv/ +env/ +*.egg-info/ + +# Docker specific +*.log +docker-compose.override.yml +.dockerignore + +# Byte-compiled / optimized / DLL files +*.pyc +*.pyo +*.pyd + +# Distribution / packaging +build/ +dist/ +*.egg +*.egg-info/ +.installed.cfg +*.manifest +*.spec + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# IDEs and editors +.vscode/ +.idea/ +*.swp +*.swo +*.swn \ No newline at end of file diff --git a/Functionnalities/Audio_Player.py b/Functionnalities/Audio_Player.py new file mode 100644 index 0000000..74e2a16 --- /dev/null +++ b/Functionnalities/Audio_Player.py @@ -0,0 +1,63 @@ +import discord +from discord.ext import commands +import yt_dlp + +ytdl = yt_dlp.YoutubeDL({ + 'format': 'm4a/bestaudio/best', + # ℹ️ See help(yt_dlp.postprocessor) for a list of available Postprocessors and their arguments + 'postprocessors': [{ # Extract audio using ffmpeg + 'key': 'FFmpegExtractAudio', + 'preferredcodec': 'm4a', + }] +}) +ytdl.params.update({ + 'noplaylist': True, # Avoid downloading playlists + 'quiet': True, # Suppress output + 'skip_download': True, # Avoid downloading files +}) + +class YoutubePlayer(commands.Cog): + def __init__(self, url): + infos = ytdl.extract_info(url, download=False) + self.title = infos["title"] + self.url = infos["webpage_url"] + self.duration = infos["duration"] + formats = [elem for elem in infos["formats"] if elem["audio_ext"] != "none"] + if( len(formats) == 0): + raise Exception("No audio format found") + self.audio_url = formats[0]["url"] + +class Audio_Player(): + def __init__(self): + self.playlist = [] # List of songs to play + self.current_song = None # Currently playing song + pass + + async def play(self, ctx, url: str): + """Play a song from a URL.""" + voice_channel = ctx.author.voice.channel + + await ctx.message.delete() + + if ctx.voice_client is None: + await voice_channel.connect() + else: + await ctx.voice_client.move_to(voice_channel) + + if ctx.voice_client.is_playing(): + ctx.voice_client.stop() + + audio_source = discord.FFmpegPCMAudio(YoutubePlayer(url).audio_url) + audio_transformer = discord.PCMVolumeTransformer(audio_source, 0.40) + ctx.voice_client.play(audio_transformer, after=lambda _: print(f"Finished playing: {url}")) + + await ctx.send(f"Now playing: {url}") + + async def stop(self, ctx): + """Stop the current song.""" + if ctx.voice_client.is_playing(): + ctx.voice_client.stop() + await ctx.send("Stopped playing.") + else: + await ctx.send("Not currently playing any song.") + await ctx.voice_client.disconnect() \ No newline at end of file diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..b9491d3 --- /dev/null +++ b/compose.yml @@ -0,0 +1,13 @@ +services: + discord-bot: + build: + context: . + dockerfile: Dockerfile + container_name: garuda-discord-bot + restart: unless-stopped + network_mode: bridge + env_file: + - .env + volumes: + - ./data:/app/data + \ No newline at end of file diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000..19c3483 --- /dev/null +++ b/dockerfile @@ -0,0 +1,6 @@ +FROM alpine:latest +WORKDIR /app +COPY . . +RUN apk add --no-cache python3 py3-pip ffmpeg +RUN pip3 install --no-cache-dir --break-system-packages -r requirements.txt +CMD ["python3", "main.py"] \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..4380fc8 --- /dev/null +++ b/main.py @@ -0,0 +1,33 @@ +import os +import discord +import logging +from discord.ext import commands +from Functionnalities import Audio_Player + + +logging.basicConfig(level=logging.DEBUG) + +intents = discord.Intents.default() +intents.message_content = True + +bot = commands.Bot(command_prefix="!", intents=intents) +player = Audio_Player.Audio_Player() + +@bot.command() +async def play(ctx, url: str): + try: + await player.play(ctx, url) + except Exception as e: + await ctx.send(f"An error occurred: {e}") + print(f"Error: {e}") + +@bot.command() +async def stop(ctx): + try: + await player.stop(ctx) + except Exception as e: + await ctx.send(f"An error occurred: {e}") + print(f"Error: {e}") + +token = os.getenv("DISCORD_TOKEN") +bot.run(token) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..72631f4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +aiohttp +PyNaCl +ffmpeg +yt-dlp +discord.py \ No newline at end of file