-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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 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.
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.
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.
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.