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()





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



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.

Popular posts from this blog

Render GeoTiff to on browser with leaflet

How to get chrome logged in user's email id through website

using states in a react-navigation without redux