Beets plugin to read all GENRE tags from audio files into a queryable field
Project description
beets-multigenre
A beets plugin that reads all GENRE tags from your audio files and stores them in a queryable flexible attribute.
The Problem
Beets only stores a single genre field per track. When taggers like Lidarr or MusicBrainz Picard write multiple GENRE tags to your files (e.g. Industrial Metal, Neue Deutsche HäRte, Alternative Metal, Electro-Industrial), beets discards all but the first one.
This means queries and smart playlists based on genre are unreliable — a Rammstein track tagged with 5 genres including Neue Deutsche HäRte would only match on Industrial Metal.
The Solution
beets-multigenre reads all GENRE tags directly from the audio file using mutagen and stores them as a semicolon-separated string in a flexible attribute (multi_genres by default). You can then query against this field using beets' regex query syntax.
Before:
$ beet list -f '$genre $album' artist:Rammstein
Industrial Metal Mutter
Industrial Metal Sehnsucht
After:
$ beet list -f '$multi_genres $album' artist:Rammstein
Industrial Metal;Neue Deutsche HäRte;Alternative Metal;Heavy Metal;Rock;Electronic;Industrial;Gothic Metal Mutter
Industrial Metal;Alternative Metal;Neue Deutsche HäRte;Rock;Industrial;Electronic;Metal Sehnsucht
Supported Formats
- FLAC (Vorbis comments)
- MP3 (ID3 TCON frame)
- OGG / OPUS (Vorbis comments)
- M4A / AAC (MP4 atoms)
- WavPack, Musepack, AIFF
Installation
Via pip (recommended)
pip install beets-multigenre
Manual
git clone https://github.com/abstract/beets-multigenre
cp beets-multigenre/beets_multigenre/__init__.py /path/to/your/beets/plugins/multigenre.py
Configuration
Add to your config.yaml:
plugins: multigenre
multigenre:
field: multi_genres # flexible attribute name (default: multi_genres)
separator: ";" # separator between genres (default: ;)
auto: yes # run automatically on import (default: yes)
Usage
Run manually across your library
beet multigenre
Run on a subset
beet multigenre artist:Rammstein
beet multigenre album:"Mutter"
Query by genre
# Regex match - catches any track with "Neue Deutsche" anywhere in multi_genres
beet list multi_genres::"Neue Deutsche"
# Exact substring match
beet list multi_genres:"Industrial Metal"
# Multiple genres (OR)
beet list multi_genres::"Neue Deutsche" multi_genres::"Industrial Metal"
Smart playlists
Use with the smartplaylist plugin:
smartplaylist:
playlists:
- name: 'Neue Deutsche Harte.m3u'
query: 'multi_genres::"Neue Deutsche"'
- name: 'Industrial Night.m3u'
query: 'multi_genres::Industrial multi_genres::EBM multi_genres::"Neue Deutsche" multi_genres::"Electro-Industrial"'
- name: 'Gothic & Darkwave.m3u'
query: 'multi_genres::Gothic multi_genres::"Dark Wave" multi_genres::"Dark Ambient" multi_genres::"Death Rock"'
Why not just use lastgenre?
The lastgenre plugin fetches genres from Last.fm and stores up to count genres as a comma-separated string. This works but:
- Last.fm genre data may differ from MusicBrainz
- Overwrites genres already written by Lidarr/Picard
- Requires API calls and an internet connection
- Still limited to a single concatenated string field
beets-multigenre reads what's already in your files — no API calls, no overwriting, works offline, and respects the work your tagger already did.
Crontab / Automation
If you run beets imports on a schedule, add beet multigenre after the import:
0 * * * * (timeout 3600 beet import -A -q /music; beet multigenre; beet splupdate) > /dev/null 2>&1
Contributing
Issues and PRs welcome at github.com/abstract/beets-multigenre.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file beets_multigenre-1.0.2.tar.gz.
File metadata
- Download URL: beets_multigenre-1.0.2.tar.gz
- Upload date:
- Size: 6.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4b136b5622805a73101a944c0c3799eb555f7571a43895e028b0942e48cbb76
|
|
| MD5 |
bed8fc734ecdaaf2e154d961c8a083ea
|
|
| BLAKE2b-256 |
1a091cd923ae0b9e5bdafa8c6eab4d679d74555f118b5ba7d49eb9aca7a2428c
|
File details
Details for the file beets_multigenre-1.0.2-py3-none-any.whl.
File metadata
- Download URL: beets_multigenre-1.0.2-py3-none-any.whl
- Upload date:
- Size: 6.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8941c8e08fdc05e261a5e95ade3c035aa349febfd15497e3d6d19033821c1f1
|
|
| MD5 |
80d0951e946d60931a42deec699f4701
|
|
| BLAKE2b-256 |
5c35b3c76cf661677385b7917d791ead329e32bfd0b591eae167531a48049ec2
|