Custom Tag Playlists¶
Create automatic YouTube Music playlists based on Last.fm tags and genres. You can define multiple tag-based playlists that fill themselves with matching tracks from your scrobble history.
For example, define a "Breakcore Mix" playlist that only includes tracks tagged breakcore or drill and bass on Last.fm, or a "Chill Electronic" playlist that requires both electronic and ambient tags.
How Tags Are Resolved¶
The tag system follows the same cache-first approach as the main sync:
- Tag overrides - check
config/tag_overrides.json(user manual fixes). If the override mode is"replace", the override tags are used directly and steps 2-3 are skipped. - Tag cache - check
cache/.tag_cache.json(90-day TTL, configurable viaTAG_CACHE_TTL_DAYS) - Last.fm API - fetch via
track.getTopTags, falling back toartist.getTopTagsif track-level tags are unavailable
After fetching, "add" mode tag overrides are merged into the result (this allows supplementing Last.fm's tags without replacing them entirely).
Tags with fewer votes than TAG_MIN_COUNT (default: 10) are filtered out to avoid noise.
If backfilling is enabled and a playlist has not reached its target track count after filtering, the tool automatically fetches more scrobbles and repeats until the limit is met or no more data is available.
Configuration¶
Docker: Use the web dashboard to create and manage tag playlists. Tag sync can be triggered manually from the UI, or automatically after each scheduled main sync via AUTO_TAG_SYNC_ENABLED and AUTO_TAG_SYNC_FREQUENCY (see Configuration).
CLI: Edit config/custom_playlists.json directly:
1. Create the config file¶
2. Define your playlists¶
{
"playlists": [
{
"name": "Breakcore Mix (auto)",
"tags": ["breakcore", "drill and bass"],
"match": "any",
"limit": 50,
"backfill": true,
"blacklist": []
},
{
"name": "Ambient Electronic (auto)",
"tags": ["ambient", "electronic"],
"match": "all",
"limit": 30,
"backfill": true,
"blacklist": ["artist name|unwanted track"]
}
]
}
| Field | Description |
|---|---|
name |
Playlist name on YouTube Music |
description |
Optional playlist description |
tags |
Last.fm tags to match against |
match |
"any" (track has at least one tag) or "all" (track has every tag) |
limit |
Target number of tracks |
backfill |
Fetch more scrobbles if filtering doesn't reach the limit |
blacklist |
Per-playlist exclusions as "artist\|title" (lowercase) |
Environment Variables¶
| Variable | Default | Description |
|---|---|---|
CUSTOM_PLAYLISTS_FILE |
config/custom_playlists.json |
Path to playlist definitions |
TAG_CACHE_TTL_DAYS |
90 |
Days before cached tags expire |
TAG_MIN_COUNT |
10 |
Minimum Last.fm tag count threshold |
TAG_SLEEP_BETWEEN |
0.25 |
Seconds between tag API calls |
CUSTOM_PLAYLISTS_PRIVACY |
(main setting) | Privacy for tag playlists (PUBLIC / PRIVATE) |
BACKFILL_PASSES |
3 |
Maximum backfill iterations |
Tag Overrides¶
When Last.fm's tag data is wrong or incomplete, you can manually fix it.
Docker: Use the web dashboard's tag management interface.
CLI: Edit config/tag_overrides.json directly:
1. Create the overrides file¶
2. Add your override¶
{
"_overrides": {
"artist name|song title": {
"artist": "Artist Name",
"title": "Song Title",
"tags": ["breakcore", "electronic"],
"mode": "add",
"reason": "Last.fm only has 'electronic', adding 'breakcore'"
}
}
}
| Field | Description |
|---|---|
| Key | artist\|title in lowercase |
tags |
List of tag names to apply |
mode |
"add" merges with existing Last.fm tags, "replace" overwrites them entirely |
reason |
Optional note for your reference |
Running Tag Sync¶
Tag playlists are synced separately from the main playlist. Use the dedicated entry point:
Warning
python run.py only runs the main playlist sync. Tag playlists must be triggered separately via run_tags.py or from the web dashboard.