🚀 fixed some errors, optimised spotify playlists
This commit is contained in:
@@ -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()
|
||||||
@@ -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))
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user