Discord.py send youtube thumbnail in embed message - python

Im trying to learn on how to make a music bot, the play command is alr fine but the youtube thumbnail pic doesnt show when the url is given in embed message. Idk whats the function to make the bot show the youtube video thumbnail into the embed message. Heres the code :
#client.command()
async def play(ctx, url : str):
song_there = os.path.isfile("song.mp3")
try:
if song_there:
os.remove("song.mp3")
except PermissionError:
await ctx.send("Wait for the current playing music to end or use %leave <:_Paimon6:827074349450133524>")
return
voiceChannel = discord.utils.get(ctx.guild.voice_channels, name='Private')
await voiceChannel.connect()
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
em6 = discord.Embed(title = "Downloading 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)
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
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", description = f'{url}\n\nPlease use %leave first to change music.\nMusic provided by {ctx.author.mention} <:_Paimon6:827074349450133524>',color = ctx.author.color)
await ctx.send(embed = em1)

Anyways, I think you're looking for the .set_image() method.
You can get a link to the thumbnail of a youtube video via
https://img.youtube.com/vi/<insert-youtube-video-id-here>/0.jpg
Like explained here.
Retrieve the id of the youtube video via
videoID = url.split("watch?v=")[1].split("&")[0]
And then you can set it as the embed image or thumbnail.
In your case it should look like this
#client.command()
async def play(ctx, url : str):
song_there = os.path.isfile("song.mp3")
try:
if song_there:
os.remove("song.mp3")
except PermissionError:
await ctx.send("Wait for the current playing music to end or use %leave <:_Paimon6:827074349450133524>")
return
voiceChannel = discord.utils.get(ctx.guild.voice_channels, name='Private')
await voiceChannel.connect()
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
em6 = discord.Embed(title = "Downloading 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)
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
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", description = f'{url}\n\nPlease use %leave first to change music.\nMusic provided by {ctx.author.mention} <:_Paimon6:827074349450133524>',color = ctx.author.color)
# get id
videoID = url.split("watch?v=")[1].split("&")[0]
em1.set_image(url = "https://img.youtube.com/vi/{videoID}/0.jpg".format(videoID = videoID))
await ctx.send(embed = em1)
If you find this image too big, you could also set it as a thumbnail via
embed.set_thumbnail(url)

Related

youtubedl stuck on 'downloading webpage' in python music bot

I have everything setup, and everything installed properly. When I try to run the bot with !play command, the traceback is just on downloading web page. no errors at all. I'm suspecting it might be an error with the source, but I am not sure.
#commands.command()
async def play(self, ctx, url):
if ctx.voice_client is None:
if ctx.author.voice:
await ctx.author.voice.channel.connect()
else:
await ctx.send("You're not connected to a voice channel.")
raise commands.CommandError("Author not connected to voice channel.")
elif ctx.voice_client.is_playing():
ctx.voice_client.stop()
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnected_delay_max 5', 'options': '-vn'}
YDL_OPTIONS = {'format':"bestaudio"}
vc = ctx.voice_client
with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
info = ydl.extract_info(url, download=False)
url2 = info["formats"][0]['url']
source = await discord.FFmpegOpusAudio.from_probe(url2, **FFMPEG_OPTIONS)
vc.play(source)
I changed your code a little bit.
You will need the YoutubeSearch module
pip install youtube-search
from youtube_search import YoutubeSearch
#client.command()
async def play(ctx,*, song):
voice_state = ctx.member.voice
if voice_state == None:
await ctx.send("You are not in a voice channel!")
return
if voice_state != None:
await ctx.author.voice.channel.connect()
results = YoutubeSearch(song, max_results=1).to_dict()
print(results)
song_name = results[0]['title']
url_suffix = results[0]['url_suffix']
url = "https://youtube.com"+url_suffix
playinge = discord.Embed(
title = "Now Playing",
description = f"[{song_name}]({url})",
color = discord.Colour.green()
)
ydl_opts = {'format': 'bestaudio'}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(url, download=False)
URL = info['formats'][0]['url']
vc = ctx.voice_client
vc.play(discord.FFmpegPCMAudio(URL))
await ctx.send(embed=playinge)
Try this.

Unsupported link: Spotify, Discord.py Music Bot

I'm making a discord bot. But I'm having spotify issue.
its says
"spotdl: error: unrecognized arguments: -s: (music link)"
I've installed pip youtubedl,spotdl, every pip I needed.
I'm making this bot for my discord server.
Please help me.
I've learned this from this Youtube link. In this tutorial, bot was working fine. But not mine. What should I do now?
import os
import shutil
from os import system
import discord
import youtube_dl
from discord.ext import commands
from discord.utils import get
TOKEN = 'TOKEN'
BOT_PREFIX = '.'
bot = commands.Bot(command_prefix=BOT_PREFIX)
#bot.event
async def on_ready():
print("Logged in as: " + bot.user.name + "\n")
#bot.command(pass_context=True, aliases=['j', 'joi'])
async def join(ctx):
global voice
channel = ctx.message.author.voice.channel
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
await voice.disconnect()
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
print(f"The bot has connected to {channel}\n")
await ctx.send(f"Joined {channel}")
#bot.command(pass_context=True, aliases=['l', 'lea'])
async def leave(ctx):
channel = ctx.message.author.voice.channel
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.disconnect()
print(f"The bot has left {channel}")
await ctx.send(f"Left {channel}")
else:
print("Bot was told to leave voice channel, but was not in one")
await ctx.send("Don't think I am in a voice channel")
#bot.command(pass_context=True, aliases=['p', 'pla'])
async def play(ctx, url: str):
def check_queue():
Queue_infile = os.path.isdir("./Queue")
if Queue_infile is True:
DIR = os.path.abspath(os.path.realpath("Queue"))
length = len(os.listdir(DIR))
still_q = length - 1
try:
first_file = os.listdir(DIR)[0]
except:
print("No more queued song(s)\n")
queues.clear()
return
main_location = os.path.dirname(os.path.realpath(__file__))
song_path = os.path.abspath(os.path.realpath("Queue") + "\\" + first_file)
if length != 0:
print("Song done, playing next queued\n")
print(f"Songs still in queue: {still_q}")
song_there = os.path.isfile("song.mp3")
if song_there:
os.remove("song.mp3")
shutil.move(song_path, main_location)
for file in os.listdir("./"):
if file.endswith(".mp3"):
os.rename(file, 'song.mp3')
voice.play(discord.FFmpegPCMAudio("song.mp3"), after=lambda e: check_queue())
voice.source = discord.PCMVolumeTransformer(voice.source)
voice.source.volume = 100.00
else:
queues.clear()
return
else:
queues.clear()
print("No songs were queued before the ending of the last song\n")
song_there = os.path.isfile("song.mp3")
try:
if song_there:
os.remove("song.mp3")
queues.clear()
print("Removed old song file")
except PermissionError:
print("Trying to delete song file, but it's being played")
await ctx.send("ERROR: Music playing")
return
Queue_infile = os.path.isdir("./Queue")
try:
Queue_folder = "./Queue"
if Queue_infile is True:
print("Removed old Queue Folder")
shutil.rmtree(Queue_folder)
except:
print("No old Queue folder")
await ctx.send("Getting everything ready now")
voice = get(bot.voice_clients, guild=ctx.guild)
ydl_opts = {
'format': 'bestaudio/best',
'quiet': True,
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
try:
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
print("Downloading audio now\n")
ydl.download([url])
except:
print("FALLBACK: youtube-dl does not support this URL, using Spotify (This is normal if Spotify URL)")
c_path = os.path.dirname(os.path.realpath(__file__))
system("spotdl -f " + '"' + c_path + '"' + " -s " + url)
for file in os.listdir("./"):
if file.endswith(".mp3"):
name = file
print(f"Renamed File: {file}\n")
os.rename(file, "song.mp3")
voice.play(discord.FFmpegPCMAudio("song.mp3"), after=lambda e: check_queue())
voice.source = discord.PCMVolumeTransformer(voice.source)
voice.source.volume = 0.07
nname = name.rsplit("-", 2)
await ctx.send(f"Playing: {nname[0]}")
print("playing\n")
#bot.command(pass_context=True, aliases=['pa', 'pau'])
async def pause(ctx):
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_playing():
print("Music paused")
voice.pause()
await ctx.send("Music paused")
else:
print("Music not playing failed pause")
await ctx.send("Music not playing failed pause")
#bot.command(pass_context=True, aliases=['r', 'res'])
async def resume(ctx):
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_paused():
print("Resumed music")
voice.resume()
await ctx.send("Resumed music")
else:
print("Music is not paused")
await ctx.send("Music is not paused")
#bot.command(pass_context=True, aliases=['s', 'sto'])
async def stop(ctx):
voice = get(bot.voice_clients, guild=ctx.guild)
queues.clear()
queue_infile = os.path.isdir("./Queue")
if queue_infile is True:
shutil.rmtree("./Queue")
if voice and voice.is_playing():
print("Music stopped")
voice.stop()
await ctx.send("Music stopped")
else:
print("No music playing failed to stop")
await ctx.send("No music playing failed to stop")
queues = {}
#bot.command(pass_context=True, aliases=['q', 'que'])
async def queue(ctx, url: str):
Queue_infile = os.path.isdir("./Queue")
if Queue_infile is False:
os.mkdir("Queue")
DIR = os.path.abspath(os.path.realpath("Queue"))
q_num = len(os.listdir(DIR))
q_num += 1
add_queue = True
while add_queue:
if q_num in queues:
q_num += 1
else:
add_queue = False
queues[q_num] = q_num
queue_path = os.path.abspath(os.path.realpath("Queue") + f"\song{q_num}.%(ext)s")
ydl_opts = {
'format': 'bestaudio/best',
'quiet': True,
'outtmpl': queue_path,
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
try:
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
print("Downloading audio now\n")
ydl.download([url])
except:
print("FALLBACK: youtube-dl does not support this URL, using Spotify (This is normal if Spotify URL)")
q_path = os.path.abspath(os.path.realpath("Queue"))
system(f"spotdl -ff song{q_num} -f " + '"' + q_path + '"' + " -s " + url)
await ctx.send("Adding song " + str(q_num) + " to the queue")
print("Song added to queue\n")
#bot.command(pass_context=True, aliases=['n', 'nex'])
async def next(ctx):
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_playing():
print("Playing Next Song")
voice.stop()
await ctx.send("Next Song")
else:
print("No music playing")
await ctx.send("No music playing failed")
bot.run('TOKEN')
Hello Md Sadman Muhtasim Billah!
Well, it seems like the problem is actually in the URL you're submitting, as it don't recognize the '-s' argument, not the parameter itself.
So you should probably try the same URL he uses in the YouTube video you sent, to test it. Or try other links.
I couldn't find a flaw in the code, and it really is the same used in the YT tutorial.
Hope I helped. :)

Discord.py making a queue command

I am in the process of making a discord.py music bot (my first) and am wondering how to make a queue. I'm guessing that it has something to do with the asyncio command (import asyncio) but I really don't know.
from discord.ext import commands
from discord.utils import get
import asyncio
import youtube_dl
import os
bot = commands.Bot(command_prefix='>')
bot.remove_command('help')
#bot.event
async def on_ready():
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=">help"))
print("Bot is online! Logged in as: " + bot.user.name + "\n")
#bot.command(pass_context=True)
async def ping(ctx):
await ctx.send(f'**Pong!** Latency: {round(bot.latency * 1000)}ms')
#bot.command(pass_context=True, aliases=['j'])
async def join(ctx):
channel = ctx.message.author.voice.channel
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
await voice.disconnect()
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
#bot.command(pass_context=True, aliases=['l'])
async def leave(ctx):
channel = ctx.message.author.voice.channel
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.disconnect()
else:
print("Bot was told to leave voice channel, but was not in one.")
await ctx.send("OneBeat is not connected to a voice channel. Connect OneBeat to a voice channel before using this command.")
#bot.command(pass_context=True, aliases=['p'])
async def play(ctx, url: str):
channel = ctx.message.author.voice.channel
voice = get(bot.voice_clients, guild=ctx.guild)
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
await voice.disconnect()
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
song_there = os.path.isfile("song.mp3")
try:
if song_there:
os.remove("song.mp3")
print("Removed old song file.")
except PermissionError:
print("Trying to delete song file, but it's being played")
await ctx.send("Error: Music is already playing (Queue feature coming soon).")
return
await ctx.send("One second...")
voice = get(bot.voice_clients, guild=ctx.guild)
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
print("Downloading audio now\n")
ydl.download([url])
for file in os.listdir("./"):
if file.endswith(".mp3"):
name = file
print(f"Renamed File: {file}\n")
os.rename(file, "song.mp3")
voice.play(discord.FFmpegPCMAudio("song.mp3"), after=lambda e: print("Song done!"))
voice.source = discord.PCMVolumeTransformer(voice.source)
voice.source.volume = 0.5
nname = name.rsplit("-", 2)
await ctx.send(f"Now playing: {nname[0]}")
print("Playing\n")
bot.run('token')
Not really! I have no idea how to use asyncio and I still managed to make queues. My way of doing it is to have a json file that contains dictionaries and lists. Which looks something like this:
{
"queueskey": [
{
"channelid": [],
"queue": [],
"status": []
},
{
"channelid": [],
"queue": [],
"status": []
},
{
"channelid": [],
"queue": [],
"status": []
}
]
}
Something like that repeating over and over again. You can also have extra info stored as well with that. Though it took me quite some time to debug and make the thing work, I'd say this is one of the simplest ways of doing it.

Need help making a discord music bot

I'm making a music bot, and, im struggling with some parts. I don't know how to make the skip part or play the next song in the queue once the current one ends. Any help?
Here is all the code (all of it because just in case)
The queue part is near the bottom, the skip part is also near the bottom and playing the song is right below here.
import os
import re
import urllib.request
import youtube_dl
import shutil
import discord
from discord.ext import commands
from discord.utils import get
bot = commands.Bot(command_prefix='g.')
token = '<mytoken>'
#bot.command(pass_context=True)
async def play(ctx, *args: str):
search = '+'.join(args)
print(search)
if search == " ":
await ctx.send("Uso: g.play (Video)")
return
else:
html = urllib.request.urlopen("https://www.youtube.com/results?search_query=" + search)
video_ids = re.findall(r"watch\?v=(\S{11})", html.read().decode())
url = "https://www.youtube.com/watch?v=" + video_ids[0]
print(url)
def check_queue():
Queue_infile = os.path.isdir("./Queue")
if Queue_infile is True:
DIR = os.path.abspath(os.path.realpath("Queue"))
length = len(os.listdir(DIR))
still_q = length - 1
try:
first_file = os.listdir(DIR)[0]
except:
print("No more queued song(s)\n")
queues.clear()
return
main_location = os.path.dirname(os.path.realpath(__file__))
song_path = os.path.abspath(os.path.realpath("Queue") + "\\" + first_file)
if length != 0:
print("Song done, playing next queued\n")
print(f"Songs still in queue: {still_q}")
song_there = os.path.isfile("song.mp3")
if song_there:
os.remove("song.mp3")
shutil.move(song_path, main_location)
for file in os.listdir("./"):
if file.endswith(".mp3"):
os.rename(file, 'song.mp3')
enfile = file
voice.play(discord.FFmpegPCMAudio("song.mp3"), after=lambda e: check_queue())
voice.source = discord.PCMVolumeTransformer(voice.source)
voice.source.volume = 0.07
print(f"Playing {nname[0]}")
else:
queues.clear()
return
else:
queues.clear()
print("No songs were queued before the ending of the last song\n")
song_there = os.path.isfile("song.mp3")
try:
if song_there:
os.remove("song.mp3")
queues.clear()
print("Removed old song file")
except PermissionError:
print("Trying to delete song file, but it's being played.")
print("ERROR: Music Playing")
await ctx.send("Error: Ya estoy poniendo musica! Usa g.queue (cancion) para agregar una cancion a la lista.")
search = ' '.join(args)
channel = ctx.message.channel
return
Queue_infile = os.path.isdir("./Queue")
try:
Queue_folder = "./Queue"
if Queue_infile is True:
print("Removed old Queue Folder")
shutil.rmtree(Queue_folder)
except:
print("No old queue folder.")
print("Getting everytihng ready now.")
await ctx.send("Preparando cancion...")
voice = get(bot.voice_clients, guild=ctx.guild)
ydl_opts = {
'format': 'bestaudio/best',
'quiet': True,
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
print("Downloading audio now\n")
ydl.download([url])
for file in os.listdir("./"):
if file.endswith(".mp3"):
name = file
print(f"Renamed file: {file}\n")
os.rename(file, "song.mp3")
nfile = file
print(str(voice))
channel = ctx.message.author.voice.channel
voice.play(discord.FFmpegPCMAudio("song.mp3"), after=lambda e: check_queue())
voice.source = discord.PCMVolumeTransformer(voice.source)
voice.source.volume = 0.3
nname = name.rsplit("-", 2)
print(f"Playing {nname[0]}")
await embed(ctx, url, nfile, video_ids[0])
queues = {}
#bot.command(pass_context=True)
async def queue(ctx, *searchs):
search = '+'.join(searchs)
Queue_infile = os.path.isdir("./Queue")
if Queue_infile is False:
os.mkdir("Queue")
DIR = os.path.abspath(os.path.realpath("Queue"))
q_num = len(os.listdir(DIR))
q_num += 1
add_queue = True
while add_queue:
if q_num in queues:
q_num += 1
else:
add_queue = False
queues[q_num] = q_num
queue_path = os.path.abspath(os.path.realpath("Queue") + f"\song{q_num}.%(ext)s")
ydl_opts = {
'format': 'bestaudio/best',
'quiet': True,
'outtmpl': queue_path,
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192'
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
print("Downloading audio now\n")
html = urllib.request.urlopen("https://www.youtube.com/results?search_query=" + search)
video_ids = re.findall(r"watch\?v=(\S{11})", html.read().decode())
url = "https://www.youtube.com/watch?v=" + video_ids[0]
print(url)
ydl.download([url])
await ctx.send("AƱadiendo cancion " + str(q_num) + " a la lista!")
print("Song added to the queue:" + str(q_num))
#bot.event
async def on_ready():
print(f"""Bot {bot.user} has connected to discord!""")
bot.run(token)```
You can get code for understanding its not the proper-one but it can help you.
Music Bot Code
You will get an idea how to code these commands.

python discord music bot youtube_dl

import discord
import youtube_dl
from discord.ext import commands
-----------------------------------------------
#cat.command(pass_context=True)
async def play(ctx):
if not ctx.message.author.voice:
await ctx.send('you are not connected to a voice channel')
return
else:
channel = ctx.message.author.voice.channel
await channel.connect()
server = ctx.message.guild
voice_channel = server.voice.client
async with ctx.typing():
player = await YTDLSource.from_url(url, loop = client.loop)
voice_channel.play(player)
await ctx.send(f'**Music:**{player.title}')
Is there any way to fix this error?
AttributeError: 'Guild' object has no attribute 'voice'
Check this working example.
import discord
import youtube_dl
from discord.ext import commands
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
def endSong(guild, path):
os.remove(path)
#cat.command(pass_context=True)
async def play(ctx, url):
if not ctx.message.author.voice:
await ctx.send('you are not connected to a voice channel')
return
else:
channel = ctx.message.author.voice.channel
voice_client = await channel.connect()
guild = ctx.message.guild
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
file = ydl.extract_info(url, download=True)
path = str(file['title']) + "-" + str(file['id'] + ".mp3")
voice_client.play(discord.FFmpegPCMAudio(path), after=lambda x: endSong(guild, path))
voice_client.source = discord.PCMVolumeTransformer(voice_client.source, 1)
await ctx.send(f'**Music: **{url}')
Optional, useful function
If you want you can make your bot leave the voice channel after the song stops playing. Add this at the end of your code:
while voice_client.is_playing():
await asyncio.sleep(1)
else:
await voice_client.disconnect()
print("Disconnected")
Try to replace if not ctx.message.author.voice: with if 'voice' not in ctx.message.author:

Categories