From 91b3740554728cf3e10f2d93f284cc2d5c3cdb9b Mon Sep 17 00:00:00 2001 From: llama <100429699+iamllama@users.noreply.github.com> Date: Sat, 4 Jan 2025 23:55:40 +0800 Subject: [PATCH] Stop audio playback on editor close (#3666) * stop audio playback on browser close * revert fix * add caller-aware versions of play_file and stop_and_clear_queue * stop editor's audio autoplay on close * remove superfluous stop_and_clear_queue from addcards --- qt/aqt/addcards.py | 1 - qt/aqt/editor.py | 3 ++- qt/aqt/sound.py | 11 +++++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/qt/aqt/addcards.py b/qt/aqt/addcards.py index a447b95c1..306ac910f 100644 --- a/qt/aqt/addcards.py +++ b/qt/aqt/addcards.py @@ -341,7 +341,6 @@ class AddCards(QMainWindow): evt.ignore() def _close(self) -> None: - av_player.stop_and_clear_queue() self.editor.cleanup() self.notetype_chooser.cleanup() self.deck_chooser.cleanup() diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index ff07de711..e1b120363 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -700,6 +700,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too return True def cleanup(self) -> None: + av_player.stop_and_clear_queue_if_caller(self.editorMode) self.set_note(None) # prevent any remaining evalWithCallback() events from firing after C++ object deleted if self.web: @@ -850,7 +851,7 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too name = urllib.parse.quote(fname.encode("utf8")) return f'' else: - av_player.play_file(fname) + av_player.play_file_with_caller(fname, self.editorMode) return f"[sound:{html.escape(fname, quote=False)}]" def urlToFile(self, url: str) -> str | None: diff --git a/qt/aqt/sound.py b/qt/aqt/sound.py index 36e3b2914..e377d001e 100644 --- a/qt/aqt/sound.py +++ b/qt/aqt/sound.py @@ -140,6 +140,8 @@ class AVPlayer: # when a new batch of audio is played, should the currently playing # audio be stopped? interrupt_current_audio = True + # caller key for the current playback (optional) + current_caller = None def __init__(self) -> None: self._enqueued: list[AVTag] = [] @@ -163,6 +165,10 @@ class AVPlayer: self._enqueued = [] self._stop_if_playing() + def stop_and_clear_queue_if_caller(self, caller) -> None: + if caller == self.current_caller: + self.stop_and_clear_queue() + def clear_queue_and_maybe_interrupt(self) -> None: self._enqueued = [] if self.interrupt_current_audio: @@ -171,6 +177,10 @@ class AVPlayer: def play_file(self, filename: str) -> None: self.play_tags([SoundOrVideoTag(filename=filename)]) + def play_file_with_caller(self, filename: str, caller) -> None: + self.current_caller = caller + self.play_file(filename) + def insert_file(self, filename: str) -> None: self._enqueued.insert(0, SoundOrVideoTag(filename=filename)) self._play_next_if_idle() @@ -198,6 +208,7 @@ class AVPlayer: return self._enqueued.pop(0) def _on_play_finished(self) -> None: + self.current_caller = None gui_hooks.av_player_did_end_playing(self.current_player) self.current_player = None self._play_next_if_idle()