Beets

Beets is a music tagger and library organizer using the MusicBrainz database. It has been initially released in 2010 and is regularly updated since.

Installation

Install the beets package or beets-gitAUR for the development version.

The audio file decoding backend of Beets is audioread, a project developed by the same team. This backend works itself by using, among others, FFmpeg and/or GStreamer (including its gst-libav and gst-plugins-good packages) as backends.

Additionally, see the #Plugins for plugin specific dependencies.

Configuration

Tip: Beets provides a command for configuration manipulations. To edit the configuration file, run beet config -e. It will be opened with the text editor specified in the environment variable EDITOR.

User configuration is done using YAML syntax. For example:

~/.config/beets/config.yaml
directory: ~/beets/library/     # Library directory to store music.
library: ~/beets/library.db     # Database file to store library state and metada.

Usage

See the Getting Started guide to start with Beets. In this section, we assume that the reader already know the basics. The following operations are organized by their goal and are more advanced examples than the basics.

Get help and generalities

The beet command and its subcommands (e.g., import, list, etc.) supports a -h/--help flag to print the help. You can list enabled/loaded plugins using beet version. You can enable a verbose output for debugging using the -vv flag. Finally, you can ensure the default behavior without any loaded plugin only for one command using the --plugin="" flag.

Add music

See Beets importing music.

By default, Beets will copy or move imported files as well as writing tags to the file. Beets support a read-only importation mode, where imported files will not be modified nor moved:

$ beet import -A -C -W path

Additionally, one may enable the fetchart plugin using --plugin=fetchart such that Beets will look for album arts in the same directory as the imported file.

List music

See Beets seeing your music.

Beets support custom format for listing the music. The fields name can be either a default/standard field (genre in the following example) or a custom/flexible field (mood in the following example) as long as it is used in the Beets SQLite database:

$ beet ls -f 'Mood: ${mood} Genre: ${genre}' query

Here are some corner cases when listing music:

  • List files without titles in their tags:
$ beet list -p "title::^$"
  • List missing files in the library:
$ beet --plugin="badfiles" bad 2>/dev/null | grep "file does not exist"
  • Delete missing files from the library automatically:
$ beet --plugin="badfiles" bad 2>/dev/null | grep "file does not exist" | cut -d ":" -f 1 | xargs -I% beet remove -f path::%

Remove music

See Beets remove.

Tip: If you remove music from your filesystem or do any changes to the files without using beet, do not forget to run beet update to update your library database.

Tag music

To run the Beets auto-tagger on already imported music, the way to go is to re-import the files directly from the music library:

  1. ...using a path: beet import /my/beets/library/my/album
  2. ...using a query (see #Querying)]: beet import -L query

To manually tag music, one may use the modify command or the edit command from the edit plugin (see #Plugins). Beware that the edit command will use the import configuration regarding moving (move option) and copying (copy option) for moving files after the command completion. For example, you can add two genre tags to the music using:

$ beet modify query genre="genre1;genre2"

Tagging modifications will be written to the database. To reflect the modifications into the file tags, use the following command:

$ beet write query

Querying

Nearly all Beets commands operate on matching items (music files imported into the library) based on a query. You can list the fields available using the beet fields command. The query format is the following:

value
Match songs with value contained in tags title, artist, albumname, albumartist, genre, comments.
#value
Match songs with the bareasc plugin, searching the library using simple ASCII character matching (ignoring special characters).
~value
Match sings with the fuzzy plugin, searching the library using fuzzy matching algorithms.
tag:value
Match songs with tag containing value.
tag::regex
Match songs with tag matching the Python regular expression's regex.
tag:N1..N2
Match songs with tag matching numbers between the range N1 and N2.
tag:=value / tag:=~value
Match songs with tag matching value in a case-sensitive or case-insensitive way, respectively.
SPACE
Logical AND between queries.
,SPACE
Logical OR between queries (the SPACE character after the comma is mandatory to separate the keywords).
^ / -
Logical NOT.

ReplayGain

ReplayGain support is accessible via an included plugin (see #Plugins). One can compute ReplayGain information for files matching the query using:

$ beet --plugin="replaygain" replaygain query
Tip: Add the -w -f flags to force writing the result into file tags.

Album art

Album art is automatically fetched during the import, if the fetchart included plugin is enabled (see #Plugins). After importing, one can:

  • Manually add an image as an album art inside a file metadata:
$ beet --plugin="embedart" embedart -f /path/to/image.jpg query

Ensure that the zero plugin is not loaded, otherwise it will delete our album art after saving it, therefore canceling our command.

  • Import an album art into the library:
$ beet --plugin="fetchart" fetchart -q query

It will search in priority for images on the filesystem, i.e., where the music is stored in the library.

  • Remove album art from files:
    • First, include images in the fields parameter of the zero plugin inside the configuration file.
    • Second, run:
$ beet --plugin="zero" zero query
Warning: There is no confirmation before removing the album art and no output of processed files.

Plugins

Beets supports official plugins and community plugins. Here is a curated list of plugins that add major features that may be available in other music library organizer tools:

replaygain
Support computing and adding ReplayGain information during music import (relies on the FFmpeg or GStreamer backend through the python-gobject package).
chroma
Compute audio fingerprint using the Chromaprint technology and identify songs using the AcoustID online database. Requires the fpcalc command-line tool provided by chromaprint package for fingerprint computation, and python-pyacoustid package for fetching the online database. The fingerprint will be written inside the ACOUSTID_FINGERPRINT tag of files.
lyrics
Search and download lyrics from web databases during music import (relies on the backend python-beautifulsoup4 package).
fetchart
Search the local filesystem and/or download album art from web databases during the music import.
convert
Transcode a library into another directory (e.g., from lossless to lossy transcoding for nomad devices) (relies on backends like FFmpeg).
alternatives
External plugin supporting multiple versions (e.g., a lossless and lossy version) or locations for the library.
playlist
Read playlists in m3u format.
smartplaylist
Create and automatically update playlists in m3u format based on predefined queries.
fuzzy
Search the library using fuzzy pattern matching.
edit
Modify music metadata inside external editors (e.g., configuring the EDITOR variable for Vim, Emacs, etc.).
badfiles
Check for corrupted files using checksum. Requires flac for FLAC files mp3valAUR for MP3 files.

Tips and tricks

Enabling tab autocompletion

Autocompletion is supported for Bash and Zsh.

Bash

Beets includes support for Bash shell command completion. To enable completion, put the following line into your .bashrc:

~/.bashrc
eval "$(beet completion)"

You will also need to install the package bash-completion for this to work.

Zsh

The official Arch package install the Zsh completion on the system. If using another installation method, to install the completions, make the beets/extra/_beet (from the upstream repository) file available in one of the Zsh's $fpath directories (either by a copy or symlink). Using the Zsh's Bash completion compatibility as suggested by the documentation does only work partially.

Setup the library directory (external drive, network)

Once imported, Beets hard code the path of each item of the library inside the SQLite's .db database file. Therefore, it is recommended to use a fixed path on the filesystem using a link redirecting to the actual directory storing the Beets library.

Note: It is possible to use a symbolic link instead of an hardlink, since Beets will not dereference the link. Compared to an hardlink, it allows to point on a different filesystem (e.g., an external drive).

It has the following advantages:

  1. Having the link of the library pointing to different paths across machines, when the library is synced but not available on the same path.
  2. Allowing to dynamically change the path of the library by updating the symbolic link, for example, when switching to a synced external hard drive.
  3. Not having to deal with SQLite's database items path when the library is moved. Indeed, if you change the library location on the filesystem without any beet command, it will be cumbersome to change the path of already imported items inside the database file (see #Updating the library directory).

As an example, to use a symlink with a fixed path of /srv/beets pointing to a library mounted over network at /mnt/network/beets, execute:

$ ln -sfT /srv/beets /mnt/network/beets

You can rexecute the same command to update the symlink to another location later. In the configuration file, one should have:

~/.config/beets/config.yaml
directory: /srv/beets

Updating the library directory

According to Beets' FAQ, two regular options are offered to modify the path to the library directory (containing music files) after the files have been imported:

  1. Make the modification in ~/.config/beets/config.yaml and use beet move. This solution has the disadvantage that the library should be moved by Beets itself, and not before by an external program.
  2. Delete the SQLite database (.db file) and re-create it from the new path using beet import -AWC. This solution has the disadvantage that the custom tags that are stored inside the SQLite database itself (instead of inside the music files' metadata/header) would be lost.

The last solution suggested by Beets developers are to manually modifying the SQLite database without further indication. This can be achieved by the following, assuming that SQLite is installed, and that the old and new paths of the library was /old/library/path and /new/library/path, respectively.

1. Make a backup of the library database and open it:

$ cp /path/to/library.db /path/to/library.db.bak"
$ sqlite /path/to/library.db

2. List the tables to check that the scheme corresponds to the following UPDATE requests, and update it (in-place):

sqlite> .schema
sqlite> UPDATE items  SET path    = REPLACE(path,    '/old/library/path', '/new/library/path');
sqlite> UPDATE albums SET artpath = REPLACE(artpath, '/old/library/path', '/new/library/path');

3. Exit SQLite:

sqlite> .exit

4. Check that Beets correctly list the files of the library under the new path:

$ beet ls -p [QUERY]

Synchronization across computers and external drives

Beets does not implement any syncing mechanisms on its own. However, its architecture makes it well suited to be used with other FOSS syncing software (as reported in its GitHub Issue #271):

Syncthing
For syncing the SQLite database and the library across devices.
git-annex
For syncing the library with a more advanced and fine-grained configuration across devices and external drives.

See also

This article is issued from Archlinux. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.