import asyncio import typing import lavalink from discord.channel import TextChannel from discord.ext import commands from bot import TuneBot from cogs.music import helper from cogs.music.interactions import MusicCommands from cogs.music.interactions import QUEUE_SIZE from cogs.music.voice_client import LavalinkVoiceClient from utils.classes import BaseCog from utils.log import logger if typing.TYPE_CHECKING: from bot import TuneBot class MusicCog(BaseCog, name="Music"): def __init__(self, bot: TuneBot): super().__init__(bot) if not hasattr(bot, "lavalink"): self.bot.lavalink = self.bot.create_lavalink(bot.user.id) self.bot.lavalink.add_event_hook(self.track_hook) @commands.Cog.listener() async def on_ready(self): while not self.is_lavalink_ready(): await asyncio.sleep(1) redis_result = await self.bot.global_autojoin.fetch_channels() for guild_id, (voicechannel_id, textchannel_id) in redis_result.items(): try: player = self.bot.lavalink.player_manager.create(guild_id) player.store("channel", textchannel_id) voice_channel = await self.bot.fetch_channel(voicechannel_id) await voice_channel.connect(cls=LavalinkVoiceClient) if not player.is_playing: await helper.fill_player_queue(self.bot, player, QUEUE_SIZE) await player.play() except: logger.error(f"Failed to autojoin guild {guild_id}.") 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 = helper.create_track_embed(event.player.current) await channel.send(embed=embed) elif isinstance(event, lavalink.events.TrackEndEvent): await helper.fill_player_queue(self.bot, event.player, 1) async def setup(bot: "TuneBot"): await bot.add_cog(MusicCog(bot)) bot.tree.add_command(MusicCommands(bot), override=True)