A beets plugin to assign genres to all items within your music library.
- Gets genres from last.fm using the lastgenre plugin.
- Favours track as last.fm genre source when track is a remix.
- Fallback to estimating the genre using the xtractor plugin / Essentia.
- Fixes the genre of (re)mixes by matching the genre tree against the track and album title.
- Allows to specify the genre per item manually.
The following beets plugins and their dependencies must be installed:
- lastgenre plugin.
- xtractor plugin which relies on Essentia.
python3 -m pip install beets-autogenreEnable the plugin and add a autogenre section to your beets config.yaml as follows:
plugins:
- autogenre
- lastgenre
- xtractor
autogenre:
pretend: false
all: false
force: false
lastgenre: true
xtractor: true
from_title: true
genre_rosamerica_strong: 0.8
genre_electronic_strong: 0.8
genre_electronic_prepend: 0.5
genre_electronic_append: 0.45
lastgenre:
auto: false
prefer_specific: true
source: album
count: 4
min_weight: 15
canonical: /etc/beets/genre-tree.yaml
whitelist: /etc/beets/genres.txt
xtractor:
auto: no
dry-run: no
write: yes
threads: 4
force: no
quiet: no
keep_output: no
keep_profiles: no
output_path: /tmp/xtractor
essentia_extractor: /usr/local/bin/essentia_streaming_extractor_music
high_level_targets:
genre_rosamerica_probability: # 0..1
path: "highlevel.genre_rosamerica.probability"
type: float
genre_electronic:
path: "highlevel.genre_electronic.value"
type: string
genre_electronic_probability: # 0..1
path: "highlevel.genre_electronic.probability"
type: float
timbre: # "dark" or "bright"
path: "highlevel.timbre.value"
type: string
tonal_atonal: # "tonal" or "atonal"
path: "highlevel.tonal_atonal.value"
type: string
key_edma: # e.g. "C#"
path: "tonal.key_edma.key"
type: string
key_edma_scale: # e.g. "minor"
path: "tonal.key_edma.scale"
type: string
extractor_profile:
highlevel:
svm_models:
- /var/lib/essentia/svm-models/beta5/danceability.history
- /var/lib/essentia/svm-models/beta5/gender.history
- /var/lib/essentia/svm-models/beta5/genre_rosamerica.history
- /var/lib/essentia/svm-models/beta5/genre_electronic.history
- /var/lib/essentia/svm-models/beta5/mood_acoustic.history
- /var/lib/essentia/svm-models/beta5/mood_aggressive.history
- /var/lib/essentia/svm-models/beta5/mood_electronic.history
- /var/lib/essentia/svm-models/beta5/mood_happy.history
- /var/lib/essentia/svm-models/beta5/mood_sad.history
- /var/lib/essentia/svm-models/beta5/mood_party.history
- /var/lib/essentia/svm-models/beta5/mood_relaxed.history
- /var/lib/essentia/svm-models/beta5/moods_mirex.history
- /var/lib/essentia/svm-models/beta5/voice_instrumental.history
- /var/lib/essentia/svm-models/beta5/tonal_atonal.history
- /var/lib/essentia/svm-models/beta5/timbre.historyFor more information, see CLI.
Once the autogenre plugin is enabled within your beets configuration, you can detect and assign the genres for each track within your library as follows:
beet autogenreUsage: beet autogenre [options]
Options:
-h, --help show this help message and exit
--pretend do not persist item changes but log them
-f, --force reevaluate genres for items with a matching genre_source
-a, --all overwrite genre if genre_source not specified
--no-all do not overwrite genre from unspecified source
--lastgenre use lastgenre plugin
--no-lastgenre do not use lastgenre plugin
--xtractor use xtractor plugin
--no-xtractor do not use xtractor plugin
--from-title derive genre from title
--no-from-title do not derive genre from title
--parent-genres add primary genre's parent genres
--no-parent-genres do not add primary genre's parent genres
--genre=GENRE specify the genre to assign to the selected items
Run the unit tests (containerized):
make testRun the e2e tests (containerized):
make test-e2eTo test your plugin changes manually, you can run a shell within a beets docker container as follows:
make beets-shA temporary beets library is written to ./data.
It can be removed by calling make clean-data.