init repo

This commit is contained in:
Thomas 2025-06-15 15:37:24 +02:00
commit b7c9e76a02
6 changed files with 170 additions and 0 deletions

50
.gitignore vendored Normal file
View File

@ -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

View File

@ -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()

13
compose.yml Normal file
View File

@ -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

6
dockerfile Normal file
View File

@ -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"]

33
main.py Normal file
View File

@ -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)

5
requirements.txt Normal file
View File

@ -0,0 +1,5 @@
aiohttp
PyNaCl
ffmpeg
yt-dlp
discord.py