Fixed some issues with incorrect songs being played in DJ mode.

This commit is contained in:
Jared Kick 2025-07-30 11:52:49 -04:00
parent a7f00f9e43
commit a8b5a59212
2 changed files with 30 additions and 20 deletions

View File

@ -88,28 +88,37 @@ class YTDLSource(discord.PCMVolumeTransformer):
loop = ctx.bot.loop if ctx else asyncio.get_event_loop()
# If we got a YouTube link, get the video title for the song search
if validators.url(search):
logger.debug("Search parameter:", search)
if isinstance(search, dict):
search_term = search["title"]
artist_str = f"&artist={search["artist"]}"
elif isinstance(search, str) and validators.url(search):
with YoutubeDL() as ydl:
info = ydl.extract_info(search, download=False)
search_term = info.get("title", "")
artist_str = ""
else:
search_term = search
artist_str = ""
# Get song metadata
logger.info(f"Searching LastFM for: '{search_term}'")
url = f"http://ws.audioscrobbler.com/2.0/?method=track.search&"\
f"track={search_term}&api_key={LASTFM_API_KEY}&format=json"
f"track={search_term}{artist_str}&api_key={LASTFM_API_KEY}&format=json"
response = requests.get(url)
lastfm_data = response.json()
# Let's get the first result, if any
if lastfm_data['results']['trackmatches']['track']:
track = lastfm_data['results']['trackmatches']['track'][0]
artist = track['artist']
song_title = track['name']
if not lastfm_data['results']['trackmatches']['track']:
raise RuntimeError("LastFM returned no results")
track = lastfm_data['results']['trackmatches']['track'][0]
logger.debug("LastFM match: ", track)
artist = track['artist']
song_title = track['name']
# Adjust search term if we didn't get a URL
if not validators.url(search):
if isinstance(search, dict) and not validators.url(search):
search = f"{song_title} {artist} official audio"
logger.debug(f"Search string is not a URL; converting to {search}")
# Get YouTube video source
logger.info(f"Getting YouTube video: {search_term}")
@ -428,26 +437,23 @@ class MusicPlayer:
"Queue is empty and DJ mode is on. Picking song at random"
)
try:
# TEST
user_ids = [m.id for m in self._channel.members]
channel_ids = [c.id for c in self._channel.guild.channels]
song = self.bot.db.get_next_song(users=user_ids, channels=channel_ids)
search = f"{song["artist"]} {song["title"]}"
source = await YTDLSource.create_source(
None,
search,
song,
download=True,
)
if not source:
raise RuntimeError("Could not get YouTube source.")
except Exception as e:
# Something's wrong, turn off DJ mode to prevent infinite
# loop
self.dj_mode = False
print(e)
await self._channel.send("Failed to get YouTube source.")
# # Something's wrong, turn off DJ mode to prevent infinite
# # loop
# self.dj_mode = False
logger.error(e)
# await self._channel.send(str(e))
# For the time being, we're going to use 'None' to signal to the
# player that it should go back around and check for a song again,

View File

@ -415,8 +415,10 @@ class Database:
del activity_stats[None]
return activity_stats
def get_next_song(self, users: list[int], channels: list[int], limit: int = 100, cutoff: datetime = datetime.now() - timedelta(hours=1)):
def get_next_song(self, users: list[int], channels: list[int], limit: int = 100, cutoff: datetime = None):
_cutoff = datetime.now() - timedelta(hours=1) if not cutoff else cutoff
print("users:", users)
print("channels:", channels)
@ -466,7 +468,7 @@ class Database:
""" % (
",".join(str(id) for id in user_ids),
",".join(str(id) for id in channel_ids)
), (cutoff, limit))
), (_cutoff, limit))
old_song_plays = cursor.fetchall()
# Compile results into cleaner list of dicts
@ -490,7 +492,7 @@ class Database:
GROUP BY
song_title,
song_artist;
""" % (",".join(str(id) for id in channel_ids)), (cutoff, ))
""" % (",".join(str(id) for id in channel_ids)), (_cutoff, ))
recent_song_plays = cursor.fetchall()
print("recent:", recent_song_plays)
@ -535,7 +537,9 @@ class Database:
"song title is the 'title' key and the artist is "\
"the 'artist' key. I want you to return a song "\
"title and artist that you would recommend based "\
"on the given songs. You should give me only a bare text "\
"on the given songs. Don't be afraid to branch out "\
"and vary songs; the same artist should not be "\
"repeated more than twice. You should give me only a bare text "\
"string formatted as a Python dict where the "\
"'title' key is the song title, and the 'artist' "\
"key is the song's artist. Don't add anything other "\