我正在尝试使用Python进行盲人测试的机器人游戏,实际上效果还不错。通过该play_next()
函数,我设法在队列中获得了一个完整的Spotify播放列表。
def play_next(ctx):
if len(song_queue) >= 1:
del song_queue[0]
source = song_queue[0]
vc.play(FFmpegPCMAudio(source=source.preview_url),
after=lambda e: play_next(ctx))
track_played = source
@client.command()
async def start(ctx):
...
...
for song in tracks:
if not song.track.preview_url:
continue
source = song.track
song_queue.append(source)
if not vc.is_playing():
vc.play(FFmpegPCMAudio(source=source.preview_url),
after=lambda e: play_next(ctx))
track_played = source
同样,先前的代码运行良好,但是一旦我将play_next()
功能转到async
以输出有关正在播放的曲目的详细信息,问题就会开始。
async def play_next(ctx):
await ctx.send("The answer was: {} from {}".format(track_played.name,
' and'.join(track_played.artists)))
if len(song_queue) >= 1:
del song_queue[0]
source = song_queue[0]
await ctx.send('Next song is about to start')
vc.play(FFmpegPCMAudio(source=source.preview_url),
after=lambda e: play_next(ctx))
track_played = source
运行前面的代码会引发以下错误:play_next() was never awaited
。
现在我知道很多人都经历过这种类型的问题,但是我似乎似乎无法理解最近几个小时所读的内容,而我尝试过的任何方法都无法解决此问题……如果有人可以启发我,那太好了!
编辑
我终于遇到了一个解决方案,老实说,我不知道这是安全的还是好的做法。
我必须使该play_next()
函数保持同步,并在另一个ctx.send()
函数中获得对async
的调用,如下所示:
async def sendMsg(message, ctx):
await ctx.send(message)
并使用asyncio在主循环线程中调用协程。参见:
def play_next(ctx):
...
send_fut = asyncio.run_coroutine_threadsafe(sendMsg(message, ctx), loop)
send_fut.result()
if len(song_queue) >= 1:
source = song_queue[0]
message = ('Next song is about to start')
send_fut = asyncio.run_coroutine_threadsafe(sendMsg(message, ctx), loop)
send_fut.result()
del song_queue[0]
track_played = source
vc.play(FFmpegPCMAudio(source=source.preview_url),
after=lambda x: play_next(ctx))
先前在loop
中用全局变量初始化了main()
。请注意,在找到正确的命令和位置之前,我尝试了很多命令和位置,这使我在这两条线上非常费劲。请注意get_event_loop()
而不是new_event_loop()
。
def main():
global loop
loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop)
def_globals()
client.run('TOKEN')
希望这可能现在对其他人有所帮助!