aqt.sound
=========

.. py:module:: aqt.sound


Attributes
----------

.. autoapisummary::

   aqt.sound.OnDoneCallback
   aqt.sound.AUDIO_EXTENSIONS
   aqt.sound.av_player
   aqt.sound.si
   aqt.sound.mpvManager


Classes
-------

.. autoapisummary::

   aqt.sound.Player
   aqt.sound.SoundOrVideoPlayer
   aqt.sound.SoundPlayer
   aqt.sound.VideoPlayer
   aqt.sound.AVPlayer
   aqt.sound.SimpleProcessPlayer
   aqt.sound.SimpleMpvPlayer
   aqt.sound.SimpleMplayerPlayer
   aqt.sound.MpvManager
   aqt.sound.SimpleMplayerSlaveModePlayer
   aqt.sound.Recorder
   aqt.sound.QtAudioInputRecorder
   aqt.sound.NativeMacRecorder
   aqt.sound.RecordDialog


Functions
---------

.. autoapisummary::

   aqt.sound.is_audio_file
   aqt.sound.retryWait
   aqt.sound.encode_mp3
   aqt.sound.record_audio
   aqt.sound.clearAudioQueue
   aqt.sound.play
   aqt.sound.playFromText
   aqt.sound.av_refs_to_play_icons
   aqt.sound.play_clicked_audio
   aqt.sound.setup_audio
   aqt.sound.cleanup_audio


Module Contents
---------------

.. py:data:: OnDoneCallback

.. py:class:: Player

   Bases: :py:obj:`abc.ABC`


   Helper class that provides a standard way to create an ABC using
   inheritance.


   .. py:method:: play(tag: anki.sound.AVTag, on_done: OnDoneCallback) -> None
      :abstractmethod:


      Play a file.

      When reimplementing, make sure to call
      gui_hooks.av_player_did_begin_playing(self, tag)
      on the main thread after playback begins.



   .. py:method:: rank_for_tag(tag: anki.sound.AVTag) -> int | None
      :abstractmethod:


      How suited this player is to playing tag.

      AVPlayer will choose the player that returns the highest rank
      for a given tag.

      If None, this player can not play the tag.



   .. py:method:: stop() -> None

      Optional.

      If implemented, the player must not call on_done() when the audio is stopped.



   .. py:method:: seek_relative(secs: int) -> None

      Jump forward or back by secs. Optional.



   .. py:method:: toggle_pause() -> None

      Optional.



   .. py:method:: shutdown() -> None

      Do any cleanup required at program termination. Optional.



.. py:data:: AUDIO_EXTENSIONS

.. py:function:: is_audio_file(fname: str) -> bool

.. py:class:: SoundOrVideoPlayer

   Bases: :py:obj:`Player`


   Helper class that provides a standard way to create an ABC using
   inheritance.


   .. py:attribute:: default_rank
      :value: 0



   .. py:method:: rank_for_tag(tag: anki.sound.AVTag) -> int | None

      How suited this player is to playing tag.

      AVPlayer will choose the player that returns the highest rank
      for a given tag.

      If None, this player can not play the tag.



.. py:class:: SoundPlayer

   Bases: :py:obj:`Player`


   Helper class that provides a standard way to create an ABC using
   inheritance.


   .. py:attribute:: default_rank
      :value: 0



   .. py:method:: rank_for_tag(tag: anki.sound.AVTag) -> int | None

      How suited this player is to playing tag.

      AVPlayer will choose the player that returns the highest rank
      for a given tag.

      If None, this player can not play the tag.



.. py:class:: VideoPlayer

   Bases: :py:obj:`Player`


   Helper class that provides a standard way to create an ABC using
   inheritance.


   .. py:attribute:: default_rank
      :value: 0



   .. py:method:: rank_for_tag(tag: anki.sound.AVTag) -> int | None

      How suited this player is to playing tag.

      AVPlayer will choose the player that returns the highest rank
      for a given tag.

      If None, this player can not play the tag.



.. py:class:: AVPlayer

   .. py:attribute:: players
      :type:  list[Player]
      :value: []



   .. py:attribute:: interrupt_current_audio
      :value: True



   .. py:attribute:: current_caller
      :type:  Any
      :value: None



   .. py:attribute:: current_caller_interrupted
      :value: False



   .. py:attribute:: current_player
      :type:  Player | None
      :value: None



   .. py:method:: play_tags(tags: list[anki.sound.AVTag]) -> None

      Clear the existing queue, then start playing provided tags.



   .. py:method:: append_tags(tags: list[anki.sound.AVTag]) -> None

      Append provided tags to the queue, then start playing them if the current player is idle.



   .. py:method:: queue_is_empty() -> bool


   .. py:method:: stop_and_clear_queue() -> None


   .. py:method:: stop_and_clear_queue_if_caller(caller: Any) -> None


   .. py:method:: clear_queue_and_maybe_interrupt() -> None


   .. py:method:: play_file(filename: str) -> None

      Play the provided path.

      SECURITY: Filename may be an arbitrary path. For filenames coming from a collection,
      you should only ever use the os.path.basename(filename) as the filename.



   .. py:method:: play_file_with_caller(filename: str, caller: Any) -> None

      Play the provided path, noting down the caller.

      SECURITY: Filename may be an arbitrary path. For filenames coming from a collection,
      you should only ever use the os.path.basename(filename) as the filename.



   .. py:method:: insert_file(filename: str) -> None

      Place the provided path at the top of the playlist.

      SECURITY: Filename may be an arbitrary path. For filenames coming from a collection,
      you should only ever use the os.path.basename(filename) as the filename.



   .. py:method:: toggle_pause() -> None


   .. py:method:: seek_relative(secs: int) -> None


   .. py:method:: shutdown() -> None


.. py:data:: av_player

.. py:data:: si
   :value: None


.. py:function:: retryWait(proc: subprocess.Popen) -> int

.. py:class:: SimpleProcessPlayer(taskman: aqt.taskman.TaskManager, media_folder: str | None = None)

   Bases: :py:obj:`Player`


   A player that invokes a new process for each tag to play.


   .. py:attribute:: args
      :type:  list[str]
      :value: []



   .. py:attribute:: env
      :type:  dict[str, str] | None
      :value: None



   .. py:method:: play(tag: anki.sound.AVTag, on_done: OnDoneCallback) -> None

      Play a file.

      When reimplementing, make sure to call
      gui_hooks.av_player_did_begin_playing(self, tag)
      on the main thread after playback begins.



   .. py:method:: stop() -> None

      Optional.

      If implemented, the player must not call on_done() when the audio is stopped.



.. py:class:: SimpleMpvPlayer(taskman: aqt.taskman.TaskManager, base_folder: str, media_folder: str)

   Bases: :py:obj:`SimpleProcessPlayer`, :py:obj:`VideoPlayer`


   A player that invokes a new process for each tag to play.


   .. py:attribute:: default_rank
      :value: 1



.. py:class:: SimpleMplayerPlayer(taskman: aqt.taskman.TaskManager, media_folder: str | None = None)

   Bases: :py:obj:`SimpleProcessPlayer`, :py:obj:`SoundOrVideoPlayer`


   A player that invokes a new process for each tag to play.


.. py:class:: MpvManager(base_path: str, media_folder: str)

   Bases: :py:obj:`aqt.mpv.MPV`, :py:obj:`SoundOrVideoPlayer`


   Class for communication with the mpv media player via unix socket
   based JSON IPC. It adds a few usable methods and a callback API.

   To automatically register methods as event callbacks, subclass this
   class and define specially named methods as follows:

       def on_file_loaded(self):
           # This is called for every 'file-loaded' event.
           ...

       def on_property_time_pos(self, position):
           # This is called whenever the 'time-pos' property is updated.
           ...

   Please note that callbacks are executed inside a separate thread. The
   MPV class itself is completely thread-safe. Requests from different
   threads to the same MPV instance are synchronized.


   .. py:attribute:: default_argv
      :value: ['--idle', '--no-terminal', '--force-window=no', '--ontop', '--audio-display=no',...



   .. py:attribute:: media_folder


   .. py:attribute:: executable


   .. py:method:: on_init() -> None


   .. py:method:: play(tag: anki.sound.AVTag, on_done: OnDoneCallback) -> None

      Play a file.

      When reimplementing, make sure to call
      gui_hooks.av_player_did_begin_playing(self, tag)
      on the main thread after playback begins.



   .. py:method:: stop() -> None

      Optional.

      If implemented, the player must not call on_done() when the audio is stopped.



   .. py:method:: toggle_pause() -> None

      Optional.



   .. py:method:: seek_relative(secs: int) -> None

      Jump forward or back by secs. Optional.



   .. py:method:: on_property_idle_active(value: bool) -> None


   .. py:method:: shutdown() -> None

      Do any cleanup required at program termination. Optional.



   .. py:attribute:: togglePause


   .. py:attribute:: seekRelative


   .. py:method:: queueFile(file: str) -> None


   .. py:method:: clearQueue() -> None


.. py:class:: SimpleMplayerSlaveModePlayer(taskman: aqt.taskman.TaskManager, media_folder: str)

   Bases: :py:obj:`SimpleMplayerPlayer`


   A player that invokes a new process for each tag to play.


   .. py:attribute:: media_folder


   .. py:method:: command(*args: Any) -> None

      Send a command over the slave interface.

      The trailing newline is automatically added.



   .. py:method:: seek_relative(secs: int) -> None

      Jump forward or back by secs. Optional.



   .. py:method:: toggle_pause() -> None

      Optional.



.. py:function:: encode_mp3(mw: aqt.AnkiQt, src_wav: str, on_done: collections.abc.Callable[[str], None]) -> None

   Encode the provided wav file to .mp3, and call on_done() with the path.


.. py:class:: Recorder(output_path: str)

   Bases: :py:obj:`abc.ABC`


   Helper class that provides a standard way to create an ABC using
   inheritance.


   .. py:attribute:: STARTUP_DELAY
      :value: 0.3



   .. py:attribute:: output_path


   .. py:method:: start(on_done: collections.abc.Callable[[], None]) -> None

      Start recording, then call on_done() when started.



   .. py:method:: stop(on_done: collections.abc.Callable[[str], None]) -> None

      Stop recording, then call on_done() when finished.



   .. py:method:: duration() -> float

      Seconds since recording started.



   .. py:method:: on_timer() -> None

      Will be called periodically.



.. py:class:: QtAudioInputRecorder(output_path: str, mw: aqt.AnkiQt, parent: QWidget)

   Bases: :py:obj:`Recorder`


   Helper class that provides a standard way to create an ABC using
   inheritance.


   .. py:attribute:: mw


   .. py:method:: start(on_done: collections.abc.Callable[[], None]) -> None

      Start recording, then call on_done() when started.



   .. py:method:: stop(on_done: collections.abc.Callable[[str], None]) -> None

      Stop recording, then call on_done() when finished.



.. py:class:: NativeMacRecorder(output_path: str)

   Bases: :py:obj:`Recorder`


   Helper class that provides a standard way to create an ABC using
   inheritance.


   .. py:method:: start(on_done: collections.abc.Callable[[], None]) -> None

      Start recording, then call on_done() when started.



   .. py:method:: stop(on_done: collections.abc.Callable[[str], None]) -> None

      Stop recording, then call on_done() when finished.



.. py:class:: RecordDialog(parent: QWidget, mw: aqt.AnkiQt, on_success: collections.abc.Callable[[str], None])

   Bases: :py:obj:`QDialog`


   .. py:attribute:: mw


   .. py:method:: accept() -> None


   .. py:method:: reject() -> None


.. py:function:: record_audio(parent: QWidget, mw: aqt.AnkiQt, encode: bool, on_done: collections.abc.Callable[[str], None]) -> None

.. py:function:: clearAudioQueue() -> None

.. py:function:: play(filename: str) -> None

.. py:function:: playFromText(text: Any) -> None

.. py:data:: mpvManager
   :type:  MpvManager | None
   :value: None


.. py:function:: av_refs_to_play_icons(text: str) -> str

   Add play icons into the HTML.

   When clicked, the icon will call eg pycmd('play:q:1').


.. py:function:: play_clicked_audio(pycmd: str, card: anki.cards.Card) -> None

   eg. if pycmd is 'play:q:0', play the first audio on the question side.


.. py:function:: setup_audio(taskman: aqt.taskman.TaskManager, base_folder: str, media_folder: str) -> None

.. py:function:: cleanup_audio() -> None

