#+title: listen.el

# ELPA badge image.
[[https://elpa.gnu.org/packages/listen.html][https://elpa.gnu.org/packages/listen.svg]]

This package aims to provide a simple audio/music player for Emacs.  It should "just work," with little-to-no configuration, have intuitive commands, and be easily extended and customized.  (Contrast to setting up EMMS, or having to configure external players like MPD.)  A Transient menu, under the command ~listen~, is the primary entry point.

The only external dependency is VLC, which is currently the only player backend that is supported.  (Other backends may easily be added; see library ~listen-vlc~ for example.)  Track metadata is read using EMMS's native Elisp metadata library, which has been imported into this package.

Queues are provided as the means to play consecutive tracks, and they are shown in a ~vtable~-based view buffer.  They are persisted between sessions using the ~persist~ library, and they may be bookmarked.

The primary interface to one's music library is through the filesystem, by selecting a file to play, or by adding files and directories to a queue.  Although MPD is not required, support is provided for finding files from a local MPD server's library using MPD's metadata searching.

A simple "library" view is provided that shows a list of files organized into a hierarchy by genre, date, artist, album, etc.  (This will be made more configurable and useful in the future.)

Note a silly limitation: a track may be present in a queue only once (but who would want to have a track more than once in a playlist).

* Contents                                                         :noexport:
:PROPERTIES:
:TOC:      :include siblings :depth 0 :force (nothing) :ignore (this) :local (nothing)
:END:
:CONTENTS:
- [[#screenshots][Screenshots]]
- [[#installation][Installation]]
- [[#configuration][Configuration]]
- [[#usage][Usage]]
- [[#changelog][Changelog]]
- [[#development][Development]]
:END:

* Screenshots

[[file:images/screenshot-modus-vivendi-tinted.png]]

* Installation

*Requirements:*
+ Emacs version 29.1 or later.
+ [[https://www.videolan.org/vlc/][VLC]]: used to play audio.
+ Optional: ~ffprobe~ (part of [[https://ffmpeg.org/ffprobe.html][FFmpeg]]) is used to read tracks' duration when available.

** GNU ELPA

Listen.el is published in [[http://elpa.gnu.org/][GNU ELPA]] as [[https://elpa.gnu.org/packages/listen.html][listen]], so it may be installed in Emacs with the command ~M-x package-install RET listen RET~.  This is the recommended way to install Listen.el, as it will install the current stable release.

The latest development build may be installed from [[https://elpa.gnu.org/devel/listen.html][ELPA-devel]] or from Git (see below).

** Git

The ~master~ branch of the Git repository is intended to be usable at all times; only minor bugs are expected to be found in it before a new stable release is made.

To install, it is recommended to use [[https://github.com/quelpa/quelpa-use-package][quelpa-use-package]], like this (using [[https://github.com/alphapapa/unpackaged.el#upgrade-a-quelpa-use-package-forms-package][this helpful command]] for upgrading versions):

#+BEGIN_SRC elisp
  ;; Install and load `quelpa-use-package'.
  (package-install 'quelpa-use-package)
  (require 'quelpa-use-package)

  ;; Install Listen.
  (use-package listen
    :quelpa (listen :fetcher github :repo "alphapapa/listen.el"))
#+END_SRC

One might also use systems like [[https://github.com/progfolio/elpaca][Elpaca]] or [[https://github.com/radian-software/straight.el][Straight]] (which is also used by [[https://github.com/doomemacs/doomemacs][DOOM]]), but the author cannot offer support for them.

* Configuration

Listen is intended to work with little-to-no configuration.  You can set the ~listen-directory~ to the location of your music library if it's not at ~~/Music~.  See ~M-x customize-group RET listen RET~.

* Usage

Use the command ~listen~ to show the Transient menu.  From there, it is--hopefully--self-explanatory.  Please feel free to give feedback if it doesn't seem so.

* Changelog

** v0.6-pre

*Additions*
+ In library buffer, show disc number when available.

*Changes*
+ Reverting library buffers shows tracks from the queue or MPD query originally selected.
+ Command ~listen-queue-add-files~ no longer plays the queue automatically.
+ Command ~listen-library-play-or-add~ renamed to ~listen-library-play~, and it now plays the selected queue when playing multiple tracks.
+ Face ~listen-album~ slants italic.
+ In library buffer, prefer album-artist over artist tag when available.
+ Use half the number of CPUs to read track durations, by default.

*Fixes*
+ Reading new queue name when no queue is playing.

** v0.5.1

*Fixes*
+ Viewing queues which aren't currently playing.

** v0.5

*Additions*
+ Command ~listen-queue-list~ shows a list of queues.
+ Command ~listen-jump~ (bound to ~j~ in queue and library buffers) jumps to the track at point in a Dired buffer.
+ Command ~listen-track-view~ shows a track's complete metadata in a table view.
+ Mode ~listen-queue-delay-mode~ plays a queue with a configurable, random delay between tracks.
+ Option ~listen-queue-repeat-mode~ (also settable in ~listen-menu~) allows repeating a queue in-order or shuffled.
+ Option ~listen-lighter-extra-functions~ allows displaying extra information in the ~listen-mode~ lighter.
+ Option ~listen-track-end-functions~ allows running functions when a track finishes playing.
+ Show total queue duration at bottom of track list.
+ Show track ratings in library and queue buffers.

*Changes*
+ All metadata in MP3 and Ogg files is available for display (not only standard tags).
+ For date field in library and queue views, show ~originalyear~ or ~originaldate~ metadata fields in preference to ~date~ (which seems generally more useful, as the ~date~ field may contain a full date, and sometimes of a later release).

*Fixes*
+ Increase timeout for reading track durations.
+ Command ~listen-queue-deduplicate~ first removes any tracks not backed by a file.
+ In queue buffer, mark current track by comparing filename (rather than internal track identity).

** v0.4

*Additions*
+ Command ~listen-queue-deduplicate~ removes duplicate tracks from a queue (by comparing artist, album, and title metadata case-insensitively).
+ Read track durations with ~ffprobe~ and show in library and queue views.
+ Bound key ~?~ to open the ~listen~ Transient menu in library and queue views.

*Fixes*
+ Transposing a track in a queue keeps point on the track.
+ Autoloading of ~listen~ command.

** v0.3

*Additions*
+ Command ~listen-library-from-mpd~ shows tracks selected from MPD in a library view.
+ Command ~listen-library-from-queue~ shows tracks selected from a queue buffer in a library view.
+ Command ~listen-library-from-playlist-file~ shows tracks from an M3U playlist in a library view.
+ Command ~listen-queue-add-from-playlist-file~ adds tracks from an M3U playlist file to a queue.

*Changes*
+ Reading tracks from MPD allows multiple selection using ~completing-read-multiple~.
+ Various improvements in robustness.
+ Command ~listen-queue~ doesn't recreate its buffer when already open.
+ Key bindings in ~listen~ Transient menu.
+ Function ~listen-queue-complete~ accepts argument ~:allow-new-p~ to return a new queue if the entered name doesn't match an existing one.

*Fixes*
+ Completing read of tracks from MPD.
+ Unset VLC process's query-on-exit flag.

*Credits*
+ Thanks to [[https://amodernist.com/][Philip Kaludercic]] for reviewing.

** v0.2

*Additions*
+ Command ~listen-queue-jump~ jumps to the currently playing track in the queue.
+ Command ~listen-queue-shell-command~ runs a shell command on the tracks selected in the queue.
+ Reverting a queue buffer with universal prefix argument refreshes the tracks' metadata from disk.

*Fixes*
+ The queue could sometimes skip tracks when playing.
+ Improve handling of tracks that are changed during playback (e.g. metadata).
+ Update copyright statements in all libraries.

** v0.1

Initial release.

* Development

Feedback and patches are welcome.

** Copyright assignment

Listen.el is published in GNU ELPA and is considered part of GNU Emacs.  Therefore, cumulative contributions of more than 15 lines of code require that the author assign copyright of such contributions to the FSF.  Authors who are interested in doing so may contact [[mailto:assign@gnu.org][assign@gnu.org]] to request the appropriate form.

* COMMENT Export setup                                             :noexport:
:PROPERTIES:
:TOC:      :ignore this
:END:

# Copied from org-super-agenda's readme, in which much was borrowed from Org's =org-manual.org=.

#+OPTIONS: broken-links:t *:t num:1 toc:1

** Info export options

#+EXPORT_FILE_NAME: listen.texi
#+TEXINFO_DIR_CATEGORY: Emacs
#+TEXINFO_DIR_TITLE: Listen: (listen)
#+TEXINFO_DIR_DESC: Audio/Music player

# NOTE: We could use these, but that causes a pointless error, "org-compile-file: File "..README.info" wasn't produced...", so we just rename the files in the after-save-hook instead.
# #+TEXINFO_FILENAME: listen.info

** File-local variables

# NOTE: Setting org-comment-string buffer-locally is a nasty hack to work around GitHub's org-ruby's HTML rendering, which does not respect noexport tags.  The only way to hide this tree from its output is to use the COMMENT keyword, but that prevents Org from processing the export options declared in it.  So since these file-local variables don't affect org-ruby, wet set org-comment-string to an unused keyword, which prevents Org from deleting this tree from the export buffer, which allows it to find the export options in it.  And since org-export does respect the noexport tag, the tree is excluded from the info page.

# Local Variables:
# before-save-hook: org-make-toc
# org-export-with-properties: ()
# org-export-with-title: t
# org-export-initial-scope: buffer
# org-comment-string: "NOTCOMMENT"
# End:
