demix
audio processing tool: download from YouTube or use local files, separate stems, adjust tempo/pitch, detect and transpose key, and cut segments.
prerequisites
installation
I suggest to create virtualenv for this project to not break existing system-wide installations:
brew install virtualenvwrapper
brew install ffmpeg
brew install yt-dlp
mkdir demix
cd demix
mkvirtualenv -p /Users/pw/.pyenv/versions/3.8.16/bin/python demix
workon demix
pip install demix
demix -v
update
pip install demix --upgrade
development
prepare environment:
brew install virtualenvwrapper
brew install ffmpeg
git clone git@github.com:pwittchen/demix.git
cd demix
mkvirtualenv -p /Users/pw/.pyenv/versions/3.8.16/bin/python demix
workon demix
pip install -r requirements.txt
python demix.py -v
virtualenv
exit virtualenv, when you're done:
deactivate
to activate env again:
workon demix
testing
install pytest:
pip install pytest
run all tests (-v param for verbose):
pytest -v
versioning and deployment
When we create and push a new git tag, e.g. v1.0.4, deploy.yml github action is triggered. It automatically extracts created tag, updates version with bump_version.py script, performs git commit and push. After that, deployment of the new package version to PyPi is executed.
usage
demix -u <youtube-url> [options]
demix -s <search-query> [options]
demix -f <audio-file> [options]
options
| Option | Description |
|---|---|
-u, --url |
YouTube video URL to process |
-s, --search |
Search YouTube for a song (e.g., 'Artist - Song Name') |
-f, --file |
Local audio file to process (mp3, wav, flac, etc.) |
-o, --output |
Output directory (default: output) |
-t, --tempo |
Tempo factor for output audio (default: 1.0, use < 1.0 to slow down) |
-p, --transpose |
Transpose pitch by semitones (default: 0, range: -12 to +12) |
-k, --key |
Detect and display the musical key of the audio |
-K, --target-key |
Transpose audio to target key (e.g., C, Am, F#, Bb minor) |
-ss, --start |
Start time for cutting (format: MM:SS or HH:MM:SS) |
-to, --end |
End time for cutting (format: MM:SS or HH:MM:SS) |
-m, --mode |
Processing mode: nosplit, 2stems, 4stems, or 5stems (default: nosplit) |
--video |
Generate video: accompaniment track in 2stems mode, or the output music track in nosplit mode (default: skip video generation) |
-q, --quiet |
Suppress progress messages and spinners; print only the final result and errors |
-c, --clean |
Clean up files: output, models, or all |
-v, --version |
Show version number |
-h, --help |
Show help message |
modes
| Mode | Description |
|---|---|
nosplit |
No stem separation (download, convert, and apply effects only) |
2stems |
vocals, accompaniment |
4stems |
vocals, drums, bass, other |
5stems |
vocals, drums, bass, piano, other |
examples
# separate a YouTube video into vocals and accompaniment
demix -u 'https://www.youtube.com/watch?v=VIDEO_ID' -m 2stems
# search YouTube by artist and song name
demix -s 'Queen - Bohemian Rhapsody' -m 4stems
# separate a local file with 4 stems
demix -f /path/to/song.mp3 -m 4stems
# cut audio from 1:30 to 3:45
demix -f song.mp3 -ss 1:30 -to 3:45
# start from 0:30 (skip intro)
demix -f song.mp3 -ss 0:30
# keep only the first 2 minutes
demix -f song.mp3 -to 2:00
# combine cutting with tempo and transpose
demix -f song.mp3 -ss 1:00 -to 4:00 -t 0.8 -p -2
# detect musical key of a song
demix -f song.mp3 -k
# detect key before and after transposing
demix -f song.mp3 -k -p -3
# transpose to a specific key (auto-detects current key)
demix -f song.mp3 -K C
# transpose to A minor
demix -f song.mp3 -K Am
# transpose to target key with tempo change
demix -f song.mp3 -K "F# minor" -t 0.9
# slow down without separating stems
demix -f song.mp3 -t 0.8 -m nosplit
# download and cut without separation
demix -u 'https://www.youtube.com/watch?v=VIDEO_ID' -ss 1:00 -to 3:00 -m nosplit
# run silently and only print the final result message
demix -f song.mp3 -m 4stems -q
youtube downloads
When given -u or -s, demix downloads audio with yt-dlp if it's on PATH (brew install yt-dlp), falling back to pytubefix otherwise.
YouTube periodically restricts which player clients may fetch media without a PO token, and a blocked client typically fails with HTTP Error 403: Forbidden partway through the download. To survive that, demix retries the download across several yt-dlp player clients before giving up:
| Order | Strategy |
|---|---|
| 1 | yt-dlp defaults |
| 2 | player_client=tv_simply |
| 3 | player_client=web_embedded |
| 4 | player_client=mweb |
| 5 | pytubefix (WEB, ANDROID_VR, ANDROID, IOS) |
If every strategy fails, demix reports what each attempt returned instead of a single opaque error.
passing extra yt-dlp options
Set DEMIX_YT_DLP_ARGS to append arbitrary arguments to every yt-dlp invocation. This is the usual remedy when downloads are blocked and you're logged into YouTube in a browser:
DEMIX_YT_DLP_ARGS='--cookies-from-browser chrome' demix -u 'https://www.youtube.com/watch?v=VIDEO_ID' -m 2stems
Other useful values: --proxy http://…, --limit-rate 1M, --sleep-requests 2. If downloads still fail, brew upgrade yt-dlp often restores access, since new releases track YouTube's changes closely.
MCP server
The repo also ships an MCP server at mcp/ so LLM clients (Claude Desktop, Claude Code, etc.) can call demix directly. It's a sibling Python package (demix-mcp, Python 3.10+) that shells out to the demix CLI on PATH — keeping it decoupled from demix's own Python 3.8 environment.
Install (in a separate Python 3.10+ env):
pipx install ./mcp
Claude Code
Register the server with the claude mcp CLI (run from your demix workspace so pretrained_models/ and output/ cache there):
claude mcp add-json demix '{"command":"demix-mcp","cwd":"'"$PWD"'"}'
Add --scope user to make it available across all projects, or --scope project to commit it into .mcp.json for your team. Verify with:
claude mcp list
Inside Claude Code, run /mcp to inspect server status and the exposed tools.
Claude Desktop / other clients
Add the server to ~/Library/Application Support/Claude/claude_desktop_config.json (or your client's equivalent):
{
"mcpServers": {
"demix": {
"command": "demix-mcp",
"cwd": "/path/to/demix-workspace"
}
}
}
Tools exposed: process_audio, detect_key, search_youtube, clean. See mcp/README.md for details.
Claude Code skill
This repo ships a Claude Code skill at .claude/skills/demix/SKILL.md that translates plain-English requests into demix invocations — describe what you want and Claude picks the flags, shows the command, and runs it.
Examples of requests the skill handles:
- "Download
https://youtu.be/abc123and give me the instrumental" →demix -u 'https://youtu.be/abc123' -m 2stems - "Find 'Radiohead Creep', slow it 15%, keep only the first two minutes" →
demix -s 'Radiohead Creep' -t 0.85 -to 2:00 - "
~/Music/song.mp3— transpose to G minor and split into 4 stems" →demix -f '~/Music/song.mp3' -m 4stems -K 'Gm' - "What key is
song.wavin?" →demix -f 'song.wav' -k - "Make a karaoke video from 'Adele - Hello'" →
demix -s 'Adele - Hello' -m 2stems --video
Trigger it by typing /demix in Claude Code, or just describe the task in natural language — the skill loads automatically when the intent matches.
Metadata
Release files for demix 1.7.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| demix-1.7.2.tar.gz | 31.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| demix-1.7.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.4 kB
Release files / demix-1.7.2.tar.gz
| Download URL | demix-1.7.2.tar.gz |
|---|---|
| Size | 31.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9879737d8d5e11aee1619e00ce46aaebbfb20ee1487db1c8684f2d88cdb1fbc7
|
|
BLAKE2b-256 checksum How to use checksums |
e58b2aec8f8bf3b2e1e213210223cf0d2d0aec2787b71fa8df70f937fc370274
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.8.18
|
Release files / demix-1.7.2-py3-none-any.whl
| Download URL | demix-1.7.2-py3-none-any.whl |
|---|---|
| Size | 19.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
974d8620d8c1a9330043e6e55ec2a80f18bcf22ca9cdd1c41648113348c216db
|
|
BLAKE2b-256 checksum How to use checksums |
13da19080e4c1627c0df494fce739fe9e1b0d0ef1949c79ad5d77fe067ac746a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.8.18
|
Security for demix 1.7.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.