I run an unofficial server for discord.py (although some developers).
Questions are also accepted here. You can also create a personal channel and get support there for ** people who want long-term support **.
If you would like to receive personal support, please enter from the invitation url below and DM to @ Sumidora # 8931
.
https://discord.gg/KPp2Wsu ** Please also ask questions about this article here **
This article is a step-by-step study of discord.py. First you will learn the basic writing method, and then you will learn the advanced content. 【series】
Introduction to discord.py (1) Introduction to discord.py (2) Introduction to discord.py (3)
** This article is for people who can do even a little Python. ** ** However, you can use it just by copying it, but you will not be able to write it after that, so if you want to create more individual functions, It is recommended to study using books, paiza learning, dot installation, Progate, Kyoto University textbook. I will. The book I recommend is Shingo Tsuji's [Python Startbook](https://www.amazon.co.jp/Python Startbook-Augmented Revised Edition-Tsuji-Shingo / dp / 4774196436 /).
Python 3.8.3 Mac OS Catalina 10.15.5 discord.py-1.4.1
In this article, it will be an article that will follow the usage in order, not the system like each introduction so far.
Until now, you installed pip install discord.py
, but this doesn't install the library for audio. Therefore, you need to install the library for audio as well.
pip install discord.py[voice]
Finally, write [voice]
to install the voice library as well.
If you have already installed it, uninstall it first with pip uninstall discord.py
.
First, let's write the code that connects to the voice.
This time, we will create a function to connect by hitting ! Join
and disconnect by hitting! Leave
.
If the sender of the message is not connected to a voice channel, you will not know which voice channel to connect to.
So, first we need to determine if the sender of the message is connected to the voice channel.
Here we use the discord.Member.voice
variable. This variable returns a discord.VoiceState
instance if it was connected to a voice channel, and None
if it wasn't.
# in on_message
if message.content == "!join":
if message.author.voice is None:
await message.channel.send("You are not connected to a voice channel.")
return
...
After judging in the above section, the next step is to connect to the voice channel. You can connect with the discord.VoiceChannel.connect
coroutine function, but first you need to get an instance of discord.VoiceChannel
.
You can also get this with the discord.Client.get_channel
function, but you can use the discord.VoiceState.channel
variable as it is also a VoiceChannel
instance.
# in on_message
if message.content == "!join":
if message.author.voice is None:
await message.channel.send("You are not connected to a voice channel.")
return
#Connect to voice channel
await message.author.voice.channel.connect()
await message.channel.send("Connected.")
Now you can connect to your voice channel!
Next, disconnect from the voice channel. This requires a slightly special method.
First, in order to disconnect from the voice channel, you need to execute the discord.VoiceClient.disconnect
coroutine function, but you need to get this discord.VoiceClient
instance from discord.Guild
.
voice_client = message.guild.voice_client
This value will be discord.VoiceClient
if connected, None
if not connected.
With this,
import discord
client = discord.Client()
@client.event
async def on_message(message: discord.Message):
#Ignore if the sender of the message is a bot
if message.author.bot:
return
if message.content == "!join":
if message.author.voice is None:
await message.channel.send("You are not connected to a voice channel.")
return
#Connect to voice channel
await message.author.voice.channel.connect()
await message.channel.send("Connected.")
elif message.content == "!leave":
if message.guild.voice_client is None:
await message.channel.send("Not connected.")
return
#Disconnect
await message.guild.voice_client.disconnect()
await message.channel.send("I disconnected.")
You can write like this.
Use the discord.VoiceClient.move_to
coroutine function. Pass an instance of a new audio channel to move_to.
#Go to the voice channel where the user who sent the message is
message.guild.voice_client.move_to(message.author.voice.channel)
After connecting to the voice channel, let's play the voice. Here we assume that you have a file called ʻexample.mp3`.
You will also need something called ffmpeg, so please include it (search for it and you will find many ways to enter it).
Try to play it by typing ! play
.
if message.content == "!play":
if message.guild.voice_client is None:
await message.channel.send("Not connected.")
return
message.guild.voice_client.play(discord.FFmpegPCMAudio("example.mp3"))
You can play with just this! Surprisingly, the play function is not a coroutine function.
You can pause with the discord.VoiceClient.pause
function.
You can also stop (cannot resume) with the discord.VoiceClient.stop
function.
You can resume playback with the discord.VoiceClient.resume
function.
You can change it by using discord.PCMVolumeTransformer
.
source = discord.PCMVolumeTransformer(discord.FFmpegPCMAudio("example.mp3"), volume=0.5)
message.guild.voice_client.play(source)
You can specify the volume for volume. The original volume is 1 and the lowest is 0. (Half at 0.5)
** The content from here onwards may conflict with Youtube's TOS, so please do so at your own risk. Only an example is shown here. ** **
You can refer to here, but this content is advanced (difficult to write by yourself), so it's easy. I will introduce what I did.
First, run pip install youtube_dl
in the shell to install the youtube_dl
library.
Then write this at the beginning of the file:
import asyncio
import discord
import youtube_dl
# Suppress noise about console usage from errors
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)
This is located at https://github.com/Rapptz/discord.py/blob/master/examples/basic_voice.py.
Then use it to make youtube music playable.
import asyncio
import discord
import youtube_dl
# Suppress noise about console usage from errors
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 = discord.Client()
@client.event
async def on_message(message: discord.Message):
#Ignore if the sender of the message is a bot
if message.author.bot:
return
if message.content == "!join":
if message.author.voice is None:
await message.channel.send("You are not connected to a voice channel.")
return
#Connect to voice channel
await message.author.voice.channel.connect()
await message.channel.send("Connected.")
elif message.content == "!leave":
if message.guild.voice_client is None:
await message.channel.send("Not connected.")
return
#Disconnect
await message.guild.voice_client.disconnect()
await message.channel.send("I disconnected.")
elif message.content.startswith("!play "):
if message.guild.voice_client is None:
await message.channel.send("Not connected.")
return
#Do not play if playing
if message.guild.voice_client.is_playing():
await message.channel.send("Playing.")
return
url = message.content[6:]
#Download music from youtube
player = await YTDLSource.from_url(url, loop=client.loop)
#Reproduce
await message.guild.voice_client.play(player)
await message.channel.send('{}To play.'.format(player.title))
elif message.content == "!stop":
if message.guild.voice_client is None:
await message.channel.send("Not connected.")
return
#Do not run if not playing
if not message.guild.voice_client.is_playing():
await message.channel.send("Not playing.")
return
message.guild.voice_client.stop()
await message.channel.send("It has stopped.")
How was that. I explained how to use voice. If you have any other points you would like us to explain, please leave them in the comments or on the server.
In the next article, I hope I can explain the commands framework.
Well then.
Recommended Posts