diff --git a/examples/music_queue.py b/examples/music_queue.py index 9a332ade..5bc5b432 100644 --- a/examples/music_queue.py +++ b/examples/music_queue.py @@ -6,20 +6,16 @@ class Bot(commands.Bot): def __init__(self): - super().__init__(token="TOKEN", prefix="!", initial_channels=["CHANNEL"]) + super().__init__(token="TOKEN", prefix="!", initial_channels=["sockheadrps"]) self.audio_manager = queuemanager.AudioQueueManager() - - # Adding sound files paths to the queue for uses to choose from - song_dict = { - "song_one": "\\PATH\\TO\\FILE.mp3", - "song_two": "\\PATH\\TO\\FILE.mp3", - "song_three": "\\PATH\\TO\\FILE.mp3", + self.song_dict = { + "song_one": "C:\\PATH\\TO\\FILE.mp3", + "song_two": "C:\\PATH\\TO\\FILE.mp3", + "song_three": "C:\\PATH\\TO\\FILE.mp3", } async def event_ready(self): loop = asyncio.get_event_loop() - - # Start the queue loop self.task = loop.create_task(self.audio_manager.queue_loop()) @commands.command(name="sr") @@ -31,22 +27,21 @@ async def addsound(self, ctx: commands.Context, sound: str): @commands.command(name="skip") async def skip(self, ctx: commands.Context): await ctx.send(f"Skipped the current sound. {self.audio_manager.current_sound}") - await self.audio_manager.skip_audio() + self.audio_manager.skip_audio() @commands.command(name="pause") async def pause(self, ctx: commands.Context): - await self.audio_manager.pause_audio() + self.audio_manager.pause_audio() @commands.command(name="resume") async def resume(self, ctx: commands.Context): - await self.audio_manager.resume_audio() + self.audio_manager.resume_audio() @commands.command(name="queue") async def queue(self, ctx: commands.Context): - queue_contents = await self.audio_manager.get_queue_contents() + queue_contents = self.audio_manager.get_queue_contents() await ctx.send(f"Queue contents: {queue_contents}") - # Override close method to gracefully cancel the task async def close(self): self.task.cancel() await super().close() diff --git a/twitchio/ext/sounds/queuemanager.py b/twitchio/ext/sounds/queuemanager.py index c0c1cb59..267a226f 100644 --- a/twitchio/ext/sounds/queuemanager.py +++ b/twitchio/ext/sounds/queuemanager.py @@ -1,58 +1,75 @@ import asyncio from twitchio.ext import sounds +from typing import Optional class AudioQueueManager: """ Manages a queue of audio files to be played sequentially with optional repeat and pause functionalities. - Attributes: - queue (asyncio.Queue[str]): A queue to hold paths of audio files to be played. - is_playing (bool): Indicates whether an audio file is currently being played. - repeat_queue (bool): If True, adds the current playing audio file back to the queue after playing. - queue_paused (bool): If True, pauses the processing of the queue. - player (sounds.AudioPlayer): An instance of AudioPlayer to play audio files. - current_sound (str): Path of the currently playing audio file. + Attributes + ---------- + queue: asyncio.Queue[:class:`str`] + A queue to hold paths of audio files to be played. + is_playing: :class:`bool` + Indicates whether an audio file is currently being played. + repeat_queue: :class:`bool` + If True, adds the current playing audio file back to the queue after playing. + queue_paused: :class:`bool` + If True, pauses the processing of the queue. + player: :class:`sounds.AudioPlayer` + An instance of AudioPlayer to play audio files. + current_sound: :class:`str` + Path of the currently playing audio file. """ - def __init__(self): + def __init__(self, repeat_queue: Optional[bool] = True) -> None: """ Initializes an instance of AudioQueueManager with an empty queue and default settings. + + Parameters + ---------- + repeat_queue: Optional[:class:`bool`] + If True, adds the current playing audio file back to the queue after playing, by default True """ self.queue: asyncio.Queue[str] = asyncio.Queue() self.is_playing: bool = False - self.repeat_queue: bool = True + self.repeat_queue: bool = repeat_queue if repeat_queue is not None else True self.queue_paused: bool = False - self.player: sounds.AudioPlayer = sounds.AudioPlayer( - callback=self.player_done) + self.player: sounds.AudioPlayer = sounds.AudioPlayer(callback=self.player_done) self.current_sound: str = "" async def player_done(self) -> None: """ + |coro| + Callback method called when the player finishes playing an audio file. Resets the is_playing flag and marks the current task as done in the queue. """ - await asyncio.sleep(0.1) self.is_playing = False self.queue.task_done() async def add_audio(self, sound_path: str) -> None: """ + |coro| + Adds a new audio file to the queue. - Args: - sound_path (str): Path of the audio file to add to the queue. + Parameters + ---------- + sound_path: :class:`str` + Path of the audio file to add to the queue. """ - await asyncio.sleep(0.1) await self.queue.put(sound_path) async def play_next(self) -> None: """ + |coro| + Plays the next audio file in the queue if the queue is not empty and not paused. Sets the is_playing flag, retrieves the next audio file from the queue, and plays it. If repeat_queue is True, adds the current audio file back to the queue after playing. """ - await asyncio.sleep(0.1) if not self.queue.empty() and not self.queue_paused: self.is_playing = True sound_path = await self.queue.get() @@ -62,74 +79,71 @@ async def play_next(self) -> None: if self.repeat_queue: await self.queue.put(self.current_sound) - async def skip_audio(self) -> None: + def skip_audio(self) -> None: """ Stops the currently playing audio file if there is one. """ - await asyncio.sleep(0.1) if self.is_playing: self.player.stop() self.is_playing = False - async def stop_audio(self) -> None: + def stop_audio(self) -> None: """ Stops the currently playing audio file. Resets the playing flag but leaves the queue intact. """ - await asyncio.sleep(0.1) if self.is_playing: self.player.stop() self.is_playing = False - async def pause_audio(self) -> None: + def pause_audio(self) -> None: """ Pauses the currently playing audio file. """ - await asyncio.sleep(0.1) self.player.pause() - async def resume_audio(self) -> None: + def resume_audio(self) -> None: """ Resumes the currently paused audio file. """ - await asyncio.sleep(0.1) self.player.resume() async def clear_queue(self) -> None: """ + |coro| + Clears all audio files from the queue. """ - await asyncio.sleep(0.1) while not self.queue.empty(): await self.queue.get() self.queue.task_done() - async def pause_queue(self) -> None: + def pause_queue(self) -> None: """ Pauses the processing of the queue. """ - await asyncio.sleep(0.1) self.queue_paused = True - async def resume_queue(self) -> None: + def resume_queue(self) -> None: """ Resumes the processing of the queue. """ - await asyncio.sleep(0.1) self.queue_paused = False - async def get_queue_contents(self) -> list: + def get_queue_contents(self) -> list[str]: """ - Retrieves the current contents of the queue. + Retrieves the current contents of the queue as a list. - Returns: - list: List of paths of audio files in the queue. + Returns + ------- + List[:class:`str`] """ - await asyncio.sleep(0.1) return list(self.queue._queue) async def queue_loop(self) -> None: """ + |coro| + Continuously checks the queue and plays the next audio file if not currently playing and not paused. """ try: