Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

beets_multigenre-1.0.2.tar.gz (6.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

beets_multigenre-1.0.2-py3-none-any.whl (6.0 kB view details)

Uploaded Python 3

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

Hashes for beets_multigenre-1.0.2.tar.gz
Algorithm Hash digest
SHA256 e4b136b5622805a73101a944c0c3799eb555f7571a43895e028b0942e48cbb76
MD5 bed8fc734ecdaaf2e154d961c8a083ea
BLAKE2b-256 1a091cd923ae0b9e5bdafa8c6eab4d679d74555f118b5ba7d49eb9aca7a2428c

See more details on using hashes here.

File details

Details for the file beets_multigenre-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for beets_multigenre-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a8941c8e08fdc05e261a5e95ade3c035aa349febfd15497e3d6d19033821c1f1
MD5 80d0951e946d60931a42deec699f4701
BLAKE2b-256 5c35b3c76cf661677385b7917d791ead329e32bfd0b591eae167531a48049ec2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page