Search and download music from YouTube Music with lyrics
Project description
Kikusan
Search and download music from YouTube Music with lyrics.
Features
- Search & Download: Search YouTube Music and download audio in OPUS/MP3/FLAC format
- Playlist Support: Download entire playlists from YouTube Music, YouTube, and Spotify
- Quick Download: Search and download first match with a single command
- Automatic Lyrics: Fetch and embed synchronized lyrics from lrclib.net (LRC format)
- Web Interface: Modern web UI with search, download, theme toggle, and format selection
- Docker Support: Easy deployment with Docker and docker-compose
- Plugin System: Extensible architecture for custom music sources
- Scheduled Sync: Automated playlist monitoring with cron scheduling
- M3U Playlists: Automatic playlist file generation for downloads
Plugin System
Kikusan supports plugins for syncing music from various sources beyond standard playlists:
Built-in Plugins:
-
listenbrainz- Weekly recommendations from listenbrainz.org- Required:
user(listenbrainz username) - Optional:
recommendation_type(weekly-exploration, weekly-jams)
- Required:
-
rss- Generic RSS/Atom feed parser for music podcasts, blogs, etc.- Required:
url(RSS/Atom feed URL) - Optional:
artist_field,title_field,timeout,user_agent
- Required:
-
reddit- Fetch songs from music subreddits (r/listentothis, r/Music, r/IndieHeads, etc.)- Required:
subreddit(subreddit name) - Optional:
sort(hot/new/top/rising),time_filter,limit,min_score
- Required:
-
billboard- Fetch songs from Billboard charts (hot-100, pop-songs, etc.)- Required:
chart_name(e.g., 'hot-100', 'pop-songs') - Optional:
date(YYYY-MM-DD),year(for year-end charts),limit
- Required:
Usage:
# List available plugins
kikusan plugins list
# Run a plugin once
kikusan plugins run listenbrainz --config '{"user": "myuser"}'
kikusan plugins run reddit --config '{"subreddit": "listentothis", "limit": 25}'
kikusan plugins run billboard --config '{"chart_name": "hot-100", "limit": 50}'
# Schedule in cron.yaml
# See cron.example.yaml for configuration examples
Creating Third-Party Plugins:
See examples/third-party-plugin/ for a complete example of creating your own plugin. Plugins are distributed as Python packages and automatically discovered via entry points.
Installation
uv sync
Usage
CLI
# Search for music
kikusan search "Bohemian Rhapsody"
# Download by video ID
kikusan download bSnlKl_PoQU
# Download by URL
kikusan download --url "https://music.youtube.com/watch?v=bSnlKl_PoQU"
# Search and download first match
kikusan download --query "Bohemian Rhapsody Queen"
# Download entire playlist (YouTube Music, YouTube, or Spotify)
kikusan download --url "https://music.youtube.com/playlist?list=..."
kikusan download --url "https://open.spotify.com/playlist/..."
# Custom filename format
kikusan download bSnlKl_PoQU --filename "%(title)s"
# Options
kikusan download bSnlKl_PoQU --output ~/Music --format mp3
Web Interface
kikusan web
# Open http://localhost:8000
Features:
- Search YouTube Music with real-time results
- Download individual tracks with format selection (OPUS/MP3/FLAC)
- Dark/light theme toggle with automatic system preference detection
- View counts displayed for each track
- Responsive design for mobile and desktop
Scheduled Sync (Cron)
Automatically monitor and sync playlists or plugins on a schedule:
# Run continuously with cron.yaml configuration
kikusan cron
# Run all syncs once and exit
kikusan cron --once
# Use custom config file
kikusan cron --config /path/to/cron.yaml
Create a cron.yaml file to configure:
- Playlists: YouTube Music, YouTube, or Spotify playlists
- Plugins: Listenbrainz, Reddit, Billboard, RSS feeds
- Schedule: Standard cron expressions (e.g., "0 9 * * *" for daily at 9am)
- Sync Mode: Keep or delete files when removed from source
See cron.example.yaml for detailed configuration examples.
Notifications
Kikusan can send push notifications via Gotify for scheduled sync operations:
- Summary notifications only - One notification per sync operation, not per track
- Includes download/skip/fail counts - See results at a glance
- Optional - Gracefully disabled if not configured
- Non-blocking - Notification failures don't stop downloads
Setup:
- Install a Gotify server or use an existing instance
- Create an application token in Gotify
- Set environment variables:
export GOTIFY_URL="https://push.example.com" export GOTIFY_TOKEN="your-app-token"
Notifications are sent for:
- Scheduled playlist syncs (via
kikusan cron) - Scheduled plugin syncs (via
kikusan cron)
Notifications are not sent for CLI operations or web UI downloads, as these are interactive and the user already sees the results.
Docker
docker compose up -d
# Open http://localhost:8000
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
KIKUSAN_DOWNLOAD_DIR |
./downloads |
Download directory |
KIKUSAN_AUDIO_FORMAT |
opus |
Audio format (opus, mp3, flac) |
KIKUSAN_FILENAME_TEMPLATE |
%(artist,uploader)s - %(title)s |
Filename template (yt-dlp format) |
KIKUSAN_WEB_PORT |
8000 |
Web server port |
KIKUSAN_WEB_PLAYLIST |
None |
M3U playlist name for web downloads (optional) |
GOTIFY_URL |
None |
Gotify server URL for notifications (optional) |
GOTIFY_TOKEN |
None |
Gotify application token (optional) |
State Files & Playlists
Kikusan tracks downloaded files and generates M3U playlists automatically:
- State Files: Stored in
{download_dir}/.kikusan/state/(for playlists) and{download_dir}/.kikusan/plugin_state/(for plugins) - M3U Playlists: Generated at
{download_dir}/{name}.m3ufor each sync configuration
Requirements
- Python 3.12+
- ffmpeg (for audio processing)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kikusan-0.8.0.tar.gz.
File metadata
- Download URL: kikusan-0.8.0.tar.gz
- Upload date:
- Size: 107.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e8bfc137960ae07e948327ed7f48105e4ad700c18e324344dab3dbd87377593
|
|
| MD5 |
f9afedbdd0354da68324b63225d05435
|
|
| BLAKE2b-256 |
58270701f85a94883e4755c5286812424c1915aebc5f8331e0e851b75d66c005
|
Provenance
The following attestation bundles were made for kikusan-0.8.0.tar.gz:
Publisher:
publish.yml on dadav/kikusan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kikusan-0.8.0.tar.gz -
Subject digest:
6e8bfc137960ae07e948327ed7f48105e4ad700c18e324344dab3dbd87377593 - Sigstore transparency entry: 843351163
- Sigstore integration time:
-
Permalink:
dadav/kikusan@35bc80b7a834412be15a6760906dc230edc8ac1c -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/dadav
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@35bc80b7a834412be15a6760906dc230edc8ac1c -
Trigger Event:
push
-
Statement type:
File details
Details for the file kikusan-0.8.0-py3-none-any.whl.
File metadata
- Download URL: kikusan-0.8.0-py3-none-any.whl
- Upload date:
- Size: 51.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16d64645e4995a140e60d64652a3cf9063f56049e69d9bff9161df52d937fa35
|
|
| MD5 |
5b1ea171bda29c508be0dad6faf8f034
|
|
| BLAKE2b-256 |
52f619d060ee91aaf70cac216750f9bd96d8f4905dfb5b73d3a06a5bc3328062
|
Provenance
The following attestation bundles were made for kikusan-0.8.0-py3-none-any.whl:
Publisher:
publish.yml on dadav/kikusan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kikusan-0.8.0-py3-none-any.whl -
Subject digest:
16d64645e4995a140e60d64652a3cf9063f56049e69d9bff9161df52d937fa35 - Sigstore transparency entry: 843351171
- Sigstore integration time:
-
Permalink:
dadav/kikusan@35bc80b7a834412be15a6760906dc230edc8ac1c -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/dadav
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@35bc80b7a834412be15a6760906dc230edc8ac1c -
Trigger Event:
push
-
Statement type: