How to Make My Discord.Py Bot Play Mp3 in Voice Channel

How do i make a bot from discord.py play music in my voice chat?

Idk how to solve that either, but if u need a play music command from yt, you can use my code here, just change the description and the command name.

@client.command()
async def playyt(ctx, url):
song_there = os.path.isfile("song.mp3")
try:
if song_there:
os.remove("song.mp3")
except PermissionError:
em8 = discord.Embed(title = "Music Is Currently Playing", description = 'Please wait for the current playing music to end or use %leave <:_Paimon6:827074349450133524>.\nMusic provided by {ctx.author.mention} <:_Paimon6:827074349450133524>',color = ctx.author.color)
await ctx.send(embed = em8)
return

voiceChannel = discord.utils.get(ctx.guild.voice_channels)
await voiceChannel.connect()
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
em6 = discord.Embed(title = "Downloading Youtube Music", description = f'{url}\n\nPlease wait for paimon to setup the music you provide.\nMusic provided by {ctx.author.mention} <:_Paimon6:827074349450133524>',color = ctx.author.color)
await ctx.send(embed = em6, delete_after = 2)
await ctx.message.delete()

ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '196',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
for file in os.listdir("./"):
if file.endswith(".mp3"):
os.rename(file, "song.mp3")
voice.play(discord.FFmpegPCMAudio("song.mp3"))
em1 = discord.Embed(title = "Now Listening Youtube Music", description = f'{url}\n\nPlease use %leave first to change music.\nMusic provided by {ctx.author.mention} <:_Paimon6:827074349450133524>',color = ctx.author.color)

videoID = url.split("watch?v=")[1].split("&")[0]

em1.set_thumbnail(url = f'https://img.youtube.com/vi/{videoID}/default.jpg'.format(videoID = videoID))
await ctx.send(embed = em1)

How to make the discord bot queue local mp3?

Seen as if you're not using cogs, you could try something like this:

guild_queues = {}  # Multi-server support as a dict, just use a list for one server

# EDIT: Map song names in a dict
play_messages = {
"song1": "Now playing something cool!",
"song2": "And something even cooler just started playing!",
"song3": "THE COOLEST!"
}


async def handle_queue(ctx, song):
voice = discord.utils.get(bot.voice_clients, guild=ctx.guild)
channel = ctx.author.voice.channel
if voice and channel and voice.channel != channel:
await voice.move_to(channel)
elif not voice and channel:
voice = await channel.connect()
if not voice.is_playing():
audio = discord.FFmpegPCMAudio(f"./{song}.mp3")
source = discord.PCMVolumeTransformer(audio)
source.volume = 0.1
voice.play(audio)
await ctx.send(play_messages[song])
while voice.is_playing():
await asyncio.sleep(.1)
if len(guild_queues[ctx.guild.id]) > 0:
next_song = guild_queues[ctx.guild.id].pop(0)
await handle_queue(ctx, next_song)
else:
await voice.disconnect()


@bot.command()
async def play(ctx, *, song): # I'd recommend adding the filenames as an arg, but it's up to you
# Feel free to add a check if the filename exists
try:
# Get the current guild's queue
queue = guild_queues[ctx.guild.id]
except KeyError:
# Create a queue if it doesn't already exist
guild_queues[ctx.guild.id] = []
queue = guild_queues[ctx.guild.id]

voice = discord.utils.get(bot.voice_clients, guild=ctx.guild)
queue.append(song)
# The one song would be the one currently playing
if voice and len(queue) > 0:
await ctx.send("Added to queue!")
else:
current_song = queue.pop(0)
await handle_queue(ctx, current_song)


References:

  • utils.get()
  • Client.voice_clients
  • Context.guild
  • Member.voice
  • VoiceState.channel
  • VoiceClient.move_to()
  • VoiceClient.is_playing()
  • VoiceClient.play()
  • discord.FFmpegPCMAudio()
  • discord.PCMVolumeTransformer()
  • Context.send()

Issue playing local audio file in Discord bot

I assume you didn't the discord.py with voice support, use this pip command to download the package:

pip install discord.py[voice]

how to play gtts mp3 file in discord voice channel the user is in (discord.py)

So, firstly you should put any imports at the start of your file (Same area you import discord)

Now onto the code, I will simplify it a bit. My code does not ask the user for text, instead this code uses the input called after the command. I.e !repeat Hello will speak hello in the voice channel

First, here is some code to connect to a voice channel. For this purpose, we will keep it separate. This is some nice code, and somewhat better then the gtts code I will attempt.

@bot.command()
async def connect(ctx, *, channel: discord.VoiceChannel=None):
"""
Connect to a voice channel
This command also handles moving the bot to different channels.

Params:
- channel: discord.VoiceChannel [Optional]
The channel to connect to. If a channel is not specified, an attempt to join the voice channel you are in
will be made.
"""
if not channel:
try:
channel = ctx.author.voice.channel
except AttributeError:
raise InvalidVoiceChannel('No channel to join. Please either specify a valid channel or join one.')

vc = ctx.voice_client

if vc:
if vc.channel.id == channel.id:
return
try:
await vc.move_to(channel)
except asyncio.TimeoutError:
raise VoiceConnectionError(f'Moving to channel: <{channel}> timed out.')
else:
try:
await channel.connect()
except asyncio.TimeoutError:
raise VoiceConnectionError(f'Connecting to channel: <{channel}> timed out.')

await ctx.send(f'Connected to: **{channel}**', delete_after=20)

Cool, so now we can connect to the channel. So here's my go at actually doing some gtts work. I wont talk to much, it is all commented. However, if theres an issue just leave a comment :)

The following is the required import from gtts import gTTS

@bot.command()
async def repeat(ctx, *, text=None):
"""
A command which saves `text` into a speech file with
gtts and then plays it back in the current voice channel.

Params:
- text [Optional]
This will be the text we speak in the voice channel
"""
if not text:
# We have nothing to speak
await ctx.send(f"Hey {ctx.author.mention}, I need to know what to say please.")
return

vc = ctx.voice_client # We use it more then once, so make it an easy variable
if not vc:
# We are not currently in a voice channel
await ctx.send("I need to be in a voice channel to do this, please use the connect command.")
return

# Lets prepare our text, and then save the audio file
tts = gTTS(text=text, lang="en")
tts.save("text.mp3")

try:
# Lets play that mp3 file in the voice channel
vc.play(discord.FFmpegPCMAudio('text.mp3'), after=lambda e: print(f"Finished playing: {e}"))

# Lets set the volume to 1
vc.source = discord.PCMVolumeTransformer(vc.source)
vc.source.volume = 1

# Handle the exceptions that can occur
except ClientException as e:
await ctx.send(f"A client exception occured:\n`{e}`")
except TypeError as e:
await ctx.send(f"TypeError exception:\n`{e}`")
except OpusNotLoaded as e:
await ctx.send(f"OpusNotLoaded exception: \n`{e}`")

Now, in order to leave the current voice channel you can do the following

@bot.command()
async def disconnect(ctx):
"""
Disconnect from a voice channel, if in one
"""
vc = ctx.voice_client

if not vc:
await ctx.send("I am not in a voice channel.")
return

await vc.disconnect()
await ctx.send("I have left the voice channel!")

discord.py | play audio from url

use pafy.

First import some stuff and set FFmpeg options...

import pafy
from discord import FFmpegPCMAudio, PCMVolumeTransformer


FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5','options': '-vn'}

Then play it

@commands.command(name='test')
async def test(self, ctx):

search = "morpheus tutorials discord bot python"

if ctx.message.author.voice == None:
await ctx.send(embed=Embeds.txt("No Voice Channel", "You need to be in a voice channel to use this command!", ctx.author))
return

channel = ctx.message.author.voice.channel

voice = discord.utils.get(ctx.guild.voice_channels, name=channel.name)

voice_client = discord.utils.get(self.client.voice_clients, guild=ctx.guild)

if voice_client == None:
voice_client = await voice.connect()
else:
await voice_client.move_to(channel)

search = search.replace(" ", "+")

html = urllib.request.urlopen("https://www.youtube.com/results?search_query=" + search)
video_ids = re.findall(r"watch\?v=(\S{11})", html.read().decode())


await ctx.send("https://www.youtube.com/watch?v=" + video_ids[0])

song = pafy.new(video_ids[0]) # creates a new pafy object

audio = song.getbestaudio() # gets an audio source

source = FFmpegPCMAudio(audio.url, **FFMPEG_OPTIONS) # converts the youtube audio source into a source discord can use

voice_client.play(source) # play the source



Related Topics



Leave a reply



Submit