Correct way of playing sound contained within a sound tag

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)
1 Like

Can’t you use card.question/answer_av_tags()?

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)


don’t worry too much about this use case as this particular feature is not super important.

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)

play_sound_in_editor

3 Likes