Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
import re import disnake from disnake import ApplicationCommandInteraction as Interaction from disnake.ext import commands import lavalink import logging # Configure logging logging.basicConfig(level=logging.DEBUG) url_rx = re.compile(r'https?://(?:www\.)?.+') CHOICE = commands.option_enum(["Youtube", "Spotify", "Soundcloud"]) class LavalinkVoiceClient(disnake.VoiceProtocol): def __init__(self, client: disnake.Client, channel: disnake.abc.Connectable): self.client = client self.channel = channel self.guild_id = channel.guild.id self._destroyed = False if not hasattr(self.client, 'lavalink'): self.client.lavalink = lavalink.Client(client.user.id) self.client.lavalink.add_node( host='localhost', port=2333, password='youshallnotpass', region='us', name='default-node' ) self.lavalink = self.client.lavalink async def on_voice_server_update(self, data): lavalink_data = {'t': 'VOICE_SERVER_UPDATE', 'd': data} await self.lavalink.voice_update_handler(lavalink_data) async def on_voice_state_update(self, data): channel_id = data['channel_id'] if not channel_id: await self._destroy() return self.channel = self.client.get_channel(int(channel_id)) lavalink_data = {'t': 'VOICE_STATE_UPDATE', 'd': data} await self.lavalink.voice_update_handler(lavalink_data) async def connect(self, *, timeout: float, reconnect: bool, self_deaf: bool = False, self_mute: bool = False) -> None: self.lavalink.player_manager.create(guild_id=self.channel.guild.id) await self.channel.guild.change_voice_state( channel=self.channel, self_mute=self_mute, self_deaf=self_deaf ) async def disconnect(self, *, force: bool = False) -> None: player = self.lavalink.player_manager.get(self.channel.guild.id) if not force and not player.is_connected: return await self.channel.guild.change_voice_state(channel=None) player.channel_id = None await self._destroy() async def _destroy(self): if self._destroyed: return self._destroyed = True try: await self.lavalink.player_manager.destroy(self.guild_id) except lavalink.ClientError as e: logger.error(f'Error destroying Lavalink player: {e}') class Music(commands.Cog): def __init__(self, bot): self.bot = bot @commands.Cog.listener() async def on_ready(self): if not hasattr(self.bot, 'lavalink'): self.bot.lavalink = lavalink.Client(self.bot.user.id) self.bot.lavalink.add_node( host='localhost', port=2333, password='youshallnotpass', region='us', name='default-node' ) async def create_player(self, inter): if inter.guild is None: await inter.response.send_message("This command can only be used in a server.") return player = self.bot.lavalink.player_manager.create(inter.guild.id) should_connect = inter.data['name'] in ('play',) voice_client = inter.guild.voice_client if not inter.author.voice or not inter.author.voice.channel: await inter.response.send_message('You need to join a voice channel first.') return voice_channel = inter.author.voice.channel if voice_client is None: if not should_connect: await inter.response.send_message("I'm not playing music.") return permissions = voice_channel.permissions_for(inter.guild.me) if not permissions.connect or not permissions.speak: await inter.response.send_message('I need the `CONNECT` and `SPEAK` permissions.') return if voice_channel.user_limit > 0: if len(voice_channel.members) >= voice_channel.user_limit and not inter.guild.me.guild_permissions.move_members: raise commands.CommandInvokeError('Your voice channel is full!') player.store('channel', inter.channel.id) # Automatically join the voice channel if the bot is not already connected await voice_channel.connect(cls=LavalinkVoiceClient) elif voice_client.channel.id != voice_channel.id: # If the bot is connected to another channel, raise an error raise commands.CommandInvokeError('You need to be in the same voice channel as the bot.') return True @commands.slash_command(name='play', description='Searches and plays a song from a given query.') async def play(self, inter, query: str, source: CHOICE = None): await self.create_player(inter) player = self.bot.lavalink.player_manager.get(inter.guild.id) # print(player) query = query.strip('<>') # print(source) if not url_rx.match(query): if source == 'Spotify': query = f'sprec:{query}' elif source == 'Soundcloud': query = f'scsearch:{query}' elif source == 'Youtube': query = f'ytsearch:{query}' else: query = f'ytsearch:{query}' # print(query) results = await player.node.get_tracks(query) embed = disnake.Embed(color=disnake.Color.blurple()) if results.load_type == lavalink.LoadType.EMPTY: return await inter.response.send_message("I couldn't find any tracks for that query.") elif results.load_type == lavalink.LoadType.PLAYLIST: tracks = results.tracks for track in tracks: player.add(track=track, requester=inter.author.id) embed.title = 'Playlist Enqueued!' embed.description = f'{results.playlist_info.name} - {len(tracks)} tracks' else: track = results.tracks[0] embed.title = 'Track Enqueued' embed.description = f'[{track.title}]({track.uri})' player.add(track=track, requester=inter.author.id) await inter.response.send_message(embed=embed) if not player.is_playing: await player.play() @commands.slash_command(name='stop', description='Stops the player and clears the queue.') async def stop(self, inter): player = self.bot.lavalink.player_manager.get(inter.guild.id) if not player.is_connected: return await inter.response.send_message("I'm not connected to a voice channel.") player.queue.clear() # Stop the current track so Lavalink consumes less resources. await player.stop() # Disconnect from the voice channel. await inter.guild.voice_client.disconnect(force=True) # await inter.guild.voice_client.disconnect(force=True) await inter.response.send_message("Stopped the player and cleared the queue.") @commands.slash_command(name='skip', description='Skips the current track.') async def skip(self, inter: Interaction): player = self.bot.lavalink.player_manager.get(inter.guild.id) if not player.is_connected: return await inter.response.send_message("I'm not connected to a voice channel.") if not player.is_playing: return await inter.response.send_message("There's no track playing right now.") await player.skip() await inter.response.send_message("Skipped the current track.") @commands.slash_command(name='join', description='Joins the voice channel you are in.') async def join(self, inter): await self.create_player(inter) await inter.response.send_message("Joined the voice channel.") @commands.slash_command(name='volume', description='Sets the player volume.') async def volume(self, inter: Interaction, volume: int): player = self.bot.lavalink.player_manager.get(inter.guild.id) if not player.is_connected: return await inter.response.send_message("I'm not connected to a voice channel.") if volume < 0 or volume > 1000: return await inter.response.send_message("Volume must be between 0 and 100.") await player.set_volume(volume) await inter.response.send_message(f"Set the player volume to {volume}%.") @commands.slash_command(name='pause', description='Pauses the current track.') async def pause(self, inter: Interaction): player = self.bot.lavalink.player_manager.get(inter.guild.id) if not player.is_connected: return await inter.response.send_message("I'm not connected to a voice channel.") if not player.is_playing: return await inter.response.send_message("There's no track playing right now.") await player.set_pause(True) await inter.response.send_message("Paused the current track.") @commands.slash_command(name='resume', description='Resumes the current track.') async def continue_(self, inter: Interaction): player = self.bot.lavalink.player_manager.get(inter.guild.id) if not player.is_connected: return await inter.response.send_message("I'm not connected to a voice channel.") if not player.is_playing: return await inter.response.send_message("There's no track playing right now.") await player.set_pause(False) await inter.response.send_message("Resumed the current track.") @commands.slash_command(name='loop', description='Toggles looping the current track.') async def loop(self, inter: Interaction): player = self.bot.lavalink.player_manager.get(inter.guild.id) if not player.is_connected: return await inter.response.send_message("I'm not connected to a voice channel.") if not player.is_playing: return await inter.response.send_message("There's no track playing right now.") player.set_loop(not player.loop) loop_state = "enabled" if player.loop else "disabled" await inter.response.send_message(f"Looping is now {loop_state}.") def setup(bot): bot.add_cog(Music(bot))
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)