{"id":51239711,"url":"https://github.com/skvggor/klangbild","last_synced_at":"2026-06-28T23:30:51.680Z","repository":{"id":341881391,"uuid":"1162577575","full_name":"skvggor/klangbild","owner":"skvggor","description":"Generate a 4K audio visualizer video (MP4) and a matching cover image (JPG) from any MP3 file.","archived":false,"fork":false,"pushed_at":"2026-03-26T20:46:19.000Z","size":29783,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-27T08:32:12.632Z","etag":null,"topics":["4k","audio","audio-visualizer","ffmpeg","linux","mp3","music","python","visualizer","youtube"],"latest_commit_sha":null,"homepage":"https://klangbild.skvggor.dev","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skvggor.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-20T12:42:14.000Z","updated_at":"2026-03-26T20:46:23.000Z","dependencies_parsed_at":"2026-03-26T22:04:02.222Z","dependency_job_id":null,"html_url":"https://github.com/skvggor/klangbild","commit_stats":null,"previous_names":["skvggor/klangbild"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/skvggor/klangbild","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skvggor%2Fklangbild","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skvggor%2Fklangbild/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skvggor%2Fklangbild/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skvggor%2Fklangbild/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skvggor","download_url":"https://codeload.github.com/skvggor/klangbild/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skvggor%2Fklangbild/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34907985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["4k","audio","audio-visualizer","ffmpeg","linux","mp3","music","python","visualizer","youtube"],"created_at":"2026-06-28T23:30:50.993Z","updated_at":"2026-06-28T23:30:51.675Z","avatar_url":"https://github.com/skvggor.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/icon.svg\" alt=\"klangbild icon\" width=\"120\" height=\"120\"/\u003e\u003cbr/\u003e\n  \u003ch1 align=\"center\"\u003eklangbild\u003c/h1\u003e\n\u003c/p\u003e\n\nGenerate a **4K audio visualizer video** (MP4) and a matching **cover image** (JPG) from any MP3 file.\n\nA **Linux-only command-line tool** written in Python.\n\n---\n\n\u003cimg height=\"50\" src=\"assets/star.svg\" alt=\"klangbild preview\" /\u003e\n\n---\n\n## Demos\n\n[Watch on YouTube](https://www.youtube.com/watch?v=zSJnd_S_jVk\u0026list=PLHu9uHPNFQRA6BXrLtX8D1RPYmmZm1wZ4)\n\n---\n\n## Features\n\n- Multiple layout options: classic, spotlight, split-left, split-right\n- Two waveform styles: mirrored lines or radial/circular\n- Background image rendered as-is, without any darkening overlay\n- Song title, artist, album, and a seek bar positioned according to layout\n- Staggered fade-in / fade-out (background → wave → UI)\n- Infinite-wave edge fade effect (line style)\n- GPU encoding via NVENC or VAAPI (optional)\n- Parallel CPU frame rendering piped directly to FFmpeg (no temp files)\n- Batch mode: process an entire folder of MP3s at once\n\n---\n\n## Examples\n\n### Covers\n\n![Cover](assets/cover_main.jpg)\n\n*SKVGGOR — \"Мемориал Героям-панфиловцам\"*\n\n---\n\n### Layouts\n\n| Layout | Line Wave | Circular Wave |\n|--------|:---------:|:-------------:|\n| **Classic** | ![classic line](assets/classic_line_warm.jpg) | ![classic circular](assets/classic_circular_warm.jpg) |\n| **Spotlight** | ![spotlight line](assets/spotlight_line_neutral.jpg) | ![spotlight circular](assets/spotlight_circular_neutral.jpg) |\n| **Split Left** | ![split-left line](assets/split-left_line_contrast.jpg) | ![split-left circular](assets/split-left_circular_contrast.jpg) |\n| **Split Right** | ![split-right line](assets/split-right_line_warm.jpg) | ![split-right circular](assets/split-right_circular_warm.jpg) |\n\n---\n\n### Film Grain\n\n| Low (0.08) | Medium (0.15) | High (0.25) |\n|:----------:|:-------------:|:-----------:|\n| ![grain low](assets/grain_low.jpg) | ![grain medium](assets/grain_medium.jpg) | ![grain high](assets/grain_high.jpg) |\n\n---\n\n## Requirements\n\n- Python ≥ 3.11\n- [uv](https://github.com/astral-sh/uv) (package manager)\n- FFmpeg ≥ 5 (must be in `$PATH`)\n- For NVIDIA GPU encoding: NVENC-capable driver\n- For Intel/AMD GPU encoding: Mesa VA-API\n\n---\n\n## Installation\n\n```bash\ngit clone https://github.com/skvggor/klangbild.git\ncd klangbild\nuv sync\n```\n\n---\n\n## Development\n\n```bash\n# Install dev dependencies\nuv sync --group dev\n\n# Set up pre-commit hooks (pre-commit and pre-push)\nuv run pre-commit install\nuv run pre-commit install --hook-type pre-push\n\n# Run all checks manually\nuv run pre-commit run --all-files\n```\n\n### Git Hooks\n\n- **Commit**: ruff (lint + format)\n- **Push**: mypy + pytest\n\n### CI\n\nTests run automatically on PRs to `main` via GitHub Actions.\n\n---\n\n## Usage\n\n### Basic\n\n```bash\nuv run klangbild \\\n    --audio \"song.mp3\" \\\n    --background \"cover.jpg\" \\\n    --title \"Song Title\" \\\n    --artist \"Artist Name\" \\\n    --album \"Album Name\" \\\n    --output \"visualizer.mp4\"\n```\n\n### With Custom Font\n\n```bash\nuv run klangbild \\\n    --audio \"song.mp3\" \\\n    --background \"cover.jpg\" \\\n    --title \"Song Title\" \\\n    --artist \"Artist Name\" \\\n    --album \"Album Name\" \\\n    --font \"Montserrat-Regular.ttf\" \\\n    --font-bold \"Montserrat-Black.ttf\" \\\n    --output \"visualizer.mp4\"\n```\n\n### With Gradients\n\n```bash\nuv run klangbild \\\n    --audio \"song.mp3\" \\\n    --background \"cover.jpg\" \\\n    --layout spotlight \\\n    --wave-style circular \\\n    --text-gradient \"#FF8C42,#FF5A5F\" \\\n    --wave-gradient \"#FF5A5F,#FF8C42\" \\\n    --output \"visualizer.mp4\"\n```\n\n### With Film Grain\n\n```bash\nuv run klangbild \\\n    --audio \"song.mp3\" \\\n    --background \"cover.jpg\" \\\n    --grain 0.15 \\\n    --output \"visualizer.mp4\"\n```\n\n### With Portuguese Language\n\n```bash\nuv run klangbild \\\n    --audio \"musica.mp3\" \\\n    --background \"capa.jpg\" \\\n    --title \"Título da Música\" \\\n    --artist \"Nome do Artista\" \\\n    --album \"Nome do Álbum\" \\\n    --lang pt \\\n    --output \"visualizer.mp4\"\n```\n\n### Full Example\n\n```bash\nuv run klangbild \\\n    --audio \"song.mp3\" \\\n    --background \"cover.jpg\" \\\n    --title \"Тыл — фронту\" \\\n    --artist \"SKVGGOR\" \\\n    --album \"Productive Laziness (2026)\" \\\n    --layout spotlight \\\n    --wave-style circular \\\n    --text-gradient \"#FFD700,#FF6B6B\" \\\n    --wave-gradient \"#FF6B6B,#FFD700\" \\\n    --grain 0.1 \\\n    --font \"Montserrat-Regular.ttf\" \\\n    --font-bold \"Montserrat-Black.ttf\" \\\n    --gpu nvenc \\\n    --workers 30 \\\n    --output \"visualizer.mp4\"\n```\n\n### Batch Mode\n\n```bash\nuv run klangbild \\\n    --input-dir \"/path/to/mp3s\" \\\n    --background \"cover.jpg\" \\\n    --font \"Montserrat-Regular.ttf\" \\\n    --font-bold \"Montserrat-Black.ttf\" \\\n    --gpu nvenc \\\n    --workers 30\n```\n\n---\n\n## Options\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--audio` | — | Path to MP3/WAV (single-file mode) |\n| `--input-dir` | — | Folder of MP3s (batch mode) |\n| `--background` | **required** | Background image path for video |\n| `--cover-background` | same as `--background` | Separate background image for cover JPG |\n| `--title` | filename stem | Song title |\n| `--artist` | `\"\"` | Artist name |\n| `--album` | `\"\"` | Album name |\n| `--color` | `#FFFFFF` | Hex color (`#RGB` or `#RRGGBB`) |\n| `--output` | `output.mp4` | Output path (single-file mode) |\n| `--gpu` | `none` | `none` · `nvenc` · `vaapi` |\n| `--workers` | cpu_count − 2 | Parallel render workers |\n| `--font` | system DejaVu/Liberation | Regular font `.ttf/.otf` |\n| `--font-bold` | system DejaVu Bold | Bold font `.ttf/.otf` |\n| `--lang` | `en` | Prefix language: `en` (by/from) · `pt` (por/de) |\n| `--layout` | `classic` | Visual layout (see below) |\n| `--wave-style` | `line` | Waveform drawing style (see below) |\n| `--text-gradient` | — | Gradient colors for text (see below) |\n| `--text-gradient-dir` | `horizontal` | Text gradient direction: `horizontal` · `vertical` |\n| `--wave-gradient` | — | Gradient colors for waveform (see below) |\n| `--wave-gradient-dir` | `horizontal` | Waveform gradient direction: `horizontal` · `vertical` |\n| `--grain` | `0.0` | Film-grain intensity: `0.0` (off) → `1.0` (heavy) |\n| `--smoothing-window` | `15` | Spatial waveform smoothing window |\n| `--temporal-alpha` | `0.35` | Temporal EMA between frames (0=frozen, 1=raw) |\n\n---\n\n## Resources\n\n### Layouts\n\nThe `--layout` flag controls how elements are positioned on the 3840×2160 canvas.\n\n| Layout | Description |\n|--------|-------------|\n| `classic` | Original layout. Waveform centred, text stacked below, seek bar at bottom. |\n| `spotlight` | Large centred text with generous margins. Seek bar above text, waveform below. |\n| `split-left` | Two-column layout. Waveform on the left, text on the right, full-width seek bar at bottom. |\n| `split-right` | Two-column layout. Text on the left, waveform on the right, full-width seek bar at bottom. |\n\nReference layout images are included in `assets/`:\n\n| Spec file | Description |\n|-----------|-------------|\n| `spec_classic_line.png` | classic + line waveform |\n| `spec_classic_circular.png` | classic + circular waveform |\n| `spec_spotlight_line.png` | spotlight + line waveform |\n| `spec_spotlight_circular.png` | spotlight + circular waveform |\n| `spec_split-left_line.png` | split-left + line waveform |\n| `spec_split-left_circular.png` | split-left + circular waveform |\n| `spec_split-right_line.png` | split-right + line waveform |\n| `spec_split-right_circular.png` | split-right + circular waveform |\n| `spec_cover.png` | cover image layout |\n\nEach spec shows:\n- Waveform area (blue for line, orange for circular)\n- Text area (green)\n- Seek bar (yellow)\n- Dimensions and positions\n\n### Wave Styles\n\nThe `--wave-style` flag controls how the waveform is drawn.\n\n| Style | Description |\n|-------|-------------|\n| `line` | Classic mirrored waveform lines with fill. |\n| `circular` | Radial waveform — bars project outward from a central ring. |\n\nBoth styles react to the audio in real-time. The circular style works best with spotlight layout.\n\n### Gradients\n\nBoth text and waveform support independent color gradients. Each flag accepts two or more `#RGB` or `#RRGGBB` values separated by commas.\n\n```bash\n# Text gradient only\nuv run klangbild \\\n    --audio \"song.mp3\" --background \"cover.jpg\" \\\n    --text-gradient \"#FF8C42,#FF5A5F\"\n\n# Waveform gradient only\nuv run klangbild \\\n    --audio \"song.mp3\" --background \"cover.jpg\" \\\n    --wave-gradient \"#FFD700,#FF6B6B\"\n\n# Both combined, vertical direction\nuv run klangbild \\\n    --audio \"song.mp3\" --background \"cover.jpg\" \\\n    --text-gradient \"#FF8C42,#FF5A5F\" --text-gradient-dir vertical \\\n    --wave-gradient \"#FFD700,#FF6B6B\" --wave-gradient-dir vertical\n\n# Three-stop gradient\nuv run klangbild \\\n    --audio \"song.mp3\" --background \"cover.jpg\" \\\n    --text-gradient \"#FF0000,#FFFFFF,#0000FF\"\n```\n\nWhen `--text-gradient` is provided it overrides `--color` for all text elements and for the seek bar. When `--wave-gradient` is provided it overrides `--color` for the waveform. If only `--wave-gradient` is set (no text gradient), the seek bar also picks its color from the wave gradient. Both flags are independent and can be combined freely.\n\n**Direction:**\n\n| Value | Text | Waveform (`line`) |\n|-------|------|-------------------|\n| `horizontal` *(default)* | left → right across each glyph | left → right across the wave |\n| `vertical` | top → bottom across each glyph | top → bottom across the wave |\n\nFor the `circular` waveform style the gradient direction flag is ignored — colors cycle angularly around the ring instead.\n\n### Film Grain\n\nThe `--grain` flag overlays animated film grain on every frame. The value is a float between `0.0` (no grain) and `1.0` (heavy grain). At `0.0` the effect is completely skipped with no performance cost.\n\n```bash\n# Subtle grain\nuv run klangbild \\\n    --audio \"song.mp3\" --background \"cover.jpg\" \\\n    --grain 0.08\n\n# Noticeable grain\nuv run klangbild \\\n    --audio \"song.mp3\" --background \"cover.jpg\" \\\n    --grain 0.25\n```\n\nEach frame uses a unique random seed so the grain animates naturally without repeating patterns.\n\n---\n\n## Output\n\n- `\u003coutput\u003e.mp4` — 3840×2160 (4K), 30 fps, H.264, AAC 320 kbps\n- `\u003coutput\u003e.jpg` — 4K cover image with centered text\n\n---\n\n## License\n\n[GNU General Public License v3.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskvggor%2Fklangbild","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskvggor%2Fklangbild","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskvggor%2Fklangbild/lists"}