mirror of
https://github.com/G2-Games/simple-discord-music-bot.git
synced 2025-04-19 07:52:54 -05:00
Fixed queue index when skipping, added colorthief theming to playback embed
This commit is contained in:
parent
c6b3fa0190
commit
5dca7c5726
2 changed files with 53 additions and 29 deletions
67
src/main.py
67
src/main.py
|
@ -10,6 +10,7 @@ import json
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
## LOCAL IMPORTS ##
|
## LOCAL IMPORTS ##
|
||||||
|
#####
|
||||||
import utils
|
import utils
|
||||||
|
|
||||||
logging.basicConfig()
|
logging.basicConfig()
|
||||||
|
@ -85,13 +86,15 @@ async def play(ctx, *, query: str = None):
|
||||||
return
|
return
|
||||||
|
|
||||||
if ctx.message.attachments:
|
if ctx.message.attachments:
|
||||||
notice = await ctx.send(":arrow_double_up: Uploading file...", suppress_embeds=True)
|
success_list = []
|
||||||
|
notice = await ctx.send(":arrow_double_up: Uploading...", suppress_embeds=True)
|
||||||
|
success_string = ":white_check_mark: Successfully uploaded: \n"
|
||||||
for song in ctx.message.attachments:
|
for song in ctx.message.attachments:
|
||||||
filename, thumbname = utils.getFileNames(server_id)
|
filename, thumbname = utils.getFileNames(server_id)
|
||||||
|
|
||||||
# Make sure the file is either audio or video
|
# Make sure the file is either audio or video
|
||||||
filetype = song.content_type
|
filetype = song.content_type
|
||||||
if filetype.split('/')[0] != "audio" and filetype.split('/')[0] != "video":
|
if filetype is None or (filetype.split('/')[0] != "audio" and filetype.split('/')[0] != "video"):
|
||||||
await notice.edit(content=":no_entry_sign: Not a valid video or audio file...")
|
await notice.edit(content=":no_entry_sign: Not a valid video or audio file...")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -100,11 +103,20 @@ async def play(ctx, *, query: str = None):
|
||||||
|
|
||||||
# Get all the info about the file and create an "item" for it
|
# Get all the info about the file and create an "item" for it
|
||||||
item = utils.parseMediaFile(song, filename, thumbname)
|
item = utils.parseMediaFile(song, filename, thumbname)
|
||||||
|
success_list.append(item["name"]);
|
||||||
|
|
||||||
await notice.edit(content=":white_check_mark: Successfully uploaded \"" + item["name"] + "\"", delete_after=3)
|
success_string += " –`" + item["name"] + "`\n"
|
||||||
|
|
||||||
|
await notice.edit(content=success_string)
|
||||||
server_info[server_id]["queue"].append(item)
|
server_info[server_id]["queue"].append(item)
|
||||||
|
|
||||||
|
if len(success_list) > 0:
|
||||||
|
await notice.edit(content=success_string, delete_after=3)
|
||||||
|
else:
|
||||||
|
await notice.edit(content=f":no_entry_sign: No files successfully uploaded.", delete_after=3)
|
||||||
|
return
|
||||||
elif query[0:4] != "http" and query[0:3] != "www":
|
elif query[0:4] != "http" and query[0:3] != "www":
|
||||||
filename, thumbname = utils.getFileNames(server_id)
|
filename, _ = utils.getFileNames(server_id)
|
||||||
|
|
||||||
# Let the user know the bot is searching for a video
|
# Let the user know the bot is searching for a video
|
||||||
notice = await ctx.send(":mag_right: Searching for \"" + query + "\" ...", suppress_embeds=True)
|
notice = await ctx.send(":mag_right: Searching for \"" + query + "\" ...", suppress_embeds=True)
|
||||||
|
@ -133,13 +145,14 @@ async def play(ctx, *, query: str = None):
|
||||||
"id": filename,
|
"id": filename,
|
||||||
"thumbnail": None,
|
"thumbnail": None,
|
||||||
"thumbnail_url": thumb_url,
|
"thumbnail_url": thumb_url,
|
||||||
"duration": int(float(duration))
|
"duration": int(float(duration)),
|
||||||
|
"color": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
await notice.edit(content=":white_check_mark: Found " + title + ": " + audio_url, suppress=True, delete_after=3)
|
await notice.edit(content=":white_check_mark: Found " + title + ": " + audio_url, suppress=True, delete_after=3)
|
||||||
server_info[server_id]["queue"].append(item)
|
server_info[server_id]["queue"].append(item)
|
||||||
elif query[0:4] == "http" or query[0:3] == "www":
|
elif query[0:4] == "http" or query[0:3] == "www":
|
||||||
filename, thumbname = utils.getFileNames(server_id)
|
filename, _ = utils.getFileNames(server_id)
|
||||||
|
|
||||||
notice = await ctx.send(":mag_right: Adding video \"" + query + "\" ...", suppress_embeds=True)
|
notice = await ctx.send(":mag_right: Adding video \"" + query + "\" ...", suppress_embeds=True)
|
||||||
|
|
||||||
|
@ -166,7 +179,8 @@ async def play(ctx, *, query: str = None):
|
||||||
"id": filename,
|
"id": filename,
|
||||||
"thumbnail": None,
|
"thumbnail": None,
|
||||||
"thumbnail_url": thumb_url,
|
"thumbnail_url": thumb_url,
|
||||||
"duration": int(float(duration))
|
"duration": int(float(duration)),
|
||||||
|
"color": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
await notice.edit(content=":white_check_mark: Found \"" + title + "\": " + query, suppress=True, delete_after=3)
|
await notice.edit(content=":white_check_mark: Found \"" + title + "\": " + query, suppress=True, delete_after=3)
|
||||||
|
@ -176,8 +190,7 @@ async def play(ctx, *, query: str = None):
|
||||||
await ctx.send("Something went wrong, please try a different query.", delete_after=3)
|
await ctx.send("Something went wrong, please try a different query.", delete_after=3)
|
||||||
return
|
return
|
||||||
|
|
||||||
print(str(server_id) + " | " + str(item["name"]))
|
# It's already playing, don't start another playback stream!
|
||||||
|
|
||||||
if voice_channel.is_playing():
|
if voice_channel.is_playing():
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -186,26 +199,31 @@ async def play(ctx, *, query: str = None):
|
||||||
embed = discord.Embed(title="▶️ Playing: ", description="Name: " + "\nURL: ", color=0x42f5a7)
|
embed = discord.Embed(title="▶️ Playing: ", description="Name: " + "\nURL: ", color=0x42f5a7)
|
||||||
playing = await ctx.send(embed=embed)
|
playing = await ctx.send(embed=embed)
|
||||||
|
|
||||||
# Get the current queue position
|
# Get the current queue item
|
||||||
queue_position = server_info[server_id]["queue_position"]
|
queue_position = server_info[server_id]["queue_position"]
|
||||||
queue = server_info[server_id]["queue"]
|
queue = server_info[server_id]["queue"]
|
||||||
|
current_item = queue[queue_position]
|
||||||
|
|
||||||
# Set song variables
|
# Set song variables
|
||||||
song_id = queue[queue_position]['id']
|
song_id = current_item['id']
|
||||||
song_url = queue[queue_position]['url']
|
song_url = current_item['url']
|
||||||
song_name = queue[queue_position]['name']
|
song_name = current_item['name']
|
||||||
song_thumb = queue[queue_position]['thumbnail']
|
song_thumb = current_item['thumbnail']
|
||||||
song_duration = queue[queue_position]['duration']
|
song_duration = current_item['duration']
|
||||||
song_thumb_url = queue[queue_position]['thumbnail_url']
|
song_thumb_url = current_item['thumbnail_url']
|
||||||
song_thumbname = str(int(time.time())) + ".png"
|
song_thumbname = str(int(time.time())) + ".png"
|
||||||
|
|
||||||
|
color = 0x42f5a7
|
||||||
|
if current_item["color"] is not None:
|
||||||
|
color = (current_item["color"][0] << 16) | (current_item["color"][1] << 8) | current_item["color"][2]
|
||||||
|
|
||||||
# Create the embed
|
# Create the embed
|
||||||
if queue[queue_position]['artist'] and queue[queue_position]['album']:
|
if current_item["artist"] and current_item["album"]:
|
||||||
song_desc = "Artist: " + queue[queue_position]['artist'] + "\nAlbum: " + queue[queue_position]['album']
|
song_desc = "Artist: " + current_item['artist'] + "\nAlbum: " + current_item['album']
|
||||||
else:
|
else:
|
||||||
song_desc = ""
|
song_desc = ""
|
||||||
|
|
||||||
embed = discord.Embed(title=":arrow_forward: Playing: " + song_name, url=song_url, description=song_desc, color=0x42f5a7)
|
embed = discord.Embed(title=":arrow_forward: Playing: " + song_name, url=song_url, description=song_desc, color=color)
|
||||||
if song_thumb is not None:
|
if song_thumb is not None:
|
||||||
await playing.add_files(discord.File(song_thumb, filename=song_thumbname))
|
await playing.add_files(discord.File(song_thumb, filename=song_thumbname))
|
||||||
embed.set_thumbnail(url="attachment://" + song_thumbname)
|
embed.set_thumbnail(url="attachment://" + song_thumbname)
|
||||||
|
@ -216,7 +234,7 @@ async def play(ctx, *, query: str = None):
|
||||||
|
|
||||||
song_source = None
|
song_source = None
|
||||||
pipe = False
|
pipe = False
|
||||||
if song_url is not None:
|
if song_url is not None and song_url != "":
|
||||||
song_source = subprocess.Popen(
|
song_source = subprocess.Popen(
|
||||||
['yt-dlp', '-q', '-o', '-', '-x', song_url],
|
['yt-dlp', '-q', '-o', '-', '-x', song_url],
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
|
@ -242,7 +260,7 @@ async def play(ctx, *, query: str = None):
|
||||||
bardata = progressBar.splitBar(total, current, size=20)
|
bardata = progressBar.splitBar(total, current, size=20)
|
||||||
|
|
||||||
# Create embed
|
# Create embed
|
||||||
embed=discord.Embed(title="▶️ Playing: " + song_name, url=song_url, description=song_desc, color=0x42f5a7)
|
embed=discord.Embed(title="▶️ Playing: " + song_name, url=song_url, description=song_desc, color=color)
|
||||||
|
|
||||||
if song_thumb is not None:
|
if song_thumb is not None:
|
||||||
embed.set_thumbnail(url="attachment://" + song_thumbname)
|
embed.set_thumbnail(url="attachment://" + song_thumbname)
|
||||||
|
@ -275,13 +293,14 @@ async def play(ctx, *, query: str = None):
|
||||||
server_info[server_id]["queue"].clear()
|
server_info[server_id]["queue"].clear()
|
||||||
server_info[server_id]["queue_position"] = 0
|
server_info[server_id]["queue_position"] = 0
|
||||||
|
|
||||||
# Remove all queued files and folders
|
# Remove all queued files and folders... This is a bit dangerous, maybe it
|
||||||
|
# should be made failsafe somehow? TODO
|
||||||
fileList = glob.glob(os.path.join(str(server_id),'*'))
|
fileList = glob.glob(os.path.join(str(server_id),'*'))
|
||||||
for filePath in fileList:
|
for filePath in fileList:
|
||||||
try:
|
try:
|
||||||
os.remove(filePath)
|
os.remove(filePath)
|
||||||
except OSError:
|
except OSError:
|
||||||
print("Error while deleting file")
|
print("Error while deleting file ", filePath)
|
||||||
os.rmdir(str(server_id))
|
os.rmdir(str(server_id))
|
||||||
|
|
||||||
|
|
||||||
|
@ -467,7 +486,7 @@ async def q(ctx, action = None, selection = None):
|
||||||
print(str(server_id) + " | " + "Error while deleting song or thumbnail")
|
print(str(server_id) + " | " + "Error while deleting song or thumbnail")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if selection < current_position and current_position > 1:
|
if selection < current_position and current_position:
|
||||||
try:
|
try:
|
||||||
server_info[server_id]["queue_position"] -= 1
|
server_info[server_id]["queue_position"] -= 1
|
||||||
except:
|
except:
|
||||||
|
|
15
src/utils.py
15
src/utils.py
|
@ -1,4 +1,5 @@
|
||||||
import uuid, os, ffmpeg
|
import uuid, os, ffmpeg
|
||||||
|
from colorthief import ColorThief
|
||||||
|
|
||||||
async def getIds(ctx):
|
async def getIds(ctx):
|
||||||
"""Get server id, voice channel id, and user voice channel id"""
|
"""Get server id, voice channel id, and user voice channel id"""
|
||||||
|
@ -23,11 +24,10 @@ async def notSameChannel(ctx) -> bool:
|
||||||
def getFileNames(server_id):
|
def getFileNames(server_id):
|
||||||
"""Get the UUID-based filenames for temp files"""
|
"""Get the UUID-based filenames for temp files"""
|
||||||
|
|
||||||
downloading = 1
|
|
||||||
# Get the current unix timestamp to the nearest millisecond for the filename
|
# Get the current unix timestamp to the nearest millisecond for the filename
|
||||||
uuid_stamp = uuid.uuid1()
|
uuid_stamp = uuid.uuid1()
|
||||||
audioname = str(uuid_stamp) + "audio"
|
audioname = str(uuid_stamp) + "_audio"
|
||||||
thumbname = str(uuid_stamp) + "image"
|
thumbname = str(uuid_stamp) + "_image"
|
||||||
|
|
||||||
# Create the id and thumbnail of the attachment as "tmp<timestamp>.flac" and "tmp<timestamp>.png" respectively
|
# Create the id and thumbnail of the attachment as "tmp<timestamp>.flac" and "tmp<timestamp>.png" respectively
|
||||||
# And add the server ID as the path, making it unique
|
# And add the server ID as the path, making it unique
|
||||||
|
@ -65,8 +65,12 @@ def parseMediaFile(discord_file, tmp_filename: str, tmp_thumbname: str):
|
||||||
file_album = metadata["format"]["tags"]["ALBUM"]
|
file_album = metadata["format"]["tags"]["ALBUM"]
|
||||||
|
|
||||||
|
|
||||||
|
color = None
|
||||||
if os.path.exists(tmp_thumbname):
|
if os.path.exists(tmp_thumbname):
|
||||||
thumbnail = tmp_thumbname
|
thumbnail = tmp_thumbname
|
||||||
|
color_thief = ColorThief(thumbnail)
|
||||||
|
color = color_thief.get_color(quality=1)
|
||||||
|
print(color)
|
||||||
else:
|
else:
|
||||||
thumbnail = "assets/unknown.png"
|
thumbnail = "assets/unknown.png"
|
||||||
|
|
||||||
|
@ -80,11 +84,12 @@ def parseMediaFile(discord_file, tmp_filename: str, tmp_thumbname: str):
|
||||||
"name": file_title.rstrip(),
|
"name": file_title.rstrip(),
|
||||||
"artist": file_artist.rstrip(),
|
"artist": file_artist.rstrip(),
|
||||||
"album": file_album.rstrip(),
|
"album": file_album.rstrip(),
|
||||||
"url": discord_file.url,
|
"url": None,
|
||||||
"id": tmp_filename,
|
"id": tmp_filename,
|
||||||
"thumbnail": thumbnail,
|
"thumbnail": thumbnail,
|
||||||
"thumbnail_url": None,
|
"thumbnail_url": None,
|
||||||
"duration": int(float(duration))
|
"duration": int(float(duration)),
|
||||||
|
"color": color,
|
||||||
}
|
}
|
||||||
|
|
||||||
return item
|
return item
|
||||||
|
|
Loading…
Reference in a new issue