diff options
| author | historia <historiavg@proton.me> | 2026-08-25 16:40:30 -0400 |
|---|---|---|
| committer | historia <historiavg@proton.me> | 2026-08-25 16:40:30 -0400 |
| commit | 867866f131b0b6c76c54272791e7f7dea01db990 (patch) | |
| tree | b57ecdd66eeaf7ad73742d2f2bbe15d3a5498fa3 /audiobook.py | |
| parent | fca3431721a55277f139efc83df2438207917448 (diff) | |
| download | tts-audiobook-generator-867866f131b0b6c76c54272791e7f7dea01db990.tar.gz | |
feat: better tui menu option gating for models that support custom voices (qwen) and models that do not support instructions
Diffstat (limited to 'audiobook.py')
| -rwxr-xr-x | audiobook.py | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/audiobook.py b/audiobook.py index 9bdad19..b4cd89d 100755 --- a/audiobook.py +++ b/audiobook.py @@ -59,6 +59,7 @@ def convert(backend: str = None, voice: str = None, clone: str = None, model_id: str = None, instructions: str = None, request_options: dict = None, input_dir: Path = None, output_dir: Path = None, api_url: str = None, + speaker: str = None, progress=None, cancel=None, confirm=None, book_files=None, planned=None) -> int: """Run one conversion pass with explicit options (used by the CLI and hub). @@ -101,7 +102,7 @@ def convert(backend: str = None, voice: str = None, clone: str = None, book_files, planned = AudiobookConverter.preflight_overwrites( backend=backend, voice=voice, voice_mode=voice_mode, voice_clone_ref_audio=clone, output_format=output_format, - instructions=instructions, confirm=confirm, + instructions=instructions, speaker=speaker, confirm=confirm, ) if not book_files: print("[INFO] Nothing to convert. Add a .txt, .pdf, or .epub file " @@ -120,6 +121,7 @@ def convert(backend: str = None, voice: str = None, clone: str = None, language=language, backend=backend, voice=voice, debug=debug, model_id=model_id, instructions=instructions, request_options=request_options, api_url=api_url, + speaker=speaker, progress=progress, cancel=cancel, ) converter._book_files = book_files @@ -247,11 +249,21 @@ Examples: "a key in the server's voices.json ('default' when it was started " "with --ref-audio). audiocpp: a voice_preset or voice_dir entry " "(cloning); required for audio.cpp families without built-in " - "speakers (everything except Qwen3-TTS CustomVoice). Not used by " + "speakers (everything except Qwen3-TTS CustomVoice). When " + "AUDIOCPP_CLONE_MODEL_ID names a second server entry (typically " + "the Qwen Base model), --voice reroutes to it. Not used by " "the qwen backend (use app/converter/config.py SPEAKER or --clone " "there).") ) parser.add_argument( + "--speaker", type=str, default=None, metavar="NAME", + help=("audiocpp only: a built-in Qwen3-TTS CustomVoice speaker name " + "(e.g. Vivian, Ryan, Uncle Fu). Selects speaker mode on the " + "CustomVoice model entry; mutually exclusive with --voice. " + "Without --voice/--speaker, a CustomVoice entry defaults to " + "the SPEAKER in app/converter/config.py.") + ) + parser.add_argument( "--debug", action="store_true", help=("Troubleshooting mode: dump each chunk's raw audio and the exact text " "sent for it under the debug/ folder (organized per book and chapter), " @@ -326,6 +338,11 @@ Examples: "uses a voice configured on the server (voice_presets or " "voice_dir in its config); select it with --voice (see README)") args.clone = None + if args.voice and args.speaker: + parser.error("--voice and --speaker are mutually exclusive with " + "--backend audiocpp: --voice selects a server-side " + "preset (cloning), --speaker a built-in CustomVoice " + "speaker (see README)") if args.transcription or args.no_transcription: print("[WARNING] --transcription/--no-transcription are ignored with " "--backend audiocpp: the reference transcript is configured on " @@ -356,6 +373,10 @@ Examples: parser.error("--model requires --backend audiocpp; it selects an " "audio.cpp server model entry id") + if args.speaker is not None and args.backend != BACKEND_AUDIOCPP: + parser.error("--speaker requires --backend audiocpp; it selects a " + "built-in Qwen3-TTS CustomVoice speaker") + if args.instructions is not None and args.backend != BACKEND_AUDIOCPP: parser.error("--instructions requires --backend audiocpp; it is " "sent as the audio.cpp request's instructions field") @@ -390,6 +411,7 @@ Examples: request_options=request_options, input_dir=args.input, output_dir=args.output, api_url=api_url, + speaker=args.speaker, )) |
