Skip to content

Commit

Permalink
Fixed docstrings, removed unnecessary async definitions for methods t…
Browse files Browse the repository at this point in the history
…hat didn't need to be coroutines, updated example
  • Loading branch information
sockheadrps committed Jul 10, 2024
1 parent a935e80 commit 2a739ed
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 48 deletions.
23 changes: 9 additions & 14 deletions examples/music_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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()
Expand Down
82 changes: 48 additions & 34 deletions twitchio/ext/sounds/queuemanager.py
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -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:
Expand Down

0 comments on commit 2a739ed

Please sign in to comment.