File size: 2,615 Bytes
1824ea0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
"""Command-line interface for StemSplitter."""

from __future__ import annotations

import sys
from dataclasses import replace
from pathlib import Path

import click

from stemsplitter.config import get_settings
from stemsplitter.separator import OutputFormat, StemMode, StemSplitter


@click.command()
@click.argument("input_file", type=click.Path(exists=True, dir_okay=False))
@click.option(
    "-m",
    "--mode",
    type=click.Choice(["2stem", "4stem"], case_sensitive=False),
    default="2stem",
    show_default=True,
    help="Separation mode: 2-stem (vocals/instrumental) or 4-stem.",
)
@click.option(
    "-f",
    "--format",
    "output_format",
    type=click.Choice(["WAV", "MP3", "FLAC"], case_sensitive=False),
    default=None,
    help="Output audio format. Defaults to value in .env or WAV.",
)
@click.option(
    "-o",
    "--output-dir",
    type=click.Path(file_okay=False),
    default=None,
    help="Output directory. Defaults to value in .env or ./output.",
)
@click.option(
    "--model",
    default=None,
    help="Override the model filename (e.g., htdemucs.yaml).",
)
def main(
    input_file: str,
    mode: str,
    output_format: str | None,
    output_dir: str | None,
    model: str | None,
) -> None:
    """Separate audio stems from INPUT_FILE.

    Splits an audio file into vocal and instrumental stems (2-stem mode)
    or into vocals, drums, bass, and other (4-stem mode).

    \b
    Examples:
        stemsplitter song.mp3
        stemsplitter song.wav -m 4stem -f FLAC
        stemsplitter song.flac -m 2stem -f MP3 -o ./stems/
    """
    settings = get_settings()

    if output_dir:
        settings = replace(settings, output_dir=output_dir)

    Path(settings.output_dir).mkdir(parents=True, exist_ok=True)

    splitter = StemSplitter(settings=settings)

    stem_mode = StemMode(mode)
    fmt = OutputFormat(output_format.upper()) if output_format else None

    click.echo(
        f"Processing: {input_file}\n"
        f"Mode: {stem_mode.value} | "
        f"Format: {(fmt or OutputFormat(settings.output_format)).value}"
    )

    try:
        result = splitter.separate(
            input_path=input_file,
            mode=stem_mode,
            output_format=fmt,
            model_override=model,
        )
    except FileNotFoundError as exc:
        click.secho(str(exc), fg="red", err=True)
        sys.exit(1)
    except RuntimeError as exc:
        click.secho(f"Separation failed: {exc}", fg="red", err=True)
        sys.exit(1)

    click.secho("Separation complete!", fg="green")
    for f in result.output_files:
        click.echo(f"  -> {f}")