feat(service): no_playback-Flag (nur WAV erzeugen, kein lokales Abspielen)

Fuer Remote-/Gateway-Nutzung: mit no_playback=true generiert der Worker nur die
WAV (keep_audio) und startet keinen PlaybackWorker -> der Server spielt nicht laut
ab. Default false (lokales Abspielen unveraendert).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-18 09:45:17 +02:00
commit 1ce6540711

View file

@ -99,6 +99,7 @@ class SpeakJob:
pronunciation_dict: Optional[dict] pronunciation_dict: Optional[dict]
session_id: Optional[str] session_id: Optional[str]
keep_audio: bool = False keep_audio: bool = False
no_playback: bool = False # nur WAV erzeugen, NICHT lokal abspielen (Remote-/Gateway-Nutzung)
status: JobStatus = field(default=JobStatus.pending) status: JobStatus = field(default=JobStatus.pending)
text_preview: str = field(default="") text_preview: str = field(default="")
chunks_total: int = 0 chunks_total: int = 0
@ -144,13 +145,16 @@ def _worker() -> None:
job.chunks_total = len(chunks) job.chunks_total = len(chunks)
job.text_preview = job.text[:80] job.text_preview = job.text[:80]
playback = tts.PlaybackWorker( # no_playback: nur generieren (kein lokales Abspielen) -> Remote/Gateway.
sample_rate=sr, playback = None
device=job.audio_device or "pulse", if not job.no_playback:
speed=job.speed, playback = tts.PlaybackWorker(
stop_event=tts.STOP_REQUESTED, sample_rate=sr,
) device=job.audio_device or "pulse",
playback.start() speed=job.speed,
stop_event=tts.STOP_REQUESTED,
)
playback.start()
wavs: list[torch.Tensor] = [] wavs: list[torch.Tensor] = []
try: try:
@ -159,10 +163,12 @@ def _worker() -> None:
break break
wav = tts.generate_chunk(model, model_kind, chunk, job.lang, job.voice) wav = tts.generate_chunk(model, model_kind, chunk, job.lang, job.voice)
wavs.append(wav) wavs.append(wav)
playback.put(wav) if playback is not None:
playback.put(wav)
job.chunks_done += 1 job.chunks_done += 1
finally: finally:
playback.stop() if playback is not None:
playback.stop()
if wavs: if wavs:
final = wavs[0] if len(wavs) == 1 else torch.cat(wavs, dim=-1) final = wavs[0] if len(wavs) == 1 else torch.cat(wavs, dim=-1)
@ -215,6 +221,7 @@ class SpeakRequest(BaseModel):
session_id: Optional[str] = None session_id: Optional[str] = None
pronunciation_dict: Optional[dict] = None pronunciation_dict: Optional[dict] = None
keep_audio: bool = False # WAV im Cache behalten für GET /audio/{job_id} keep_audio: bool = False # WAV im Cache behalten für GET /audio/{job_id}
no_playback: bool = False # nur generieren (kein lokales Abspielen) -> fuer Remote/Gateway
def _job_to_dict(j: SpeakJob) -> dict: def _job_to_dict(j: SpeakJob) -> dict:
@ -284,6 +291,7 @@ def speak(req: SpeakRequest):
pronunciation_dict=req.pronunciation_dict, pronunciation_dict=req.pronunciation_dict,
session_id=req.session_id, session_id=req.session_id,
keep_audio=req.keep_audio, keep_audio=req.keep_audio,
no_playback=req.no_playback,
) )
_job_queue.put(job) _job_queue.put(job)