beets-beetmatch


Namebeets-beetmatch JSON
Version 0.3.2 PyPI version JSON
download
home_pageNone
Summarybeets plugin for generating playlists of songs that somehow match
upload_time2024-11-13 13:54:41
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT License Copyright (c) 2024 Andreas Bannach Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords beets
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            # beetmatch

A plugin for the [beets](https://beets.io) media library manager that tries to generate playlists from tracks that have
similar properties.

## Installation

The plugin can be installed via pip:

```bash
$ pip install beets-beetmatch
```

To activate the plugin add `beetmatch` to the lists of plugins in your beets config.yaml:

```yaml
plugins:
  - beetmatch
```

### Install Musly (optional)

The plugin supports music similarity computation using [libmusly](https://github.com/dominikschnitzer/musly).
In order to allow beetmatch to use this functionality, the [pymusly](https://github.com/andban/pymusly) package has to
be installed first.

### Helpful Plugins

This plugin works best when it has a set of track attributes that provide addition insight on the audio content of
individual tracks.

- [autobpm] computes the BPM of tracks
- [keyfinder] computes the musical scale of tracks
- [xtractor] uses Essentia to provide multiple properties that can be used for track similarity (BPM, scales,
  danceability, etc.)
- ... any plugin that does add one or more properties to the tracks in your library that can be used to determine
  musical similarity.

## Configuration

This plugin can be configured by providing options in the beets config.yaml under the `beetmatch` section:

- **auto**: automatically analyze imported tracks when musly is available
- **[jukeboxes](#jukebox)**: define jukeboxes that narrow tracks used for generating playlists from, e.g. songs
  within the same genre.
- **[playlist](#playlist)**: defines parameters used for playlist generation
- **[musly](#musly)**: change if and how musly is used for metadata generation

### jukebox

A jukebox is a sub-set of songs in your library, that can be used to create playlists from.
For example, you want to create playlists, which are only generated from songs in the 'electronic' genre.

A jukebox entry is made up of the following attributes:

- **name**: The name of the jukebox.
- **query**: a list of queries that specify which songs should go into the jukebox.

Example:

```yaml
    jukeboxes:
      - name: electronic
        query:
          - 'genre:electronic'
          - 'length:..30:00'
      - name: rock_and_pop
        query: 'genre:(rock|pop|country)'
```

### playlist

The playlist sections defines how playlists are generated.

- **default_script**: Define a default script to be call after a playlist was generated.
- **cooldown**: Define how many songs need to be selected before another song of the same artist or album can be added
  to a playlist.
- **selection**: Configure the track selection parameters.  
  With higher pickiness, the selection will stick to the best matches, for example a pickiness of 1.0 will select only
  the tracks with the highest similarity, while 0.0 will consider every track.
  The minimum pool size configures the minimum number of tracks to consider, even if that will mean to lower the
  pickiness.
  To always select only the tracks with the highest similarity, set pickiness and minimum_pool_size to 1.
- **attributes**: Configure which attributes of a song are used for similarity computation and how they should be
  measured and weighted. The available attribute types are described further [below](#attribute-types).

Example:

```yaml
    playlist:
      default_script: '~/.config/beets/scripts/music-create-playlist'
      cooldown:
        artist: 5
        album: 2

      selection:
        pickiness: 0.9
        minimum_pool_size: 10

      attributes:
        bpm:
          type: BpmDistance
          weight: 0.4
          config:
            tolerance: 0.04
        genre:
          type: ListDistance
          weight: 0.3
        year:
          type: YearDistance
          weight: 0.3
          config:
            max_diff: 5
```

### musly

When libmusly is installed, it's setup for track analysis can be configured in this section.

- **enabled**: Whether to enable track analysis.
- **threads**: Number of threads to use when analysing the library.
- **method**: The algorithm that musly should use for track analysis one of `timbre` or `mandelellis` (not tested).
- **data_dir**: Where to store musly jukebox information inside `BEETSDIR`

Example:

```yaml
  musly:
    threads: 2
    method: timbre
    data_dir: beetmatch
```

## Usage

### Update Musly state

In case you want to use libmusly for track similarity computations, you will need to analyze the tracks and update
musly jukeboxes first.
It is recommended to trigger an update whenever you added a lot of new songs to your library, or when you feel that the
results are somehow off.
You need to install the [pymusly](https://github.com/andban/pymusly) package to enable this command.

```bash
$ beet beetmatch-musly --write --update
```

```
Analyze tracks and update musly jukeboxes

Usage: beet beetmatch-musly

Options:
  -h, --help            show this help message and exit
  -u, --update          Update jukeboxes with new musly data
  -w, --write           Write analysis results to meta data database
  -f, --force           [default: False] force analysis of previously analyzed
                        items
  -t THREADS, --threads=THREADS
                        [default: 4] number of threads to use for analysis
```

### Generate Playlists

```bash
$ beet beetmatch-generate --jukebox=<jukebox_name> --tracks=30
```

```
Usage: beet beetmatch-generate
Example: beet beetmatch-generate --jukebox=all --duration 60 'artist:Air'

Options:
  -h, --help            show this help message and exit
  -j JUKEBOX_NAME, --jukebox=JUKEBOX_NAME
                        Name of the jukebox to generate playlist from
                        (required)
  -t NUMTRACKS, --num-tracks=NUMTRACKS
                        Maximum number of tracks to add to the playlist.
  -d DURATION, --duration=DURATION
                        Approximate duration of playlist in minutes.
  -s SCRIPT, --script=SCRIPT
                        Call script after playlist was generated.
                        This overrides the default_script defined in the configuration.
```

## Attribute Types

### Tonal

This measure considers tracks similar if they use scales that are next to each other in
the [circle of fifths](https://en.wikipedia.org/wiki/Circle_of_fifths).
For example a track that uses a C major scale is considered similar to songs that use F major, G major or A minor
scales.

This example uses the `key` and `key_scale` properties provided by the xtractor plugin:

```yaml
attributes:
  key:
    type: TonalDistance
    weight: 0.2
    config:
      key_scale: key_scale
```

When the scale attribute contains a combinded key/scale, like the attribute provided by the keyfinder plugin. No
additional config is needed.

### BPM

This measure considers tracks similar if their tempo is within a certain `tolerance`.

This example uses the `bpm` property with a 4% tolerance level:

```yaml
attributes:
  bpm:
    type: BpmDistance
    weight: 0.2
    config:
      tolerance: 0.04
```

### Year

This measure considers tracks similar if the year of release is within a certain timespan.

The example uses the `year` property with a maximum distance of 10 years:

```yaml
attributes:
  year:
    type: YearDistance
    weight: 0.1
    config:
      max_diff: 10
```

### Musly

This measure uses libmusly to calculate a similarity based on their timbral properties, i.e. tracks that have a similar
sound.

```yaml
attributes:
  musly_track:
    type: MuslyDistance
    weight: 0.25
```

### Numeric

This measure uses the difference of two numeric track properties as similarity measure. For example the danceability
property provided by the xtractor beets plugin.

```yaml
attributes:
  danceability:
    type: NumberDistance
    weight: 0.1
    config:
      min_value: 0
      max_value: 1
```

### Set

This measure uses the edit difference of two set properties as similarity, like the style or genre properties provided
by the Discogs beets plugin.

```yaml
attributes:
  genre:
    type: ListDistance
    weight: 0.1

```

## Docker Image

```bash
$ docker build -f docker/Dockerfile -t beetmatch .
$ docker run -it \
     -v "${PWD}/examples/docker:/var/lib/beets" \
     -v "<your music folder>:/var/lib/music:ro" \
     -e "BEETSDIR=/var/lib/beets" \
     -e "MUSIC_FOLDER_HOST=<your music folder>" \
     beetmatch:latest

beets@docker:/var/lib/beets$ beet import /var/lib/music
# this should take quite a while
beets@docker:/var/lib/beets$ beet bmm -u -w
beets@docker:/var/lib/beets$ beet bmg -j electronic -t 10
```

After all these commands are done, you should find a rock.m3u playlist in the examples/docker/playlist folder.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "beets-beetmatch",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "beets",
    "author": null,
    "author_email": "Andreas Bannach <andreas@borntohula.de>",
    "download_url": "https://files.pythonhosted.org/packages/20/ed/e13f6649b62c58b2513cf4ff9b8c5db9bc6759a0b62c2e435eaf99586abf/beets_beetmatch-0.3.2.tar.gz",
    "platform": "ALL",
    "description": "# beetmatch\n\nA plugin for the [beets](https://beets.io) media library manager that tries to generate playlists from tracks that have\nsimilar properties.\n\n## Installation\n\nThe plugin can be installed via pip:\n\n```bash\n$ pip install beets-beetmatch\n```\n\nTo activate the plugin add `beetmatch` to the lists of plugins in your beets config.yaml:\n\n```yaml\nplugins:\n  - beetmatch\n```\n\n### Install Musly (optional)\n\nThe plugin supports music similarity computation using [libmusly](https://github.com/dominikschnitzer/musly).\nIn order to allow beetmatch to use this functionality, the [pymusly](https://github.com/andban/pymusly) package has to\nbe installed first.\n\n### Helpful Plugins\n\nThis plugin works best when it has a set of track attributes that provide addition insight on the audio content of\nindividual tracks.\n\n- [autobpm] computes the BPM of tracks\n- [keyfinder] computes the musical scale of tracks\n- [xtractor] uses Essentia to provide multiple properties that can be used for track similarity (BPM, scales,\n  danceability, etc.)\n- ... any plugin that does add one or more properties to the tracks in your library that can be used to determine\n  musical similarity.\n\n## Configuration\n\nThis plugin can be configured by providing options in the beets config.yaml under the `beetmatch` section:\n\n- **auto**: automatically analyze imported tracks when musly is available\n- **[jukeboxes](#jukebox)**: define jukeboxes that narrow tracks used for generating playlists from, e.g. songs\n  within the same genre.\n- **[playlist](#playlist)**: defines parameters used for playlist generation\n- **[musly](#musly)**: change if and how musly is used for metadata generation\n\n### jukebox\n\nA jukebox is a sub-set of songs in your library, that can be used to create playlists from.\nFor example, you want to create playlists, which are only generated from songs in the 'electronic' genre.\n\nA jukebox entry is made up of the following attributes:\n\n- **name**: The name of the jukebox.\n- **query**: a list of queries that specify which songs should go into the jukebox.\n\nExample:\n\n```yaml\n    jukeboxes:\n      - name: electronic\n        query:\n          - 'genre:electronic'\n          - 'length:..30:00'\n      - name: rock_and_pop\n        query: 'genre:(rock|pop|country)'\n```\n\n### playlist\n\nThe playlist sections defines how playlists are generated.\n\n- **default_script**: Define a default script to be call after a playlist was generated.\n- **cooldown**: Define how many songs need to be selected before another song of the same artist or album can be added\n  to a playlist.\n- **selection**: Configure the track selection parameters.  \n  With higher pickiness, the selection will stick to the best matches, for example a pickiness of 1.0 will select only\n  the tracks with the highest similarity, while 0.0 will consider every track.\n  The minimum pool size configures the minimum number of tracks to consider, even if that will mean to lower the\n  pickiness.\n  To always select only the tracks with the highest similarity, set pickiness and minimum_pool_size to 1.\n- **attributes**: Configure which attributes of a song are used for similarity computation and how they should be\n  measured and weighted. The available attribute types are described further [below](#attribute-types).\n\nExample:\n\n```yaml\n    playlist:\n      default_script: '~/.config/beets/scripts/music-create-playlist'\n      cooldown:\n        artist: 5\n        album: 2\n\n      selection:\n        pickiness: 0.9\n        minimum_pool_size: 10\n\n      attributes:\n        bpm:\n          type: BpmDistance\n          weight: 0.4\n          config:\n            tolerance: 0.04\n        genre:\n          type: ListDistance\n          weight: 0.3\n        year:\n          type: YearDistance\n          weight: 0.3\n          config:\n            max_diff: 5\n```\n\n### musly\n\nWhen libmusly is installed, it's setup for track analysis can be configured in this section.\n\n- **enabled**: Whether to enable track analysis.\n- **threads**: Number of threads to use when analysing the library.\n- **method**: The algorithm that musly should use for track analysis one of `timbre` or `mandelellis` (not tested).\n- **data_dir**: Where to store musly jukebox information inside `BEETSDIR`\n\nExample:\n\n```yaml\n  musly:\n    threads: 2\n    method: timbre\n    data_dir: beetmatch\n```\n\n## Usage\n\n### Update Musly state\n\nIn case you want to use libmusly for track similarity computations, you will need to analyze the tracks and update\nmusly jukeboxes first.\nIt is recommended to trigger an update whenever you added a lot of new songs to your library, or when you feel that the\nresults are somehow off.\nYou need to install the [pymusly](https://github.com/andban/pymusly) package to enable this command.\n\n```bash\n$ beet beetmatch-musly --write --update\n```\n\n```\nAnalyze tracks and update musly jukeboxes\n\nUsage: beet beetmatch-musly\n\nOptions:\n  -h, --help            show this help message and exit\n  -u, --update          Update jukeboxes with new musly data\n  -w, --write           Write analysis results to meta data database\n  -f, --force           [default: False] force analysis of previously analyzed\n                        items\n  -t THREADS, --threads=THREADS\n                        [default: 4] number of threads to use for analysis\n```\n\n### Generate Playlists\n\n```bash\n$ beet beetmatch-generate --jukebox=<jukebox_name> --tracks=30\n```\n\n```\nUsage: beet beetmatch-generate\nExample: beet beetmatch-generate --jukebox=all --duration 60 'artist:Air'\n\nOptions:\n  -h, --help            show this help message and exit\n  -j JUKEBOX_NAME, --jukebox=JUKEBOX_NAME\n                        Name of the jukebox to generate playlist from\n                        (required)\n  -t NUMTRACKS, --num-tracks=NUMTRACKS\n                        Maximum number of tracks to add to the playlist.\n  -d DURATION, --duration=DURATION\n                        Approximate duration of playlist in minutes.\n  -s SCRIPT, --script=SCRIPT\n                        Call script after playlist was generated.\n                        This overrides the default_script defined in the configuration.\n```\n\n## Attribute Types\n\n### Tonal\n\nThis measure considers tracks similar if they use scales that are next to each other in\nthe [circle of fifths](https://en.wikipedia.org/wiki/Circle_of_fifths).\nFor example a track that uses a C major scale is considered similar to songs that use F major, G major or A minor\nscales.\n\nThis example uses the `key` and `key_scale` properties provided by the xtractor plugin:\n\n```yaml\nattributes:\n  key:\n    type: TonalDistance\n    weight: 0.2\n    config:\n      key_scale: key_scale\n```\n\nWhen the scale attribute contains a combinded key/scale, like the attribute provided by the keyfinder plugin. No\nadditional config is needed.\n\n### BPM\n\nThis measure considers tracks similar if their tempo is within a certain `tolerance`.\n\nThis example uses the `bpm` property with a 4% tolerance level:\n\n```yaml\nattributes:\n  bpm:\n    type: BpmDistance\n    weight: 0.2\n    config:\n      tolerance: 0.04\n```\n\n### Year\n\nThis measure considers tracks similar if the year of release is within a certain timespan.\n\nThe example uses the `year` property with a maximum distance of 10 years:\n\n```yaml\nattributes:\n  year:\n    type: YearDistance\n    weight: 0.1\n    config:\n      max_diff: 10\n```\n\n### Musly\n\nThis measure uses libmusly to calculate a similarity based on their timbral properties, i.e. tracks that have a similar\nsound.\n\n```yaml\nattributes:\n  musly_track:\n    type: MuslyDistance\n    weight: 0.25\n```\n\n### Numeric\n\nThis measure uses the difference of two numeric track properties as similarity measure. For example the danceability\nproperty provided by the xtractor beets plugin.\n\n```yaml\nattributes:\n  danceability:\n    type: NumberDistance\n    weight: 0.1\n    config:\n      min_value: 0\n      max_value: 1\n```\n\n### Set\n\nThis measure uses the edit difference of two set properties as similarity, like the style or genre properties provided\nby the Discogs beets plugin.\n\n```yaml\nattributes:\n  genre:\n    type: ListDistance\n    weight: 0.1\n\n```\n\n## Docker Image\n\n```bash\n$ docker build -f docker/Dockerfile -t beetmatch .\n$ docker run -it \\\n     -v \"${PWD}/examples/docker:/var/lib/beets\" \\\n     -v \"<your music folder>:/var/lib/music:ro\" \\\n     -e \"BEETSDIR=/var/lib/beets\" \\\n     -e \"MUSIC_FOLDER_HOST=<your music folder>\" \\\n     beetmatch:latest\n\nbeets@docker:/var/lib/beets$ beet import /var/lib/music\n# this should take quite a while\nbeets@docker:/var/lib/beets$ beet bmm -u -w\nbeets@docker:/var/lib/beets$ beet bmg -j electronic -t 10\n```\n\nAfter all these commands are done, you should find a rock.m3u playlist in the examples/docker/playlist folder.\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2024 Andreas Bannach  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
    "summary": "beets plugin for generating playlists of songs that somehow match",
    "version": "0.3.2",
    "project_urls": {
        "Issues": "https://github.com/andban/beets-beetmatch/issues",
        "Repository": "https://github.com/andban/beets-beetmatch.git"
    },
    "split_keywords": [
        "beets"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "375d3f6d8a2e7c62681fb23251a65c28870a56606e46d3a3564c4277496ecdfd",
                "md5": "2f308565586f232811ad8f9cd675e34f",
                "sha256": "9d9af99fae566d0611f21d17ceabc3a750f8a4b0abc70800e8ecf062eb8c6ae8"
            },
            "downloads": -1,
            "filename": "beets_beetmatch-0.3.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2f308565586f232811ad8f9cd675e34f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 29261,
            "upload_time": "2024-11-13T13:54:40",
            "upload_time_iso_8601": "2024-11-13T13:54:40.041995Z",
            "url": "https://files.pythonhosted.org/packages/37/5d/3f6d8a2e7c62681fb23251a65c28870a56606e46d3a3564c4277496ecdfd/beets_beetmatch-0.3.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "20ede13f6649b62c58b2513cf4ff9b8c5db9bc6759a0b62c2e435eaf99586abf",
                "md5": "cbaacc0293005a7e55bf3f627c3b6168",
                "sha256": "0afdca632b0bd242049e8f7ee6036c16b5a1c9ca72a14b34a8f0b37200666f85"
            },
            "downloads": -1,
            "filename": "beets_beetmatch-0.3.2.tar.gz",
            "has_sig": false,
            "md5_digest": "cbaacc0293005a7e55bf3f627c3b6168",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 20641,
            "upload_time": "2024-11-13T13:54:41",
            "upload_time_iso_8601": "2024-11-13T13:54:41.640713Z",
            "url": "https://files.pythonhosted.org/packages/20/ed/e13f6649b62c58b2513cf4ff9b8c5db9bc6759a0b62c2e435eaf99586abf/beets_beetmatch-0.3.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-13 13:54:41",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "andban",
    "github_project": "beets-beetmatch",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "beets-beetmatch"
}
        
Elapsed time: 0.56734s