From 88103d29cf0e0f5eb9e085c7f7032ea935c6661c Mon Sep 17 00:00:00 2001 From: kelciour Date: Fri, 26 Jun 2020 20:36:58 +0300 Subject: [PATCH 1/4] Replace default mpv quit keybindings if mpv version is >= 0.30 https://github.com/mpv-player/mpv/commit/4614d432a8d21ab135af25a183f57efd5059bb62 --- qt/aqt/mpv.py | 4 ++++ qt/aqt/sound.py | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/qt/aqt/mpv.py b/qt/aqt/mpv.py index eab2e4514..c5b8a1e29 100644 --- a/qt/aqt/mpv.py +++ b/qt/aqt/mpv.py @@ -448,6 +448,10 @@ class MPV(MPVBase): if not inspect.ismethod(method): continue + # Bypass MPVError: no such event 'init' + if method_name == "on_init": + continue + if method_name.startswith("on_property_"): name = method_name[12:] name = name.replace("_", "-") diff --git a/qt/aqt/sound.py b/qt/aqt/sound.py index 5c8634308..dca5b0c1e 100644 --- a/qt/aqt/sound.py +++ b/qt/aqt/sound.py @@ -19,7 +19,7 @@ from anki.lang import _ from anki.sound import AV_REF_RE, AVTag, SoundOrVideoTag from anki.utils import isLin, isMac, isWin from aqt import gui_hooks -from aqt.mpv import MPV, MPVBase +from aqt.mpv import MPV, MPVBase, MPVCommandError from aqt.qt import * from aqt.taskman import TaskManager from aqt.utils import restoreGeom, saveGeom, showWarning, startup_info @@ -334,6 +334,16 @@ class MpvManager(MPV, SoundOrVideoPlayer): self.default_argv += ["--config-dir=" + base_path] super().__init__(window_id=None, debug=False) + def on_init(self) -> None: + try: + self.command("keybind", "q", "stop") + self.command("keybind", "Q", "stop") + self.command("keybind", "CLOSE_WIN", "stop") + self.command("keybind", "ctrl+w", "stop") + self.command("keybind", "ctrl+c", "stop") + except MPVCommandError: + print("mpv too old") + def play(self, tag: AVTag, on_done: OnDoneCallback) -> None: assert isinstance(tag, SoundOrVideoTag) self._on_done = on_done From 7518597408620687b3c09eedd59ebf80874e9097 Mon Sep 17 00:00:00 2001 From: kelciour Date: Fri, 26 Jun 2020 21:54:12 +0300 Subject: [PATCH 2/4] Replace mpv "idle" property with "end-file" event --- qt/aqt/sound.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/aqt/sound.py b/qt/aqt/sound.py index dca5b0c1e..f1e096a09 100644 --- a/qt/aqt/sound.py +++ b/qt/aqt/sound.py @@ -360,8 +360,8 @@ class MpvManager(MPV, SoundOrVideoPlayer): def seek_relative(self, secs: int) -> None: self.command("seek", secs, "relative") - def on_property_idle_active(self, val) -> None: - if val and self._on_done: + def on_end_file(self) -> None: + if self._on_done: self._on_done() def shutdown(self) -> None: From 39eec24c3d16173d9c165123981bf575e6deaccb Mon Sep 17 00:00:00 2001 From: kelciour Date: Fri, 26 Jun 2020 22:24:44 +0300 Subject: [PATCH 3/4] Fix no sound after mpv restart --- qt/aqt/mpv.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/qt/aqt/mpv.py b/qt/aqt/mpv.py index c5b8a1e29..d991f69b9 100644 --- a/qt/aqt/mpv.py +++ b/qt/aqt/mpv.py @@ -245,10 +245,13 @@ class MPVBase: else: r, w, e = select.select([self._sock], [], [], 1) if r: - b = self._sock.recv(1024) - if not b: - break - buf += b + try: + b = self._sock.recv(1024) + if not b: + break + buf += b + except ConnectionResetError: + return newline = buf.find(b"\n") while newline >= 0: @@ -373,7 +376,7 @@ class MPVBase: return self._get_response(timeout) except MPVCommandError as e: raise MPVCommandError("%r: %s" % (message["command"], e)) - except MPVTimeoutError as e: + except Exception as e: if _retry: print("mpv timed out, restarting") self._stop_process() @@ -400,6 +403,7 @@ class MPVBase: self._start_socket() self._prepare_thread() self._start_thread() + self._register_callbacks() def close(self): """Shutdown the mpv process and our communication setup. @@ -438,6 +442,9 @@ class MPV(MPVBase): super().__init__(*args, **kwargs) + self._register_callbacks() + + def _register_callbacks(self): self._callbacks = {} self._property_serials = {} self._new_serial = iter(range(sys.maxsize)) @@ -483,16 +490,10 @@ class MPV(MPVBase): """Start up the communication threads. """ super()._start_thread() - self._event_thread = threading.Thread(target=self._event_reader) - self._event_thread.daemon = True - self._event_thread.start() - - def _stop_thread(self): - """Stop the communication threads. - """ - super()._stop_thread() - if hasattr(self, "_event_thread"): - self._event_thread.join() + if not hasattr(self, "_event_thread"): + self._event_thread = threading.Thread(target=self._event_reader) + self._event_thread.daemon = True + self._event_thread.start() # # Event/callback API @@ -500,7 +501,7 @@ class MPV(MPVBase): def _event_reader(self): """Collect incoming event messages and call the event handler. """ - while not self._stop_event.is_set(): + while True: message = self._get_event(timeout=1) if message is None: continue From 66d69c34607fbdb4bf2c9629e5b831ad1013fd45 Mon Sep 17 00:00:00 2001 From: kelciour Date: Sat, 27 Jun 2020 12:31:58 +0300 Subject: [PATCH 4/4] Fix "make check" by defining dummy _register_callbacks method in MPVBase --- qt/aqt/mpv.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qt/aqt/mpv.py b/qt/aqt/mpv.py index d991f69b9..e42077047 100644 --- a/qt/aqt/mpv.py +++ b/qt/aqt/mpv.py @@ -384,6 +384,11 @@ class MPVBase: else: raise + def _register_callbacks(self): + """Will be called after mpv restart to reinitialize callbacks + defined in MPV subclass + """ + # # Public API #