Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 71 lines 2.3 kB view raw
1"""06 — Plugin: sleep timer. 2 3Stops playback after N minutes. If the user stops playback manually before the 4timer fires, the plugin cancels itself. 5 6 uv run python examples/06_plugin_sleep_timer.py # default 30 min 7 uv run python examples/06_plugin_sleep_timer.py 5 # 5 minutes 8""" 9 10from __future__ import annotations 11 12import asyncio 13import contextlib 14import sys 15from datetime import datetime, timedelta 16 17from _client import create_client # type: ignore[import-not-found] 18 19from rockbox_sdk import PlaybackStatus, PluginContext 20 21 22class SleepTimer: 23 name = "sleep-timer" 24 version = "1.0.0" 25 26 def __init__(self, minutes: int) -> None: 27 self.minutes = minutes 28 self.description = f"Stop playback after {minutes} minute(s)" 29 self._task: asyncio.Task[None] | None = None 30 31 def install(self, ctx: PluginContext) -> None: 32 fire_at = datetime.now() + timedelta(minutes=self.minutes) 33 print(f"💤 Sleep timer armed — will stop playback at {fire_at:%H:%M:%S}") 34 35 async def fire() -> None: 36 try: 37 await asyncio.sleep(self.minutes * 60) 38 except asyncio.CancelledError: 39 return 40 print("💤 Time's up — stopping playback.") 41 await ctx.query("mutation { hardStop }") 42 43 self._task = asyncio.create_task(fire()) 44 45 @ctx.events.on("status:changed") 46 def cancel_on_stop(status: int) -> None: 47 if status == PlaybackStatus.STOPPED and self._task and not self._task.done(): 48 self._task.cancel() 49 print("💤 Playback stopped manually — sleep timer cancelled.") 50 51 def uninstall(self) -> None: 52 if self._task and not self._task.done(): 53 self._task.cancel() 54 55 56async def main(minutes: int) -> None: 57 async with create_client() as client: 58 await client.connect() 59 await client.use(SleepTimer(minutes)) 60 61 print("Plugin installed. Press Ctrl+C to cancel and exit.") 62 with contextlib.suppress(asyncio.CancelledError): 63 await asyncio.Event().wait() 64 65 66if __name__ == "__main__": 67 minutes = int(sys.argv[1]) if len(sys.argv) > 1 else 30 68 try: 69 asyncio.run(main(minutes)) 70 except KeyboardInterrupt: 71 print("\nbye")