diff --git a/src/dc.py b/src/dc.py index c74e191..5fc0170 100755 --- a/src/dc.py +++ b/src/dc.py @@ -1,35 +1,65 @@ #!/usr/bin/bash import discord +from discord.ext.commands import bot from constants import BOT_TOKEN import main +from discord import app_commands, message intetns = discord.Intents.default() intetns.message_content = True client = discord.Client(intents=intetns) +tree = app_commands.CommandTree(client) player = main.Player() @client.event async def on_ready(): + await tree.sync(guild=discord.Object(id=824172801644036117)) print(f"Logged in as {client.user}") -@client.event -async def on_message(message): - if message.author == client.user: - return - if message.content == ("play"): - await player.play() - await message.channel.send("playing") - if message.content.startswith("add"): - url = message.content.strip().split()[1] - await player.add_to_que(url) - await message.channel.send(player.que) - if message.content.startswith("$hello"): - await message.channel.send("hello") - if message.content == "list": - await message.channel.send(player.que) - if message.content == "stop": - player.stop() +@tree.command( + name="hello", + description="desc", + guild=discord.Object(id=824172801644036117) +) +async def hello(interaction: discord.Interaction, _: str) -> None: + await interaction.response.send_message("Hello") + +@tree.command( + name="stop", + description="Stops the current song", + guild=discord.Object(id=824172801644036117) +) +async def stop(interaction: discord.Interaction) -> None: + player.stop() + await interaction.response.send_message("playlist stopped") + +@tree.command( + name="play", + description="Starts the current playlist", + guild=discord.Object(id=824172801644036117) +) +async def start(interaction: discord.Interaction) -> None: + await player.play() + await interaction.response.send_message("Playlist started!") + +@tree.command( + name="list", + description="Lists the songs that are in the playlist", + guild=discord.Object(id=824172801644036117) +) +async def list(interaction: discord.Interaction) -> None: + await interaction.response.send_message(player.que) + + +@tree.command( + name="add", + description="Add a song to the playlist", + guild=discord.Object(id=824172801644036117) +) +async def add(interaction: discord.Interaction, music: str) -> None: + await player.add_to_que(music) + await interaction.response.send_message(f"{music} was added to playlist") client.run(BOT_TOKEN) diff --git a/src/main.py b/src/main.py index b9f90a9..bc02eea 100755 --- a/src/main.py +++ b/src/main.py @@ -1,23 +1,53 @@ #!/usr/bin/env python3 +import os +from typing import Optional import mpv from threading import Thread +import yt_dlp as youtube_dl +from enum import Enum +import uuid + +class DownloadStatus(Enum): + NOT_STARTED = 1 + STARTED = 2 + FINISHED = 3 + +class Item: + url = "" + status = DownloadStatus.NOT_STARTED + path = "" + + def __init__(self, url) -> None: + self.url = url + + def get_playable(self): + if self.status == DownloadStatus.NOT_STARTED: + return self.url + else: + return self.path class Queue: def __init__(self): - self.queue = [] + self.queue: list[Item] = [] def add(self, item): - self.queue.append(item) + self.queue.append(Item(item)) def remove(self, index): - self.queue.remove( index) + self.queue.remove(index) def clear(self): self.queue.clear() - def pop(self): + def pop_next(self) -> Item: return self.queue.pop(0) + def get_next(self) -> Optional[Item]: + if len(self.queue) > 0: + return self.queue[0] + return None + + def __repr__(self) -> str: return self.queue.__repr__() @@ -36,11 +66,19 @@ async def play(self): self.player_thread.start() def play2(self): - while self.que.len() >= 0 and not self.paused: + while self.que.len() >= 1 and not self.paused: print(self.paused) print(self.que) - self.player.play(self.que.pop()) + current = self.que.pop_next() + self.player.play(current.get_playable()) + next = self.que.get_next() + if next != None: + self.player_thread = Thread(target=self.cache_song, args=[next]) + self.player_thread.start() self.player.wait_for_playback() + print("start-cleanup") + self.cleanup(current.path) + print(self.que.len()) async def add_to_que(self, url): self.que.add(url) @@ -48,3 +86,35 @@ async def add_to_que(self, url): def stop(self): self.player.stop() self.paused = True + + def cache_song(self, song: Item): + + path = f"downloaded_{uuid.uuid5}" + ydl_opts = { + 'format': 'bestaudio/best', + 'postprocessors': [{ + 'key': 'FFmpegExtractAudio', + 'preferredcodec': 'mp3', + 'preferredquality': '192', + }], + 'outtmpl': path + } + + song.path = f"{path}.part" + song.status = DownloadStatus.STARTED + print(song.url) + print("cache started") + with youtube_dl.YoutubeDL(ydl_opts) as ydl: + ydl.download([song.url]) + print("download finished") + song.status = DownloadStatus.FINISHED + song.path = f"{path}.mp3" + + + def cleanup(self, path: str): + try: + os.remove(path) + except: + pass + +