from urllib.request import urlretrieve
from urllib.error import HTTPError
from threading import Thread
+from queue import Queue
# non-included libs
from jinja2 import ( # type: ignore
Environment as JinjaEnv, FileSystemLoader as JinjaFSLoader)
self.last_update = PlayerUpdateId('')
self._load_filenames()
self._mpv: Optional[MPV] = None
+ self._kill_queue: Queue = Queue()
+ self._monitoring_kill = False
+
+ def _monitor_kill(self) -> None:
+ """Properly enforce mpv shutdown from direct interaction with mpv
+ client, as may happen with the "q" keystroke. If not for the handling
+ below, this may keep the 'shutdown' window open/undead, as proper
+ destruction only seems ensured when commanded from within the main
+ Python thread …?
+ """
+ if self._monitoring_kill:
+ return
+ self._monitoring_kill = True
+
+ def kill_on_queue_get() -> None:
+ self._kill_queue.get()
+ if self._mpv:
+ self._mpv.wait_for_shutdown()
+ self._kill_mpv()
+ self._monitoring_kill = False
+
+ Thread(target=kill_on_queue_get, daemon=True).start()
def _load_filenames(self) -> None:
conn = DbConnection()
self._mpv = MPV(input_default_bindings=True,
input_vo_keyboard=True,
config=True)
+ self._monitor_kill()
self._mpv.observe_property('pause', lambda a, b: self._signal_update())
for path in [f.full_path for f in self._files]:
self._mpv.command('loadfile', path, 'append')
@self._mpv.event_callback('shutdown')
def on_shutdown(_) -> None:
- self._mpv = None
- self._signal_update()
+ """To properly enforce shutdown even on direct client interaction,
+ see self._monitor_kill for more thorough explanation.
+ """
+ self._kill_queue.put(True)
self._mpv.command('playlist-play-index', self._idx)
if self._mpv:
self._mpv.terminate()
self._mpv = None
+ self._signal_update()
@property
def current_file(self) -> Optional[VideoFile]: