mirror of
https://github.com/beetbox/beets.git
synced 2025-12-15 21:14:19 +01:00
*All* URLs were checked manually, but only once per domain! I mostly concerned myself with URLs in documentation rather than source code because the latter may or may not have impactful changes, while the former should be straight forward. Changes in addition to simply adding an s: - changed pip and pypi references as their location has changed - MPoD (iOS app) url redirects to Regelian, so I replaced those - updated homebrew references Notable observations: - beets.io does have HTTPS set up properly (via gh-pages) - beatport.py uses the old HTTP url for beatport - as does lyrics.py for lyrics.wikia.com - https://tomahawk-player.org/ expired long ago, but the http page redirects to https regardless - none of the sourceforge subdomains have https (in 2019!)
165 lines
6.5 KiB
ReStructuredText
165 lines
6.5 KiB
ReStructuredText
LastGenre Plugin
|
|
================
|
|
|
|
The MusicBrainz database `does not contain genre information`_. Therefore, when
|
|
importing and autotagging music, beets does not assign a genre. The
|
|
``lastgenre`` plugin fetches *tags* from `Last.fm`_ and assigns them as genres
|
|
to your albums and items.
|
|
|
|
.. _does not contain genre information:
|
|
https://musicbrainz.org/doc/General_FAQ#Why_does_MusicBrainz_not_support_genre_information.3F
|
|
.. _Last.fm: https://last.fm/
|
|
|
|
Installation
|
|
------------
|
|
|
|
The plugin requires `pylast`_, which you can install using `pip`_ by typing::
|
|
|
|
pip install pylast
|
|
|
|
After you have pylast installed, enable the ``lastgenre`` plugin in your
|
|
configuration (see :ref:`using-plugins`).
|
|
|
|
Usage
|
|
-----
|
|
|
|
The plugin chooses genres based on a *whitelist*, meaning that only certain
|
|
tags can be considered genres. This way, tags like "my favorite music" or "seen
|
|
live" won't be considered genres. The plugin ships with a fairly extensive
|
|
`internal whitelist`_, but you can set your own in the config file using the
|
|
``whitelist`` configuration value or forgo a whitelist altogether by setting
|
|
the option to `false`.
|
|
|
|
The genre list file should contain one genre per line. Blank lines are ignored.
|
|
For the curious, the default genre list is generated by a `script that scrapes
|
|
Wikipedia`_.
|
|
|
|
.. _pip: https://pip.pypa.io
|
|
.. _pylast: https://github.com/pylast/pylast
|
|
.. _script that scrapes Wikipedia: https://gist.github.com/1241307
|
|
.. _internal whitelist: https://raw.githubusercontent.com/beetbox/beets/master/beetsplug/lastgenre/genres.txt
|
|
|
|
Canonicalization
|
|
^^^^^^^^^^^^^^^^
|
|
|
|
The plugin can also *canonicalize* genres, meaning that more obscure genres can
|
|
be turned into coarser-grained ones that are present in the whitelist. This
|
|
works using a `tree of nested genre names`_, represented using `YAML`_, where the
|
|
leaves of the tree represent the most specific genres.
|
|
|
|
The most common way to use this would be with a custom whitelist containing only
|
|
a desired subset of genres. Consider for a example this minimal whitelist::
|
|
|
|
rock
|
|
heavy metal
|
|
pop
|
|
|
|
together with the default genre tree. Then an item that has its genre specified
|
|
as *viking metal* would actually be tagged as *heavy metal* because neither
|
|
*viking metal* nor its parent *black metal* are in the whitelist. It always
|
|
tries to use the most specific genre that's available in the whitelist.
|
|
|
|
The relevant subtree path in the default tree looks like this::
|
|
|
|
- rock:
|
|
- heavy metal:
|
|
- black metal:
|
|
- viking metal
|
|
|
|
Considering that, it's not very useful to use the default whitelist (which
|
|
contains about any genre contained in the tree) with canonicalization because
|
|
nothing would ever be matched to a more generic node since all the specific
|
|
subgenres are in the whitelist to begin with.
|
|
|
|
|
|
.. _YAML: https://www.yaml.org/
|
|
.. _tree of nested genre names: https://raw.githubusercontent.com/beetbox/beets/master/beetsplug/lastgenre/genres-tree.yaml
|
|
|
|
|
|
Genre Source
|
|
^^^^^^^^^^^^
|
|
|
|
When looking up genres for albums or individual tracks, you can choose whether
|
|
to use Last.fm tags on the album, the artist, or the track. For example, you
|
|
might want all the albums for a certain artist to carry the same genre.
|
|
The default is "album". When set to "track", the plugin will fetch *both*
|
|
album-level and track-level genres for your music when importing albums.
|
|
|
|
|
|
Multiple Genres
|
|
^^^^^^^^^^^^^^^
|
|
|
|
By default, the plugin chooses the most popular tag on Last.fm as a genre. If
|
|
you prefer to use a *list* of popular genre tags, you can increase the number
|
|
of the ``count`` config option.
|
|
|
|
Lists of up to *count* genres will then be used instead of single genres. The
|
|
genres are separated by commas by default, but you can change this with the
|
|
``separator`` config option.
|
|
|
|
`Last.fm`_ provides a popularity factor, a.k.a. *weight*, for each tag ranging
|
|
from 100 for the most popular tag down to 0 for the least popular.
|
|
The plugin uses this weight to discard unpopular tags. The default is to
|
|
ignore tags with a weight less then 10. You can change this by setting
|
|
the ``min_weight`` config option.
|
|
|
|
Specific vs. Popular Genres
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
By default, the plugin sorts genres by popularity. However, you can use the
|
|
``prefer_specific`` option to override this behavior and instead sort genres
|
|
by specificity, as determined by your whitelist and canonicalization tree.
|
|
|
|
For instance, say you have both ``folk`` and ``americana`` in your whitelist
|
|
and canonicalization tree and ``americana`` is a leaf within ``folk``. If
|
|
Last.fm returns both of those tags, lastgenre is going to use the most
|
|
popular, which is often the most generic (in this case ``folk``). By setting
|
|
``prefer_specific`` to true, lastgenre would use ``americana`` instead.
|
|
|
|
Configuration
|
|
-------------
|
|
|
|
To configure the plugin, make a ``lastgenre:`` section in your
|
|
configuration file. The available options are:
|
|
|
|
- **auto**: Fetch genres automatically during import.
|
|
Default: ``yes``.
|
|
- **canonical**: Use a canonicalization tree. Setting this to ``yes`` will use
|
|
a built-in tree. You can also set it to a path, like the ``whitelist``
|
|
config value, to use your own tree.
|
|
Default: ``no`` (disabled).
|
|
- **count**: Number of genres to fetch.
|
|
Default: 1
|
|
- **fallback**: A string if to use a fallback genre when no genre is found.
|
|
You can use the empty string ``''`` to reset the genre.
|
|
Default: None.
|
|
- **force**: By default, beets will always fetch new genres, even if the files
|
|
already have one. To instead leave genres in place in when they pass the
|
|
whitelist, set the ``force`` option to ``no``.
|
|
Default: ``yes``.
|
|
- **min_weight**: Minimum popularity factor below which genres are discarded.
|
|
Default: 10.
|
|
- **prefer_specific**: Sort genres by the most to least specific, rather than
|
|
most to least popular. Default: ``no``.
|
|
- **source**: Which entity to look up in Last.fm. Can be
|
|
either ``artist``, ``album`` or ``track``.
|
|
Default: ``album``.
|
|
- **separator**: A separator for multiple genres.
|
|
Default: ``', '``.
|
|
- **whitelist**: The filename of a custom genre list, ``yes`` to use
|
|
the internal whitelist, or ``no`` to consider all genres valid.
|
|
Default: ``yes``.
|
|
|
|
Running Manually
|
|
----------------
|
|
|
|
In addition to running automatically on import, the plugin can also be run manually
|
|
from the command line. Use the command ``beet lastgenre [QUERY]`` to fetch
|
|
genres for albums or items matching a certain query.
|
|
|
|
By default, ``beet lastgenre`` matches albums. To match
|
|
individual tracks or singletons, use the ``-A`` switch:
|
|
``beet lastgenre -A [QUERY]``.
|
|
|
|
To disable automatic genre fetching on import, set the ``auto`` config option
|
|
to false.
|