Spaces:
Running
Running
| import subprocess | |
| import sys | |
| from pathlib import Path | |
| from processor import _get_device | |
| def _run_demucs(audio_path: Path) -> Path: | |
| """Run demucs in two-stems mode targeting vocals; return path to no_vocals stem.""" | |
| out_root = audio_path.parent / "demucs_out" | |
| out_root.mkdir(parents=True, exist_ok=True) | |
| cmd = [ | |
| sys.executable, | |
| "-m", | |
| "demucs", | |
| "--two-stems", "vocals", | |
| "-n", "htdemucs", | |
| "--device", _get_device(), | |
| "--mp3", | |
| "--mp3-bitrate", "192", | |
| "-o", str(out_root), | |
| str(audio_path), | |
| ] | |
| subprocess.run(cmd, check=True) | |
| # demucs writes to {out_root}/htdemucs/{audio_stem}/no_vocals.mp3 | |
| candidate = out_root / "htdemucs" / audio_path.stem / "no_vocals.mp3" | |
| if not candidate.exists(): | |
| raise RuntimeError(f"demucs did not produce {candidate}") | |
| return candidate | |
| def _encode_mp3(wav_path: Path, mp3_path: Path) -> Path: | |
| """Re-encode (or copy) a stem file to the target mp3_path.""" | |
| subprocess.run( | |
| ["ffmpeg", "-y", "-i", str(wav_path), "-b:a", "192k", str(mp3_path)], | |
| check=True, capture_output=True, | |
| ) | |
| return mp3_path | |
| def separate_vocals_to_mp3(audio_path: Path) -> Path: | |
| no_vocals_stem = _run_demucs(audio_path) | |
| return _encode_mp3(no_vocals_stem, audio_path.parent / "no_vocals.mp3") | |