I'm making a music bot with discord.py and I'm trying to use an except: statement to figure out if it is a valid url or not so I know to search for it or not. I'm trying to figure out what exception to put in the statement but when I try discord.ext.commands.errors.CommandInvokeError(e) there is a syntax error saying that e is not defined. I know that I can leave the space after the except: keyword blank but I want to try and figure it out because flake8 is highlighting it. Please help.
Here is a picture of the syntax highlight.
Here is the code:
import discord
from discord.ext import commands
import youtube_dl
import os
client = commands.Bot(command_prefix="?")
#client.event
async def on_ready():
print("Bot is ready.")
game = discord.Game("Music")
await client.change_presence(activity=game)
#client.command()
async def play(ctx, url: str = None):
if url is None:
await ctx.send("Put YouTube video's link after the \"play\" command.")
return
song_there = os.path.isfile("song.mp3")
try:
if song_there:
os.remove("song.mp3")
except PermissionError:
await ctx.send("Wait for the currently playing music to end or use the #\"stop\" command.")
channel = discord.utils.get(ctx.guild.voice_channels, name="music lounge")
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice is not None:
if not voice.is_connected():
voice = await channel.connect()
else:
voice = await channel.connect()
ydl_opts = {
"format": "bestaudio",
"postprocessors": [{
"key": "FFmpegExtractAudio",
"preferredcodec": "mp3",
"preferredquality": "192"
}]
}
try:
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
await ctx.send("Downloaded music...")
except:
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info_dict = ydl.extract_info(f"ytsearch: {url}", download=True)
for url in info_dict["entries"]:
print()
title = info_dict.get("entries")[0].get("title")
await ctx.send(f"Downloaded {title}")
for file in os.listdir("./"):
if file.endswith(".mp3"):
os.rename(file, "song.mp3")
voice.play(discord.FFmpegPCMAudio("song.mp3"))
#client.command()
async def leave(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice is not None:
if voice.is_connected():
await voice.disconnect()
else:
await ctx.send("The bot is not connected to a voice channel.")
#client.command()
async def pause(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice is not None:
if voice.is_playing():
voice.pause()
else:
await ctx.send("Currently no audio is playing.")
else:
await ctx.send("The bot is not connected to a voice channel.")
#client.command()
async def resume(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice is not None:
if voice.is_paused():
voice.resume()
else:
await ctx.send("The audio is not paused.")
else:
await ctx.send("The bot is not connected to a voice channel.")
#client.command()
async def stop(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice is not None:
if voice.is_playing():
voice.stop()
else:
await ctx.send("Currently no audio is playing.")
else:
await ctx.send("The bot is not connected to a voice channel.")
client.run("TOKEN")
Related
I'm looking for a way to add the following to my music bot:
A queue function, allowing songs to be inputted while another plays. This would then go through the play function after the first song ends
Being able to display this queue
Removing songs from/changing positions of the songs in the queue
How would I go about doing this? Below is my code.
from discord.ext import commands
from dotenv import load_dotenv
from keep_alive import keep_alive
from youtube_dl import YoutubeDL
from discord.utils import get
load_dotenv()
TOKEN = os.getenv('TOKEN')
bot = commands.Bot(command_prefix='!', case_insensitive=True)
#bot.event
async def on_ready():
print(f'{bot.user} has successfully connected to Discord!')
#bot.command(aliases=['p'])
async def play(ctx, url: str = None):
YDL_OPTIONS = {'format': 'bestaudio/best', 'noplaylist':'True'}
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
voice = get(bot.voice_clients, guild=ctx.guild)
try:
channel = ctx.message.author.voice.channel
except AttributeError:
await ctx.send('Bruh, join a voice channel')
return None
if not voice:
await channel.connect()
await ctx.send("Music/Audio will begin shortly, unless no URL provided.")
voice = get(bot.voice_clients, guild=ctx.guild)
with YoutubeDL(YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
I_URL = info['formats'][0]['url']
source = await discord.FFmpegOpusAudio.from_probe(I_URL, **FFMPEG_OPTIONS)
voice.play(source)
voice.is_playing()
await ctx.send("Playing audio.")
#bot.command()
async def pause(ctx):
voice = discord.utils.get(bot.voice_clients, guild=ctx.guild)
if voice.is_playing():
voice.pause()
await ctx.send("Audio is paused.")
if voice.is_not_playing():
await ctx.send("Currently no audio is playing.")
#bot.command()
async def resume(ctx):
voice = discord.utils.get(bot.voice_clients, guild=ctx.guild)
if voice.is_paused():
voice.resume()
await ctx.send("Resumed audio.")
if voice.is_not_paused():
await ctx.send("The audio is not paused.")
#bot.command()
async def stop(ctx):
voice = discord.utils.get(bot.voice_clients, guild=ctx.guild)
voice.stop()
await ctx.send("Stopped playback.")
#bot.command(aliases=['l'])
async def leave(ctx):
voice = discord.utils.get(bot.voice_clients, guild=ctx.guild)
await voice.disconnect()
await ctx.send("Left voice channel.")
keep_alive()
bot.run(TOKEN
first you need to create an empty queue outside your command
queues = {}
and a function to check if there's a song in queues it will play that song
#check queue
queues = {}
def check_queue(ctx, id):
if queues[id] !={}:
voice = ctx.guild.voice_client
source = queues[id].pop(0)
voice.play(source, after=lambda x=0: check_queue(ctx, ctx.message.guild.id))
and inside the play command create a function to add the next song to queue if a song is already being played and add the check queue function
if voice.is_playing():
guild_id = ctx.message.guild.id
if guild_id in queues:
queues[guild_id].append(source)
else:
queues[guild_id] = [source]
else:
voice.play(source, after=lambda x=0: check_queue(ctx, ctx.message.guild.id))
This way is to create a queue and play the next only and still cant display or change the queue
Need help Discord bot queue
I made so it connects to the voice channel by the command .join and it supposed to play a sound that i saved. This is made for a voice channel with chill music so that they don't have to copy and paste a YouTube link. I am using python 3.9
import discord
from discord.ext import commands
bot = discord.Client()
bot = commands.Bot(command_prefix=".")
#bot.command()
async def join(ctx):
if ctx.author.voice is None:
await ctx.send("You are not in a voice channel")
voice_channel = ctx.author.voice.channel
if ctx.voice_client is None:
await voice_channel.connect()
guild = ctx.guild
voice_client: discord.VoiceClient = discord.utils.get(bot.voice_clients, guild=guild)
audio_source = discord.FFmpegPCMAudio('music.mp3')
if not voice_client.is_playing():
voice_client.play(audio_source, after=None)
else:
await ctx.voice_client.move_to(voice_channel)
bot.run("token")
Try this instead:
import discord
from discord.ext import commands
from youtube_dl import YoutubeDL
bot = discord.Client()
bot = commands.Bot(command_prefix=".")
#bot.command()
async def join(ctx):
if ctx.author.voice is None:
await ctx.send("You are not in a voice channel")
return
voice_channel = ctx.author.voice.channel
if ctx.voice_client is None:
await voice_channel.connect()
else:
await ctx.voice_client.move_to(voice_channel)
audio_source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio('music.mp3'))
if not ctx.voice_client.is_playing():
ctx.voice_client.play(audio_source, after=lambda e: print('Player error: %s' % e) if e else None)
bot.run("token")
I'm trying to connect my discord bot to a voice channel, but it's not working.
There isn't any error or anything, nothing happens when I do !join on my discord channel.
Here is my code. I tried looking for some tutorials, but most seems outdated.
Could someone help me?
import discord
from discord.ext import commands
from discord.utils import get
import os
token = os.environ.get('DISCORD_TOKEN')
client = commands.Bot(command_prefix='!')
#client.command(pass_context=True)
async def join(ctx):
channel = ctx.message.author.voice.channel
voice = get(client.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
await ctx.send(f'Joined {channel}')
client.run(token)
Edit:
import discord
from discord.ext import commands
from discord.utils import get
import os
import youtube_dl
token = os.environ.get('DISCORD_TOKEN')
client = commands.Bot(command_prefix='!')
#client.event
async def on_message(message):
channels = ['bot-commands']
if str(message.channel) in channels:
if message.content == '!help':
embed = discord.Embed(title='How to use the ImposterBot', description='Useful Commands')
embed.add_field(name='!help', value='Display all the commands')
embed.add_field(name='!music', value='Play a music playlist')
embed.add_field(name='!valorant', value='Get the most recent version of Valorant stats')
embed.add_field(name='!hello', value='Greet a user')
await message.channel.send(content=None, embed=embed)
elif message.content == '!hello':
await message.channel.send(f'Greeting, {message.author}!')
elif message.content == '!valorant':
await message.channel.send('This feature is not ready yet')
elif message.content == '!music':
await message.channel.send('This feature is not ready yet')
elif 'sustin' in message.content:
await message.channel.send(f"""it's sustin... {"<:monkas:392806765789446144>"} """)
#client.command(pass_context=True)
async def join(ctx):
channel = ctx.message.author.voice.channel
voice = get(client.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
await ctx.send(f'Joined {channel}')
client.run(token)
The error in this code is that commands will not be invoked by the bot if there is an on_message event, unless that event begins with this line:
async def on_message(message):
await bot.process_commands(message)
I want to make a bot play a piece of audio and, when the audio finishes, it will replay the audio.
What I have:
#client.command()
async def play(ctx):
await ctx.channel.purge(limit=1)
channel = ctx.author.voice.channel
if channel:
print(channel.id)
await channel.connect()
guild = ctx.guild
audio_source = discord.FFmpegPCMAudio('audio.mp3')
voice_client: discord.VoiceClient = discord.utils.get(client.voice_clients, guild=guild)
if not voice_client.is_playing():
voice_client.play(audio_source, after=None)
discord.VoiceClient.Play() has an after parameter that is called when the audio stream ends. Normally, it should be used to display error messages but you can use it to repeat the song like so:
#client.command()
async def play(ctx):
await ctx.channel.purge(limit=1)
channel = ctx.author.voice.channel
voice = get(self.bot.voice_clients, guild=ctx.guild)
def repeat(guild, voice, audio):
voice.play(audio, after=lambda e: repeat(guild, voice, audio))
voice.is_playing()
if channel and not voice.is_playing():
audio = discord.FFmpegPCMAudio('audio.mp3')
voice.play(audio, after=lambda e: repeat(ctx.guild, voice, audio))
voice.is_playing()
Here is the command
It passes no errors but still doesn't play any audio
#bot.command(pass_context=True,aliases=["Play,Song"])
async def playSongs(ctx):
channel = ctx.message.author.voice.channel
if not channel:
await ctx.send("You are not connected to a voice channel")
return
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
source = FFmpegPCMAudio('song.m4a')
player = voice.play(source)