diff --git a/bot.py b/bot.py index e08daa1..4c140f9 100644 --- a/bot.py +++ b/bot.py @@ -28,6 +28,7 @@ from tunebot.redis import GlobalRedisPlaylistSource from tunebot.redis import RedisAutoJoin from tunebot.redis import RedisPlaylistSource from utils.assets import process_colours +from lavalink_player import CustomPlayer from utils.log import logger if TYPE_CHECKING: @@ -127,7 +128,7 @@ class TuneBot(commands.Bot): def create_lavalink(self, user_id: int) -> "lavalink.Client": cfg = self.config["lavalink"] - client: lavalink.Client = lavalink.Client(user_id) + client: lavalink.Client = lavalink.Client(user_id, player=CustomPlayer) client.add_node( cfg["host"], cfg["port"], diff --git a/cogs/music/__init__.py b/cogs/music/__init__.py index 06d0670..df723a5 100644 --- a/cogs/music/__init__.py +++ b/cogs/music/__init__.py @@ -13,7 +13,6 @@ from cogs.music.interactions import QUEUE_SIZE from cogs.music.voice_client import LavalinkVoiceClient from utils.classes import BaseCog - if typing.TYPE_CHECKING: from bot import TuneBot @@ -43,22 +42,18 @@ class MusicCog(BaseCog, name="Music"): async def track_hook(self, event: lavalink.Event): if isinstance(event, lavalink.events.QueueEndEvent): - # When this track_hook receives a "QueueEndEvent" from lavalink.py - # it indicates that there are no tracks left in the player's queue. - # To save on resources, we can tell the bot to disconnect from the voicechannel. guild_id = event.player.guild_id guild = self.bot.get_guild(guild_id) await guild.voice_client.disconnect(force=True) - elif isinstance(event, lavalink.events.TrackStartEvent): - channel_id = int(event.player.fetch("channel")) - channel: TextChannel = self.bot.get_channel(channel_id) - - embed = track_embed.create_track_embed( - event.player.current, event.player.queue, [] - ) - await channel.send(embed=embed) elif isinstance(event, lavalink.events.TrackEndEvent): await helper.fill_player_queue(self.bot, event.player, 1) + channel_id = int(event.player.fetch("channel")) + channel: TextChannel = self.bot.get_channel(channel_id) + event.player.append_history(event.track) + embed = track_embed.create_track_embed( + event.player.current, event.player.queue, event.player.history + ) + await channel.send(embed=embed) async def setup(bot: "TuneBot"): diff --git a/cogs/music/helper.py b/cogs/music/helper.py index 7b43407..28f6e0a 100644 --- a/cogs/music/helper.py +++ b/cogs/music/helper.py @@ -10,10 +10,11 @@ from utils.log import logger if typing.TYPE_CHECKING: from lavalink import DefaultPlayer + from lavalink_player import CustomPlayer from bot import TuneBot -def get_player(bot: "TuneBot", guild_id: int) -> "DefaultPlayer": +def get_player(bot: "TuneBot", guild_id: int) -> "CustomPlayer": if player := bot.lavalink.player_manager.get(guild_id=guild_id): return player diff --git a/cogs/music/interactions.py b/cogs/music/interactions.py index 69c6901..f7a89b5 100644 --- a/cogs/music/interactions.py +++ b/cogs/music/interactions.py @@ -11,7 +11,7 @@ from cogs.music import track_embed if typing.TYPE_CHECKING: from bot import TuneBot -QUEUE_SIZE = config["queue_buffer_size"] + 1 +QUEUE_SIZE = config["queue_buffer_size"] class MusicCommands(app_commands.Group): @@ -47,7 +47,7 @@ class MusicCommands(app_commands.Group): if not player.is_playing: await player.play() - embed.title = "*⃣ | Connected." + embed = track_embed.create_track_embed(player.current, player.queue, []) await ctx.response.send_message(embed=embed) @app_commands.command( @@ -85,7 +85,9 @@ class MusicCommands(app_commands.Group): await ctx.response.send_message(embed=embed) return - embed = track_embed.create_track_embed(player.current, player.queue, []) + embed = track_embed.create_track_embed( + player.current, player.queue, player.history + ) await ctx.response.send_message(embed=embed) @app_commands.command(name="queue", description="See what's ahead") diff --git a/cogs/music/track_embed.py b/cogs/music/track_embed.py index fefa960..31a3865 100644 --- a/cogs/music/track_embed.py +++ b/cogs/music/track_embed.py @@ -6,35 +6,24 @@ from cogs.music import helper if typing.TYPE_CHECKING: from lavalink.models import AudioTrack - from bot import TuneBot def format_track(track: "AudioTrack", max_length: int = 0): - if max_length == 0: - return f"[{track.title}]({track.uri})" + try: + duration = str(datetime.timedelta(milliseconds=int(track.duration))) + except OverflowError: + duration = "0:00:00" + if max_length == 0: + return f"`{duration}` [{track.title}]({track.uri})" + + max_length -= len(duration) + 1 if len(track.title) > max_length: track_title = track.title[: max_length - 3] + "..." else: track_title = track.title - return f"[{track_title}]({track.uri})" - - -def num_to_emoji(num: int) -> str: - emojis = { - "1": "1️⃣", - "2": "2️⃣", - "3": "3️⃣", - "4": "4️⃣", - "5": "5️⃣", - "6": "6️⃣", - "7": "7️⃣", - "8": "8️⃣", - "9": "9️⃣", - "0": "0️⃣", - } - return "".join(emojis[digit] for digit in str(num)) + return f"`{duration}` [{track_title}]({track.uri})" def create_track_embed( @@ -47,25 +36,19 @@ def create_track_embed( colour=colors["embed"], ) - try: - duration = str(datetime.timedelta(milliseconds=int(current.duration))) - except OverflowError: - duration = "🔴 LIVE" - - embed.description = f"`{duration}` [{current.title}]({current.uri})" + embed.description = format_track(current) if len(queue) > 0: - frags: typing.List[str] = [] - for index, track in enumerate(queue, start=1): - prefix = num_to_emoji(index) - max_track_len = 45 - len(prefix) - - track_fmt = format_track(track, max_length=max_track_len) - frags.append(f"{prefix} {track_fmt}") - upcoming_fmt = "\n".join(frags) + upcoming_fmt = "\n".join(format_track(track) for track in queue) else: upcoming_fmt = "No tracks have been queued yet..." - embed.add_field(name="Upcoming", value=upcoming_fmt) + embed.add_field(name="Coming up", value=upcoming_fmt, inline=False) + + if len(history) > 0: + history_fmt = "\n".join(format_track(track) for track in history) + else: + history_fmt = "No history yet..." + embed.add_field(name="Previously played", value=history_fmt, inline=False) embed.set_image(url=f"https://i3.ytimg.com/vi/{current.identifier}/mqdefault.jpg") embed.set_footer(text=f"Uploaded by: {current.author}") diff --git a/lavalink_player.py b/lavalink_player.py new file mode 100644 index 0000000..eeb1cc4 --- /dev/null +++ b/lavalink_player.py @@ -0,0 +1,21 @@ +import typing +from lavalink import DefaultPlayer + +if typing.TYPE_CHECKING: + from lavalink import Node + from lavalink.models import AudioTrack + + +class CustomPlayer(DefaultPlayer): + def __init__(self, guild_id: int, node: "Node"): + from bot import config + + self.history: typing.List["AudioTrack"] = [] + self.max_size = config["history_size"] + + super().__init__(guild_id, node) + + def append_history(self, track: "AudioTrack"): + self.history.insert(0, track) + if len(self.history) > self.max_size: + self.history.pop(-1)