🚀 fixed some errors, optimised spotify playlists

This commit is contained in:
2023-11-10 15:49:30 +00:00
parent a40679ee11
commit 5206de1840
4 changed files with 102 additions and 41 deletions

View File

@@ -92,7 +92,7 @@ class music(commands.Cog):
async with ctx.typing(): async with ctx.typing():
#TODO potentially save requests before getting stream link #TODO potentially save requests before getting stream link
# Grab video details such as title thumbnail duration # Grab video details such as title thumbnail duration
audio = translate.main(url, self.sp) audio = await translate.main(url, self.sp)
await msg.delete() await msg.delete()
@@ -103,8 +103,16 @@ class music(commands.Cog):
#TODO make sure user isn't queuing in dm for some stupid reason #TODO make sure user isn't queuing in dm for some stupid reason
for song in audio:
song['position'] = await queue.add_song( # Setup first song's position
audio[0]['position'] = await queue.add_song(
server,
audio[0],
ctx.author.display_name)
# Add any other songs
for song in audio[1:]:
await queue.add_song(
server, server,
song, song,
ctx.author.display_name) ctx.author.display_name)
@@ -164,7 +172,7 @@ class music(commands.Cog):
# Skip specificed number of songs # Skip specificed number of songs
for _ in range(n-1): for _ in range(n-1):
await queue.pop(server.id) await queue.pop(server.id, True)
# Safe to ignore error for now # Safe to ignore error for now
ctx.voice_client.stop() ctx.voice_client.stop()

View File

@@ -4,6 +4,8 @@ import sqlite3
import discord import discord
import asyncio import asyncio
from .translate import search_song
db_path = "./data/music.db" db_path = "./data/music.db"
FFMPEG_OPTS = { FFMPEG_OPTS = {
@@ -62,22 +64,40 @@ async def add_song(server_id, details, queued_by):
max_order_num = await get_max(server_id, cursor) + 1 max_order_num = await get_max(server_id, cursor) + 1
cursor.execute(""" if isinstance(details, str):
INSERT INTO songs (server_id, cursor.execute("""
song_link, INSERT INTO songs (server_id,
queued_by, song_link,
position, queued_by,
title, position,
thumbnail, title,
duration) thumbnail,
VALUES (?, ?, ?, ?, ?, ?, ?) duration)
""", (server_id, VALUES (?, ?, ?, ?, ?, ?, ?)
details['url'], """, (server_id,
queued_by, "Not grabbed",
max_order_num, queued_by,
details['title'], max_order_num,
details['thumbnail'], details,
details['duration'])) "Unkown",
"Unkown"))
else:
cursor.execute("""
INSERT INTO songs (server_id,
song_link,
queued_by,
position,
title,
thumbnail,
duration)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (server_id,
details['url'],
queued_by,
max_order_num,
details['title'],
details['thumbnail'],
details['duration']))
conn.commit() conn.commit()
conn.close() conn.close()
@@ -86,7 +106,7 @@ async def add_song(server_id, details, queued_by):
# Pop song from server # Pop song from server
async def pop(server_id): async def pop(server_id, ignore=False):
# Connect to db # Connect to db
conn = sqlite3.connect(db_path) conn = sqlite3.connect(db_path)
cursor = conn.cursor() cursor = conn.cursor()
@@ -106,6 +126,20 @@ async def pop(server_id):
if result == None: if result == None:
return None return None
elif ignore:
await mark_song_as_finished(server_id, result[3])
return None
elif result[1] == "Not grabbed":
# Fetch song info
song = await search_song(result[4])
if song == []:
return None
else:
song = song[0]
await set_current_song(server_id, song['title'])
await mark_song_as_finished(server_id, result[3])
return song['url']
await set_current_song(server_id, result[4]) await set_current_song(server_id, result[4])
await mark_song_as_finished(server_id, result[3]) await mark_song_as_finished(server_id, result[3])
@@ -286,6 +320,8 @@ class AstroPlayer(discord.FFmpegPCMAudio):
def _kill_process(self): def _kill_process(self):
super()._kill_process() super()._kill_process()
if self.ctx.voice_client.is_playing():
return
asyncio.run(play(self.ctx)) asyncio.run(play(self.ctx))
# Play and loop songs in server # Play and loop songs in server
@@ -305,5 +341,5 @@ async def play(ctx):
return return
# else play next song and call play again # else play next song and call play again
await ctx.voice_client.play( ctx.voice_client.play(
AstroPlayer(ctx, url, FFMPEG_OPTS)) AstroPlayer(ctx, url, FFMPEG_OPTS))

View File

@@ -10,20 +10,20 @@ ydl_opts = {
'ignoreerrors': True, 'ignoreerrors': True,
} }
def main(url, sp): async def main(url, sp):
#url = url.lower() #url = url.lower()
# Check if link or search # Check if link or search
if url.startswith("https://") is False: if url.startswith("https://") is False:
return search_song(url) return await search_song(url)
#TODO add better regex or something #TODO add better regex or something
if 'spotify' in url: if 'spotify' in url:
if 'track' in url: if 'track' in url:
return spotify_song(url, sp) return await spotify_song(url, sp)
elif 'playlist' in url: elif 'playlist' in url:
return spotify_playlist(url, sp) return await spotify_playlist(url, sp)
soundcloud_song = 'soundcloud' in url and 'sets' not in url soundcloud_song = 'soundcloud' in url and 'sets' not in url
# Not implemented yet # Not implemented yet
@@ -33,15 +33,15 @@ def main(url, sp):
youtube_playlist = 'playlist?list=' in url youtube_playlist = 'playlist?list=' in url
if soundcloud_song or youtube_song: if soundcloud_song or youtube_song:
return song_download(url) return await song_download(url)
if youtube_playlist: if youtube_playlist:
return playlist_download(url) return await playlist_download(url)
return [] return []
def search_song(search): async def search_song(search):
with ytdlp.YoutubeDL(ydl_opts) as ydl: with ytdlp.YoutubeDL(ydl_opts) as ydl:
try: try:
info = ydl.extract_info(f"ytsearch1:{search}", download=False) info = ydl.extract_info(f"ytsearch1:{search}", download=False)
@@ -58,7 +58,7 @@ def search_song(search):
return [data] return [data]
def spotify_song(url, sp): async def spotify_song(url, sp):
track = sp.track(url.split("/")[-1].split("?")[0]) track = sp.track(url.split("/")[-1].split("?")[0])
search = "" search = ""
@@ -72,10 +72,10 @@ def spotify_song(url, sp):
# set search to name # set search to name
query = search + " - " + track['name'] query = search + " - " + track['name']
return search_song(query) return await search_song(query)
def spotify_playlist(url, sp): async def spotify_playlist(url, sp):
# Get the playlist uri code # Get the playlist uri code
code = url.split("/")[-1].split("?")[0] code = url.split("/")[-1].split("?")[0]
@@ -99,17 +99,27 @@ def spotify_playlist(url, sp):
# Remove last column # Remove last column
search = search[:-2] search = search[:-2]
search += f" - {track['track']['name']}" search += f" - {track['track']['name']}"
songs.append(search)
searched_result = search_song(search) #searched_result = search_song(search)
if searched_result == []: #if searched_result == []:
#continue
#songs.append(searched_result[0])
while True:
search_result = await search_song(songs[0])
if search_result == []:
songs.pop(0)
continue continue
else:
songs.append(searched_result[0]) songs[0] = search_result[0]
break
return songs return songs
def song_download(url): async def song_download(url):
with ytdlp.YoutubeDL(ydl_opts) as ydl: with ytdlp.YoutubeDL(ydl_opts) as ydl:
try: try:
info = ydl.extract_info(url, download=False) info = ydl.extract_info(url, download=False)
@@ -125,7 +135,7 @@ def song_download(url):
return [data] return [data]
def playlist_download(url): async def playlist_download(url):
with ytdlp.YoutubeDL(ydl_opts) as ydl: with ytdlp.YoutubeDL(ydl_opts) as ydl:
try: try:
info = ydl.extract_info(url, download=False) info = ydl.extract_info(url, download=False)

View File

@@ -20,10 +20,12 @@ async def join_vc(ctx: Context):
# Join or move to the user's vc # Join or move to the user's vc
if ctx.voice_client is None: if ctx.voice_client is None:
await vc.connect() vc = await vc.connect()
else: else:
# Safe to ignore type error for now # Safe to ignore type error for now
await ctx.voice_client.move_to(vc) vc = await ctx.voice_client.move_to(vc)
return vc
# Leaving the voice channel of a user # Leaving the voice channel of a user
@@ -71,7 +73,12 @@ async def display_server_queue(ctx: Context, songs, n):
display = f"🔊 Currently playing: ``{await queue.get_current_song(ctx.guild.id)}``\n\n" display = f"🔊 Currently playing: ``{await queue.get_current_song(ctx.guild.id)}``\n\n"
for i, song in enumerate(songs): for i, song in enumerate(songs):
display += f"``{i + 1}.`` {song[0]} - {format_time(song[1])} Queued by {song[2]}\n"
# If text is not avaialable do not display
time = '' if isinstance(song[1], str) else format_time(song[1])
display += f"``{i + 1}.`` {song[0]} - {time} Queued by {song[2]}\n"
msg.add_field(name="Songs:", msg.add_field(name="Songs:",
value=display, value=display,
inline=True) inline=True)