Skip to content
Adrian Sampson edited this page Apr 7, 2018 · 3 revisions

Beets Concepts

This is a high-level, theoretical look at how beets works. If you're a beets user, it will help you understand why beets works the way it does. If you're a developer, it well help you navigate the beets source code. This page will eventually be moved to the official beets documentation.

The Library: Beets' Data Model

The Library is beets' core concept. A Library is a database that catalogs your music (the library does not contain any music files; as a database, it just points to music files). A Library contains Items and Albums. An Item is a single track of music, and it consists of a set of metadata fields and the path to a music file. (The vague "Item" name is meant to convey a sense of generality; beets might, eventually, track non-music media.) An Album is a sequence of Items and consists of a set of album-level metadata that is shared among the Items. (An Album can actually represent any kind of release: EP, single, compilation, etc.) Each Item belongs to at most one Album; an Item without an Album is called a singleton.

In MusicBrainz parlance, an Item is a recording and an Album is a release. Beets does not currently have concepts corresponding to MusicBrainz tracks, works, release groups, or mediums.

The user adds music to a Library by importing it (i.e., using the beet import command). Importing music, at its most basic, just consists of adding Items to the Library corresponding to some files that exist on disk (possibly with accompanying Albums). However, in practice, the importer does lots of other stuff at the same time: mainly, cleaning up metadata using MusicBrainz and copying/renaming files.

In this sense, the importer acts as a gatekeeper to the Library, which maintains certain invariants (e.g., files are located in a certain directory, metadata is reasonably clean, a naming convention is used). However, it's entirely possible for a Library to exhibit no invariants at all: the user can treat it just as a bag of Items/Albums (i.e., using beet import -AC to disable metadata correction and renaming). In either case, the Library concept is essential because everything beets does acts on the Library.

Queries

To operate on the Library, queries are used to select subsets of Albums and Items. You can think of queries as SQL SELECT statements. In practice, queries are user-friendly expressions that make it easy to find the Items or Albums you're looking for.

Most operations in beets (in the CLI, list, remove, stats, move, modify, update) work by querying the Library for Items or Albums and then performing some action on them. This lends uniformity to beets' interactions: every command queries and then operates; only the per-Album or per-Item operation differs.

Paths and Destinations

File naming is an important component of beets. Each Item has a destination, which is the path it would reside at if it were renamed according to the user's preferred scheme. In its default setup, the beet import command copies items to their destinations as they are imported.

The destination consists of two parts: the root directory (specified as directory in the config file) and the template-specified fragment. The fragment is generated based on the path format templates specified by the user. The user specifies query/template pairs in the config file; the template corresponding to the first query to match a given Item is used to generate the Item's destination.

The beet move command works by copying/moving files to a path generated by concatenating a different root directory with each Item's destination fragment.

Auto-Tagging

Beets has two auto-tagging workflows: one for Albums and one for Items (i.e., singletons). Beets uses the filesystem (or user input) to group files into Albums for the Album tagger, which is the default. Each Album or Item is then used to query a metadata provider (currently MusicBrainz) for canonical metadata.