|
@@ -0,0 +1,108 @@
|
|
|
+#!./bin/python3
|
|
|
+
|
|
|
+import threading
|
|
|
+import time
|
|
|
+
|
|
|
+from handler import EVENT_LEFT
|
|
|
+from handler.listhandler import BaseListHandler
|
|
|
+from handler.lib.pymplb import MPlayer
|
|
|
+
|
|
|
+class FileListHandler(BaseListHandler):
|
|
|
+
|
|
|
+ def __init__(self, config, display):
|
|
|
+ super().__init__(config, display)
|
|
|
+ self._mplayer = None
|
|
|
+ self._mplayer_watcher = None
|
|
|
+ self.is_playing = False
|
|
|
+ self._last_event = time.time()
|
|
|
+
|
|
|
+
|
|
|
+ def setPlaylistItem(self, item):
|
|
|
+ '''
|
|
|
+ Called with the selected item.
|
|
|
+ '''
|
|
|
+ super().setPlaylistItem(item)
|
|
|
+
|
|
|
+ if self._mplayer is None:
|
|
|
+ self._mplayer = MPlayer()
|
|
|
+ self.setItems(self.getPlaylistItems(item))
|
|
|
+ self._mplayer_watcher = threading.Thread(target=self._watch_mplayer, daemon=True)
|
|
|
+ self._mplayer_watcher.start()
|
|
|
+
|
|
|
+ self.is_playing = False
|
|
|
+
|
|
|
+
|
|
|
+ def getPlaylistItems(self, item):
|
|
|
+ raise NotImplementedError()
|
|
|
+
|
|
|
+
|
|
|
+ def update(self, text=None, highlight=-1, title=None, img=None):
|
|
|
+ '''
|
|
|
+ Called when the handler should update the display.
|
|
|
+ '''
|
|
|
+ super().update(title=[
|
|
|
+ "",
|
|
|
+ "Playlist:",
|
|
|
+ self.item["name"],
|
|
|
+ "[play]" if self.is_playing else "[stop]"
|
|
|
+ ], img=self.item.get("img"))
|
|
|
+
|
|
|
+
|
|
|
+ def itemSelected(self, item):
|
|
|
+ self._mplayer.loadfile(item["path"])
|
|
|
+ self.is_playing = True
|
|
|
+
|
|
|
+
|
|
|
+ def stop(self):
|
|
|
+ '''
|
|
|
+ Called when the handler should stop.
|
|
|
+ '''
|
|
|
+ if self._mplayer is not None:
|
|
|
+ self._mplayer.quit()
|
|
|
+ self._mplayer = None
|
|
|
+ self._mplayer_watcher = None
|
|
|
+
|
|
|
+
|
|
|
+ def emitEvent(self, event):
|
|
|
+ '''
|
|
|
+ Called when an event has happened.
|
|
|
+ '''
|
|
|
+
|
|
|
+ # Clock the time so the thread can hold off if there
|
|
|
+ # was a recent user event
|
|
|
+
|
|
|
+ self._last_event = time.time()
|
|
|
+
|
|
|
+ if event == EVENT_LEFT and self.is_playing:
|
|
|
+ self._mplayer.stop()
|
|
|
+ self.is_playing = False
|
|
|
+ return
|
|
|
+
|
|
|
+ super().emitEvent(event)
|
|
|
+
|
|
|
+
|
|
|
+ def _watch_mplayer(self):
|
|
|
+ '''
|
|
|
+ Thread to watch mplayer and advance the playlist.
|
|
|
+ '''
|
|
|
+
|
|
|
+ while self._mplayer_watcher is not None:
|
|
|
+
|
|
|
+ try:
|
|
|
+ time.sleep(0.5)
|
|
|
+
|
|
|
+ if self._mplayer:
|
|
|
+ playing_path = self._mplayer.p_path
|
|
|
+
|
|
|
+ # Only do something in the thread if the last user
|
|
|
+ # input is at least 3 seconds ago
|
|
|
+
|
|
|
+ if time.time() - self._last_event > 3:
|
|
|
+
|
|
|
+ # Advance to the next item if we are playing music
|
|
|
+
|
|
|
+ if self.is_playing and playing_path == "(null)":
|
|
|
+ self.nextItem()
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ print("Error watching player:", e)
|