{"id":18733935,"url":"https://github.com/mgoltzsche/beets-autogenre","last_synced_at":"2025-07-21T05:03:41.140Z","repository":{"id":216740116,"uuid":"736483659","full_name":"mgoltzsche/beets-autogenre","owner":"mgoltzsche","description":"beets plugin to auto-detect the genre for each item within your music library","archived":false,"fork":false,"pushed_at":"2025-02-03T00:20:33.000Z","size":57,"stargazers_count":13,"open_issues_count":5,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-18T11:42:56.739Z","etag":null,"topics":["beets","beets-plugin","genre","genre-classification","genre-suggestion","genres","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mgoltzsche.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-12-28T03:16:31.000Z","updated_at":"2025-07-14T13:21:18.000Z","dependencies_parsed_at":"2024-01-12T13:11:34.351Z","dependency_job_id":"ec83bc97-9223-445c-8559-56ee2a02a978","html_url":"https://github.com/mgoltzsche/beets-autogenre","commit_stats":null,"previous_names":["mgoltzsche/beets-autogenre"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/mgoltzsche/beets-autogenre","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgoltzsche%2Fbeets-autogenre","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgoltzsche%2Fbeets-autogenre/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgoltzsche%2Fbeets-autogenre/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgoltzsche%2Fbeets-autogenre/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mgoltzsche","download_url":"https://codeload.github.com/mgoltzsche/beets-autogenre/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgoltzsche%2Fbeets-autogenre/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266242072,"owners_count":23898102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beets","beets-plugin","genre","genre-classification","genre-suggestion","genres","python"],"created_at":"2024-11-07T15:11:50.227Z","updated_at":"2025-07-21T05:03:41.101Z","avatar_url":"https://github.com/mgoltzsche.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# beets-autogenre\n\nA [beets](https://github.com/beetbox/beets) plugin to assign genres to all items within your music library.\n\n## Features\n\n* Gets genres from last.fm using the [lastgenre plugin](https://beets.readthedocs.io/en/stable/plugins/lastgenre.html).\n* Favours track as last.fm genre source when track is a remix.\n* Fallback to estimating the genre using the [xtractor plugin](https://github.com/adamjakab/BeetsPluginXtractor) / [Essentia](https://essentia.upf.edu/).\n* Fixes the genre of (re)mixes by matching the genre tree against the track and album title.\n* Allows to specify the genre per item manually.\n\n## Dependencies\n\nThe following beets plugins and their dependencies must be installed:\n* [lastgenre plugin](https://beets.readthedocs.io/en/stable/plugins/lastgenre.html).\n* [xtractor plugin](https://github.com/adamjakab/BeetsPluginXtractor) which relies on [Essentia](https://essentia.upf.edu/).\n\n## Installation\n\n```sh\npython3 -m pip install beets-autogenre\n```\n\n## Configuration\n\nEnable the plugin and add a `autogenre` section to your beets `config.yaml` as follows:\n```yaml\nplugins:\n  - autogenre\n  - lastgenre\n  - xtractor\n\nautogenre:\n  pretend: false\n  all: false\n  force: false\n  lastgenre: true\n  xtractor: true\n  from_title: true\n  genre_rosamerica_strong: 0.8\n  genre_electronic_strong: 0.8\n  genre_electronic_prepend: 0.5\n  genre_electronic_append: 0.45\n\nlastgenre:\n  auto: false\n  prefer_specific: true\n  source: album\n  count: 4\n  min_weight: 15\n  canonical: /etc/beets/genre-tree.yaml\n  whitelist: /etc/beets/genres.txt\n\nxtractor:\n  auto: no\n  dry-run: no\n  write: yes\n  threads: 4\n  force: no\n  quiet: no\n  keep_output: no\n  keep_profiles: no\n  output_path: /tmp/xtractor\n  essentia_extractor: /usr/local/bin/essentia_streaming_extractor_music\n  high_level_targets:\n    genre_rosamerica_probability: # 0..1\n      path: \"highlevel.genre_rosamerica.probability\"\n      type: float\n    genre_electronic:\n      path: \"highlevel.genre_electronic.value\"\n      type: string\n    genre_electronic_probability: # 0..1\n      path: \"highlevel.genre_electronic.probability\"\n      type: float\n    timbre: # \"dark\" or \"bright\"\n      path: \"highlevel.timbre.value\"\n      type: string\n    tonal_atonal: # \"tonal\" or \"atonal\"\n      path: \"highlevel.tonal_atonal.value\"\n      type: string\n    key_edma: # e.g. \"C#\"\n      path: \"tonal.key_edma.key\"\n      type: string\n    key_edma_scale: # e.g. \"minor\"\n      path: \"tonal.key_edma.scale\"\n      type: string\n  extractor_profile:\n    highlevel:\n      svm_models:\n        - /var/lib/essentia/svm-models/beta5/danceability.history\n        - /var/lib/essentia/svm-models/beta5/gender.history\n        - /var/lib/essentia/svm-models/beta5/genre_rosamerica.history\n        - /var/lib/essentia/svm-models/beta5/genre_electronic.history\n        - /var/lib/essentia/svm-models/beta5/mood_acoustic.history\n        - /var/lib/essentia/svm-models/beta5/mood_aggressive.history\n        - /var/lib/essentia/svm-models/beta5/mood_electronic.history\n        - /var/lib/essentia/svm-models/beta5/mood_happy.history\n        - /var/lib/essentia/svm-models/beta5/mood_sad.history\n        - /var/lib/essentia/svm-models/beta5/mood_party.history\n        - /var/lib/essentia/svm-models/beta5/mood_relaxed.history\n        - /var/lib/essentia/svm-models/beta5/moods_mirex.history\n        - /var/lib/essentia/svm-models/beta5/voice_instrumental.history\n        - /var/lib/essentia/svm-models/beta5/tonal_atonal.history\n        - /var/lib/essentia/svm-models/beta5/timbre.history\n```\n\nFor more information, see [CLI](#cli).\n\n## Usage\n\nOnce the `autogenre` plugin is enabled within your beets configuration, you can detect and assign the genres for each track within your library as follows:\n```sh\nbeet autogenre\n```\n\n### CLI\n\n```\nUsage: beet autogenre [options]\n\nOptions:\n  -h, --help          show this help message and exit\n  --pretend           do not persist item changes but log them\n  -f, --force         reevaluate genres for items with a matching genre_source\n  -a, --all           overwrite genre if genre_source not specified\n  --no-all            do not overwrite genre from unspecified source\n  --lastgenre         use lastgenre plugin\n  --no-lastgenre      do not use lastgenre plugin\n  --xtractor          use xtractor plugin\n  --no-xtractor       do not use xtractor plugin\n  --from-title        derive genre from title\n  --no-from-title     do not derive genre from title\n  --parent-genres     add primary genre's parent genres\n  --no-parent-genres  do not add primary genre's parent genres\n  --genre=GENRE       specify the genre to assign to the selected items\n```\n\n## Development\n\nRun the unit tests (containerized):\n```sh\nmake test\n```\n\nRun the e2e tests (containerized):\n```sh\nmake test-e2e\n```\n\nTo test your plugin changes manually, you can run a shell within a beets docker container as follows:\n```sh\nmake beets-sh\n```\n\nA temporary beets library is written to `./data`.\nIt can be removed by calling `make clean-data`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgoltzsche%2Fbeets-autogenre","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmgoltzsche%2Fbeets-autogenre","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgoltzsche%2Fbeets-autogenre/lists"}