Playing music with a bot from Youtube without downloading the file - python-3.x

How would i go about playing music using a discord bot from Youtube without downloading the song as a file?
I've already had a look at the included music bot in the discord.py documentation but that one downloads a file to the directory. Is there any way to avoid this? Code from the documentation example:
ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}
ffmpeg_options = {
'options': '-vn'
}
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
self.title = data.get('title')
self.url = data.get('url')
#classmethod
async def from_url(cls, url, *, loop=None, stream=False):
loop = loop or asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download= not stream))
if 'entries' in data:
# take first item from a playlist
data = data['entries'][0]
filename = data['url'] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
#client.command()
async def play(ctx, url):
voice = await ctx.author.voice.channel.connect()
player = await YTDLSource.from_url(url, loop=client.loop)
ctx.voice_client.play(player, after=lambda e: print('Player error: %s' % e) if e else None)

To play music without downloading it, simply use this code into your play function :
ydl_opts = {'format': 'bestaudio'}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(video_link, download=False)
URL = info['formats'][0]['url']
voice = get(self.bot.voice_clients, guild=ctx.guild)
voice.play(discord.FFmpegPCMAudio(URL))
Here is what each line is used for :
ydl_opts = {'format': 'bestaudio'} : get the best possible audio
with youtube_dl.YoutubeDL(ydl_opts) as ydl: : initialize youtube-dl
info = ydl.extract_info(video_link, download=False) : get a dictionary, named info, containing all the video information (title, duration, uploader, description, ...)
URL = info['formats'][0]['url'] : get the URL which leads to the audio file of the video
voice = get(self.bot.voice_clients, guild=ctx.guild) : initialize a new audio player
voice.play(discord.FFmpegPCMAudio(URL)) : play the right music
However, Playing audio from an URL without downloading it causes a known issue explained here
To fix it, just add a variable, for instance, FFMPEG_OPTIONS which will contain options for FFMPEG:
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
Once you've created the variable, you just have to add one argument to the FFmpegPCMAudio method:
voice.play(discord.FFmpegPCMAudio(URL, **FFMPEG_OPTIONS))

Related

Discord music bot not reading the command

So, I'm trying to make a discord music bot and I keep getting this one error whenever I use the play command I think its not loading the cog or has something to do with that. this is my main function
and this is my command inside my music_player classthe error that I'm getting once I run the code
import discord
from discord.ext import commands
import os
from youtube_dl import YoutubeDL
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(
command_prefix=commands.when_mentioned_or("!"),
description='Relatively simple music bot example',
intents=intents,
)
#bot.event
async def on_ready():
print(f'Logged in as {bot.user} (ID: {bot.user.id})')
print('------')
bot.add_cog("cogs.music_player")
music_player.py
import os
import discord
from discord.ext import commands
from youtube_dl import YoutubeDL
class music_player(commands.Cog):
def __init__(self, client):
self.client = client
# Checks whether the song is playing or not
self.isplaying = False
self.ispaused = False
# The music queue ( this contains the song and the channel)
self.musicque = []
# The code below is taken from github to get the best quality of sound possible
self.ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0', # bind to ipv4 since ipv6 addresses cause issues sometimes
}
self.ffmpeg_options = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
self.vc = None
# This small function searches a song on youtube
def search_yt(self, song):
# with youtube open as
with YoutubeDL(self.ytdl_format_options) as ydl:
# This will basically search youtube and return the entries we get from our search
try:
info = ydl.extract_info("ytsearch:%s" % song, download=False)['entries'][0]
except Exception:
return False
# Returns the info as source
return {'source': info['formats'][0]['url'], 'title': info['title']}
def play_next(self):
if len(self.musicque) > 0:
self.isplaying = True
# Get the link of the first song in the que as we did in the play song function
music_link = self.musicque[0][0]['source']
# Remove the song currently playing same way we did in the play_song function
self.musicque.pop(0)
# same lambda function we used the play_song function
self.vc.play(discord.FFmpegPCMAudio(music_link, **self.ffmpeg_options), after=lambda e: self.play_next())
else:
self.isplaying = False
async def play_song(self, ctx):
if len(self.musicque) > 0:
self.isplaying = True
# Get the link of the first song in the que
music_link = self.musicque[0][0]['source']
# Connect to the voice channel the user is currently in if bot is not already connected
if self.vc == None or not self.vc.is_connected():
self.vc = await self.musicque[0][1].connect()
# if we fail to connect to the vc for whatever reason
if self.vc == None:
await ctx.send("Could not connect to the voice channel")
return
# Else if the bot is already in voice
else:
await self.vc.move_to(self.musicque[0][1])
# Remove the first song in the que using the built in pop function in python as we're already playing the song
self.musicque.pop(0)
# Took this lambda play function from github
self.vc.play(discord.FFmpegPCMAudio(music_link, **self.ffmpeg_options), after=lambda e: self.next_song())
"""WENT AHEAD AND MOVED NEXT_SONG FUNCTION ABOVE AS I REALIZED IT WOULD NOT WORK IF IT WAS BELOW"""
"""ALL THE FUNCTIONS WE NEEDED FOR OUR COMMANDS TO FUNCTION HAVE BEEN DEFINED NOW ONTO THE COMMAND"""
#commands.command()
async def play(self, ctx, *, args):
# This is the song that the user will search and we will look up
using the yt-search function that we made earlier
query = " ".join(args)
# If user is not in the voice channel
voice_channel = ctx.author.voice_channel
if voice_channel is None:
await ctx.send("You're not in a voice channel you dummy")
# If any song in the que is currently paused resume it
elif self.ispaused == True:
self.vc.resume()
else:
# assign song to the search result of the youtube song
song = self.search_yt(query)
if type(song) == type(True):
await ctx.send("Incorrect format of song could not play")
else:
await ctx.send("Song added")
self.musicque.append([song, voice_channel])
if self.isplaying == False:
await self.play_song(ctx)
I was expecting the program to play a song or atleast join thet voice channel but apparently it says the command is not found I've tried changing stuff with the cog but it didn't help so I'm fully lost at what I'm doing wrong.
The add_cog method doesn't work that way; it takes a cog class as an argument, not the path to the cog file. That's the load_extension's job. The load_extension will go to the given path and call the setup function inside the file, and you have to add the cog inside that setup function. For example:
 
cogs/cog_file.py
class ACogClass(discord.ext.commands.Cog):
    ...
 
async def setup(bot: discord.ext.commands.Bot): # as of discord.py 2, the "setup" function needs to be an async function
    bot.add_cog(ACogClass(bot))
 
main.py
bot = discord.ext.commands.Bot(...)
 
async def setup_hook():
    await bot.load_extension("cogs.cog_file") # as of discord.py 2, the "load_extension" method is now an async function
 
bot.setup_hook = setup_hook # set the bot's default "setup_hook" to our custom "setup_hook"

Discord.py ffmpeg I have everything setup correctly it is download and playing files, I need help changing directory of installed files, code below:

I have it setup correctly It does Everything I need play,pause,resume, etc.. All I can't find even on google is how to change the directory of the downloaded files.
I just want to make it so That it doesn't download the files in the main directory of the .py file insead it download them into a seperate folder so it can be more organised.
Thanks for your help.
import youtube_dl
youtube_dl.utils.bug_reports_message = lambda: ''
ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}
ffmpeg_options = {
'options': '-vn'
}
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
self.title = data.get('title')
self.url = data.get('url')
#classmethod
async def from_url(cls, url, *, loop=None, stream=False):
loop = loop or asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))
if 'entries' in data:
# take first item from a playlist
data = data['entries'][0]
filename = data['url'] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
#client.command(aliases=['p'])
#commands.has_role('DJ')
async def play(ctx, url):
channel = ctx.message.author.voice.channel
server = ctx.message.guild
author=ctx.message.author
guild=ctx.message.guild
voice=discord.utils.get(client.voice_clients,guild=ctx.guild)
if voice==None:
await channel.connect()
embed=discord.Embed(title='Connected',description=f'{author.mention} I have Joined Channel {channel.mention}',colour=discord.Colour.green())
await ctx.send(embed=embed)
channel_2=893855384517873725
audit_channel=client.get_channel(channel_2)
embed=discord.Embed(title='zenabz Bot Log',description=f'{author.mention} Has Requested Bot to Join Channel {channel.mention}',colour=discord.Colour.random())
await audit_channel.send(embed=embed)
print(f'{author} Has Requested Bot to Join Channel {channel}')
async with ctx.typing():
voice_channel = server.voice_client
player = await YTDLSource.from_url(url, loop=client.loop)
voice_channel.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
await ctx.send(f'{author.mention} **Now playing:** {format(player.title)}')
embed=discord.Embed(title='zenabz Bot Log',description=f'{author.mention} Has Requested Bot to play: {format(player.title)}',colour=discord.Colour.random())
await audit_channel.send(embed=embed)
print(f'{author} Has Requested Bot to to play: {format(player.title)}')
async with ctx.typing():
voice_channel = server.voice_client
player = await YTDLSource.from_url(url, loop=client.loop)
voice.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
await ctx.send(f'{author.mention} **Now playing:** {format(player.title)}')
channel_2=893855384517873725
audit_channel=client.get_channel(channel_2)
embed=discord.Embed(title='zenabz Bot Log',description=f'{author.mention} Has Requested Bot to play: {format(player.title)}',colour=discord.Colour.random())
await audit_channel.send(embed=embed)
print(f'{author} Has Requested Bot to to play: {format(player.title)}')
#play.error
async def play_error(ctx,error):
print(error)
if isinstance(error, commands.MissingRole):
author=ctx.message.author
embed=discord.Embed(title="Missing 'DJ' Role",description=f"{author.mention} you don't have the required roles to use this command", colour=discord.Colour.red())
ctx.send(embed=embed)
Sorry I don't know how to change download directory but,
ytdl_format_options = {
'format': 'bestaudio/best',
'extractaudio': True,
'audioformat': 'mp3',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}
This config will not download and save videos to your directory, instead extracts audio and plays it.

Discord Music bot VoiceClient' object has no attribute 'create_ytdl_player'

I wanted to programm my own discord bot, which plays some songs from youtube but it wont create the ydl player this is the error Command raised an exception: AttributeError: 'VoiceClient' object has no attribute 'create_ytdl_player' and this is my code. Thanks in advance.
#client.command(pass_context=True)
async def s(ctx):
user=ctx.message.author
voicech = ctx.author.voice.channel
voice = await voicech.connect()
player = await voice.create_ytdl_player("some url")
player = await vc.create_ytdl_player()
player.start()
create_ytdl_player was the old way of creating a player. With discord.py#rewrite (> v.1.0), playing music is a bit more complicated. There are two ways to play music. For both ways, using FFmpeg will be necessary, so you'll have to install it.
Here are two of ways to play videos (with youtube-dl and ffmpeg):
From file (you'll have to download files):
from discord.ext import commands
from discord.utils import get
from discord import FFmpegPCMAudio
from youtube_dl import YoutubeDL
#bot.command(brief="Plays a single video, from a youtube URL") #or bot.command()
async def play(ctx, url):
voice = get(client.voice_clients, guild=ctx.guild)
YDL_OPTIONS = {
'format': 'bestaudio',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
'outtmpl': 'song.%(ext)s',
}
with YoutubeDL(Music.YDL_OPTIONS) as ydl:
ydl.download("URL", download=True)
if not voice.is_playing():
voice.play(FFmpegPCMAudio("song.mp3"))
voice.is_playing()
await ctx.send(f"Now playing {url}")
else:
await ctx.send("Already playing song")
return
Without downloading music. This is simpler to play music this way, however, this causes a know issue, well explained here so you'll have to add a FFMPEG_OPTIONS variable:
from discord.ext import commands
from discord.utils import get
from discord import FFmpegPCMAudio
from youtube_dl import YoutubeDL
#bot.command(brief="Plays a single video, from a youtube URL")
async def play(ctx, url):
YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist':'True'}
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
voice = get(client.voice_clients, guild=ctx.guild)
if not voice.is_playing():
with YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(video_link, download=False)
URL = info['formats'][0]['url']
voice.play(FFmpegPCMAudio(URL, **FFMPEG_OPTIONS))
voice.is_playing()
else:
await ctx.send("Already playing song")
return
These commands will only play songs so you'll have to program every other commands (join, leave, ...).
There are a lot of example on internet, you should look at them once you're used to creating music bots.
Reference: VoiceClient documentation.

potato quality audio coming from bot

When I play audio through my bot it sounds really bad, I have a fast internet connection, so what could be causing this? Im running my bot on a Raspberry Pi 3. Im using FFMpeg. Could the RPI be bottlenecking it somehow. Is it my code?
simplified version of my code:
#client.command()
async def play(ctx):
channel = client.get_channel(ctx.message.author.voice.channel.id)
voice = await channel.connect()
if not voice.is_playing():
voice.play(await discord.FFMpegOpusAudio(source='/path/to/file'))
while voice.is_playing():
await asyncio.sleep(1)
discord.AudioSource.cleanup(str(ctx.message.author.voice.channel.id))
Looking at pafy documentation, you'd have to do this:
def download_song(url)
video = pafy.new(url)
best = video.getbest()
best.download(quiet=False)
However, I recommend using:
youtube-dl:
pip install youtube-dl
from youtube_dl import YoutubeDL
ydl_opts = {
'format': 'bestaudio/best',
'noplaylist':'True',
'outtmpl': 'song.%(ext)s'
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
def download_song(arg, url=True):
with YoutubeDL(ydl_opts) as ydl:
query = f"ytsearch:{arg}" if url else arg
data = ydl.extract_info(query, download=True)
return data if url else data['entries'][0]
def display_info(data):
video_info = {
'title': data['title']
'duration': data['duration']
'uploader': data['uploader']
'thumbnail': data['thumbnail']
'url': data['webpage_url']
'channel': data['channel_url']
}
for key, val in video_info.items():
print(f"{key}: {val}")
This function will allow you to download songs from urls and queries (eg. "30 sec video"). youtube_dl offers a lot of options.
Wavelink (lavalink wrapper for discord.py → better audio and audio control):
pip install lavalink
#Wavelink github example
import discord
import wavelink
from discord.ext import commands
class Bot(commands.Bot):
def __init__(self):
super(Bot, self).__init__(command_prefix=['audio ', 'wave ','aw '])
self.add_cog(Music(self))
async def on_ready(self):
print(f'Logged in as {self.user.name} | {self.user.id}')
class Music(commands.Cog):
def __init__(self, bot):
self.bot = bot
if not hasattr(bot, 'wavelink'):
self.bot.wavelink = wavelink.Client(bot=self.bot)
self.bot.loop.create_task(self.start_nodes())
async def start_nodes(self):
await self.bot.wait_until_ready()
# Initiate our nodes. For this example we will use one server.
# Region should be a discord.py guild.region e.g sydney or us_central (Though this is not technically required)
await self.bot.wavelink.initiate_node(host='127.0.0.1',
port=2333,
rest_uri='http://127.0.0.1:2333',
password='youshallnotpass',
identifier='TEST',
region='us_central')
#commands.command(name='connect')
async def connect_(self, ctx, *, channel: discord.VoiceChannel=None):
if not channel:
try:
channel = ctx.author.voice.channel
except AttributeError:
raise discord.DiscordException('No channel to join. Please either specify a valid channel or join one.')
player = self.bot.wavelink.get_player(ctx.guild.id)
await ctx.send(f'Connecting to **`{channel.name}`**')
await player.connect(channel.id)
#commands.command()
async def play(self, ctx, *, query: str):
tracks = await self.bot.wavelink.get_tracks(f'ytsearch:{query}')
if not tracks:
return await ctx.send('Could not find any songs with that query.')
player = self.bot.wavelink.get_player(ctx.guild.id)
if not player.is_connected:
await ctx.invoke(self.connect_)
await ctx.send(f'Added {str(tracks[0])} to the queue.')
await player.play(tracks[0])
bot = Bot()
bot.run('TOKEN')
This one is more complex but will let you have more controll over your music player. Personally, I think that youtube-dl is sufficient for playing audio in discord but it's up to you.

Discord.py rewrite - what is the source for YoutubeDL to play music?

As mentioned in the docs here, I need to use a source to play music using the play() command, I am trying to use YoutubeDL but I can't figure it out.
I have checked the rapptz discord.py basic voice example, but since I'm not using object-oriented programming its confusing me quite alot. Everywhere I have looked, their example is using the v0.16 discord.py, and I can't work out how to convert this player = await voice_client.create_ytdl_player(url) into the rewrite.
My play function at the moment looks like this:
async def play(ctx, url = None):
...
player = await YTDLSource(url)
await ctx.voice_client.play(player)
await ctx.send("Now playing: " + player.title())
"YTDLSource" being a placeholder for the source.
Any help greatly appreciated, thanks.
I am sure there are better ways of doing this with the rewrite, but I am in the same boat as you. I could not figure it out for the longest time.
After looking through youtube-dl documents and the rewrite documents this is the best I could come up with. Keep in mind I do not know if this will work with a queue system (probably not). Also I don't know if it's a bug or something I'm doing wrong when the bot joins and then you use the play command it does not output the music, but if the bot leaves then joins again the music will play. To fix I made my join command join, leave, and join.
Join command:
#bot.command(pass_context=True, brief="Makes the bot join your channel", aliases=['j', 'jo'])
async def join(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()
await voice.disconnect()
if voice and voice.is_connected():
await voice.move_to(channel)
else:
voice = await channel.connect()
await ctx.send(f"Joined {channel}")
play command:
#bot.command(pass_context=True, brief="This will play a song 'play [url]'", aliases=['pl'])
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 end or use the 'stop' command")
return
await ctx.send("Getting everything ready, playing audio soon")
print("Someone wants to play music let me get that ready for them...")
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:
ydl.download([url])
for file in os.listdir("./"):
if file.endswith(".mp3"):
os.rename(file, 'song.mp3')
voice.play(discord.FFmpegPCMAudio("song.mp3"))
voice.volume = 100
voice.is_playing()
Leave command:
#bot.command(pass_context=True, brief="Makes the bot leave your channel", aliases=['l', 'le', '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()
await ctx.send(f"Left {channel}")
else:
await ctx.send("Don't think I am in a voice channel")
All that needs to be imported (I think):
import discord
import youtube_dl
import os
from discord.ext import commands
from discord.utils import get
from discord import FFmpegPCMAudio
from os import system
you also might need to download ffmpeg off their website (there are youtube tutorials on how to do so and install it)
With the Play command post with a youtube url ('/play www.youtube.com') it will first look for a 'song.mp3' and delete it if there is one, download the new song rename it to 'song.mp3' then plays the mp3 file. The mp3 file will be put in them same directory as your bot.py
Like I said before there is probably a batter way to do this allowing a queue command, but I don't know that way as of now.
hope this helps!
The discord docs now have a full example on how to make a voice bot that implements ytdl!
Check out the yt method in https://github.com/Rapptz/discord.py/blob/master/examples/basic_voice.py :
#commands.command()
async def yt(self, ctx, *, url):
"""Plays from a url (almost anything youtube_dl supports)"""
async with ctx.typing():
player = await YTDLSource.from_url(url, loop=self.bot.loop)
ctx.voice_client.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
await ctx.send('Now playing: {}'.format(player.title))
And the YTDLSource class it depends on:
ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'restrictfilenames': True,
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0' # bind to ipv4 since ipv6 addresses cause issues sometimes
}
ffmpeg_options = {
'options': '-vn'
}
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
self.title = data.get('title')
self.url = data.get('url')
#classmethod
async def from_url(cls, url, *, loop=None, stream=False):
loop = loop or asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))
if 'entries' in data:
# take first item from a playlist
data = data['entries'][0]
filename = data['url'] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
Change player = await YTDLSource.from_url(url, loop=self.bot.loop) to player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True) if you'd rather stream audio from youtube instead of predownloading it
pastebin archive: https://pastebin.com/nEiJ5YrD

Resources