StreamPlayer “after” function isn't being called
StreamPlayer “after” function isn't being called
I am creating a discord bot that can play music but I'm a bit stuck because when
the bot finishes playing music is should leave the current voice channel. However this isn't happening, instead my after
function vc.disconnect
isn't being called at all though I've followed the instructions on the FAQ page.
after
vc.disconnect
vc = await bot.join_voice_channel(ctx.message.author.voice_channel)
player = await vc.create_ytdl_player(arg.split(' ')[1], after=vc.disconnect)
player.start()
after=lambda: print("exit")
What happens if you do the same thing:
after=lambda: vc.disconnect()
?– Tomalak
Jun 30 at 7:27
after=lambda: vc.disconnect()
Apparently also nothing.
– godith 320
Jun 30 at 7:29
Then that would mean it is called but does not do what you expect. Make a three-liner function that prints something, calls
vc.disconnect()
and then prints another thing and put that as after
. What happens?– Tomalak
Jun 30 at 7:32
vc.disconnect()
after
I think I found the reason. The docs say that you cannot run a coroutine in the
after
callback, because this is not thread-safe. But vc.disconnect()
is a coroutine. See the answer - I was just about to write the same thing.– Tomalak
Jun 30 at 7:43
after
vc.disconnect()
1 Answer
1
The problem is that vc.disconnect
is a coroutine. You need to handle it differently, as the after
call doesn't await the coroutine since the voice player is just a Thread
.
vc.disconnect
after
Thread
According to the docs, this is how it should be handled:
def my_after():
coro = vc.disconnect()
fut = asyncio.run_coroutine_threadsafe(coro, client.loop)
try:
fut.result()
except:
pass
player = await voice.create_ytdl_player(url, after=my_after)
player.start()
Also as noted by the docs, the following warning:
Warning
This function is only part of 3.5.1+ and 3.4.4+. If you are not using
these Python versions then use
discord.compat.
.
discord.compat.
Meaning that if you're running Python 3.4.0-3.4.3 or 3.5.0, your my_after
needs to be changed to this:
my_after
def my_after():
from discord.compat import run_coroutine_threadsafe
coro = vc.disconnect()
fut = run_coroutine_threadsafe(coro, client.loop)
try:
fut.result()
except:
pass
Ok, so this was something new. My python script contained a
#try:
which made the editor indent the code that came after it even though try:
was never ran. This lead to some kind of error that wasn't outputted some where and some how, after removing the #try:
s and re indenting every line the code ran seamlessly. The more you know.– godith 320
Jun 30 at 8:22
#try:
try:
#try:
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
If I change the function to
after=lambda: print("exit")
the output comes after the ytfl window closes.– godith 320
Jun 30 at 7:18