diff --git a/src/bot.py b/src/bot.py index ac85f26..c6a5771 100644 --- a/src/bot.py +++ b/src/bot.py @@ -9,7 +9,7 @@ from dotenv import load_dotenv import youtube_dl from error import ErrorHandler -from message import NowPlayingMessage, QueuedMessage +from message import NowPlayingMessage, QueuedMessage, ErrorMessage load_dotenv() @@ -54,22 +54,40 @@ class Music(commands.Cog): # pylint: disable=no-member self._handle_playback.cancel() + def _next(self): + """Trigger playback of next song.""" + self._queue.task_done() + if self._queue_lock.locked(): + self._queue_lock.release() + @tasks.loop() async def _handle_playback(self): while True: - await self._queue_lock.acquire() - ctx, song = await self._queue.get() - audio = discord.FFmpegPCMAudio(song.audio_url, **self._ffmpeg_options) + try: + await self._queue_lock.acquire() + ctx, song = await self._queue.get() + if ctx.voice_client is None: + # Bot is no longer in a voice channel. + # This could be the case because a stop command was issued. + # We will skip this (and possibly all remaining songs) in the queue + self._next() + continue + audio = discord.FFmpegPCMAudio(song.audio_url, **self._ffmpeg_options) - def after(err): - if err: - print(f"Player error: {err}") - self._queue.task_done() - self._queue_lock.release() - ctx.voice_client.play(audio, after=after) - - embed = NowPlayingMessage(title=song.title, url=song.webpage_url) - await ctx.send(embed=embed) + def after(err): + if err: + print(f"Player error: {err}") + self._next() + ctx.voice_client.play(audio, after=after) + embed = NowPlayingMessage(title=song.title, url=song.webpage_url) + await ctx.send(embed=embed) + # pylint: disable=broad-except + except Exception as err: + print(f"Error during playback: {err}") + if ctx: + embed = ErrorMessage(str(err)) + await ctx.send(embed=embed) + self._next() @_handle_playback.before_loop async def before_handle_playback(self):