Enhance play method for playlist support (#172)

Refactor play method to support playlists and sequential playback.
This commit is contained in:
Omar Amin authored and GitHub committed 2026-02-24 00:24:14 +01:00
1 parent 5a732f8421
commit 9dcc4542a4
1 file changed
+39 -17
+39 -17
View File
@@ -18,6 +18,7 @@ class MpvMediaPlayer:
self._log = logging.getLogger(self.__class__.__name__)
self._player = LibMpvPlayer(device=device)
self._done_callback: Optional[Callable[[], None]] = None
self._playlist: List[str] = []
self._log.debug("MpvMediaPlayer initialized (device=%s)", device)
@@ -31,34 +32,55 @@ class MpvMediaPlayer:
Play a media URL.
Args:
url: Media URL or list of URLs (LVA currently uses a single URL).
url: Media URL or list of URLs for sequential playback.
done_callback: Optional callback invoked when playback finishes.
stop_first: Kept for API compatibility.
"""
# LVA currently only uses single URLs
if isinstance(url, list):
self._log.debug("Received URL list, using first entry")
url = url[0]
# Handle single URL vs list
if isinstance(url, str):
urls = [url]
else:
urls = list(url) # Copy the list
# Track is changing - only stop for replacement if actually playing
if not urls:
self._log.warning("play() called with empty URL list")
return
# Track is changing - stop if needed
if self._done_callback is not None:
if self._player.state() != PlayerState.IDLE:
self._log.debug(
"Stopping active playback before starting new media"
)
self._log.debug("Stopping active playback before starting new media")
self._player.stop(for_replacement=True)
self._done_callback = None
self._log.info("Playing media: %s", url)
self._log.debug(
"play(url=%s, stop_first=%s, done_callback=%s)",
url,
stop_first,
bool(done_callback),
)
self._log.info("Playing %d URL(s): %s", len(urls), urls[0])
# Store playlist and callback
self._playlist = urls
self._done_callback = done_callback
self._player.play(url, done_callback=done_callback, stop_first=stop_first)
# Start playing first URL
next_url = self._playlist.pop(0)
self._player.play(next_url, done_callback=self._on_track_finished, stop_first=stop_first)
def _on_track_finished(self) -> None:
"""Called when a track finishes - plays next or invokes done callback."""
if self._playlist:
# More tracks to play
next_url = self._playlist.pop(0)
self._log.debug("Playing next URL from playlist: %s", next_url)
self._player.play(next_url, done_callback=self._on_track_finished, stop_first=False)
else:
# Playlist finished
callback = self._done_callback
self._done_callback = None
if callback:
self._log.debug("Playlist finished, invoking done_callback")
try:
callback()
except Exception as e:
self._log.exception("Error in done_callback: %s", e)
def pause(self) -> None:
"""Pause playback."""