What’s the right way of playing sounds contained within a sound tag in a field ?
The following code fields the warning “Accessing the backend directly will break in the future. Please use the public methods on Collection instead.”. I don’t see an equivalent of this method on the collection object.
def play_anki_sound_tag(self, text):
out = aqt.mw.col.backend.extract_av_tags(text=text, question_side=True)
file_list = [
x.filename
for x in anki.template.av_tags_to_native(out.av_tags)
if isinstance(x, anki.sound.SoundOrVideoTag)
]
if len(file_list) >= 1:
filename = file_list[0]
aqt.sound.av_player.play_file(filename)
I use this inside the editor, a field which is registered as type “sound” will have a play button. (my addon Language Tools associates a language with each field, and sound fields are also registered that way)
I have created and am currently using a small add-on that allows me to play [sound:...] tag files in the editor from the right-click context menu, similar to that feature of your add-on. I’m not sure if it’s a correct way, but in my add-on I use regular expressions to extract the sound tags. Here is the source code.
import re
from pathlib import Path
import anki
import aqt
# https://fonts.google.com/icons
PLAY_ICON = str(
Path(__file__).parent.resolve() / "icon" / "play_circle_outline-24px.svg"
)
def get_inverted_icon(icon):
""" for Night Mode """
img = icon.pixmap(32).toImage()
img.invertPixels()
new_icon = aqt.qt.QIcon(aqt.qt.QPixmap.fromImage(img))
return new_icon
def on_editor_will_show_context_menu(
editor_webview: aqt.editor.EditorWebView, menu: aqt.qt.QMenu # type: ignore
):
assert aqt.mw is not None
note: anki.notes.Note = editor_webview.editor.note # type: ignore
sound_regex = aqt.mw.col.media.sound_regexps[0]
for match in re.finditer(sound_regex, note.joinedFields()):
filename = match.group("fname")
truncated_filename = f"...{filename[-24:]}" if len(filename) > 24 else filename
icon = aqt.qt.QIcon(PLAY_ICON) # type: ignore
if aqt.mw.pm.night_mode():
icon = get_inverted_icon(icon)
menu.addAction(
icon,
truncated_filename,
lambda f=filename: aqt.sound.av_player.play_file(f),
)
aqt.gui_hooks.editor_will_show_context_menu.append(on_editor_will_show_context_menu)