fix(tts): Linux audio — pw-play/paplay first, warn on nonzero exit

Na Linuksie wybiera pierwszy dostępny odtwarzacz w kolejności:
pw-play → paplay → aplay (wykrywa przez shutil.which).
Gdy żaden nie istnieje: "[TTS: brak odtwarzacza audio]".
Gdy odtwarzacz zwróci kod != 0: wypisuje ostrzeżenie ze stderr
(wcześniej aplay milczał bez śladu przy cichej awarii).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Oskar Kapala 2026-06-10 14:01:30 +02:00
parent d0f9f2ef42
commit 77c18e8b84

View file

@ -1,8 +1,11 @@
import os import os
import shutil
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
_LINUX_PLAYERS = ["pw-play", "paplay", "aplay"]
def speak(text: str, voice_path: str) -> None: def speak(text: str, voice_path: str) -> None:
with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tf: with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tf:
@ -35,7 +38,11 @@ def speak(text: str, voice_path: str) -> None:
def _play(wav_path: str) -> None: def _play(wav_path: str) -> None:
if sys.platform.startswith("linux"): if sys.platform.startswith("linux"):
_run_player("aplay", wav_path) player = next((p for p in _LINUX_PLAYERS if shutil.which(p)), None)
if player is None:
print("[TTS: brak odtwarzacza audio]")
return
_run_player(player, wav_path)
elif sys.platform == "darwin": elif sys.platform == "darwin":
_run_player("afplay", wav_path) _run_player("afplay", wav_path)
elif sys.platform == "win32": elif sys.platform == "win32":
@ -50,7 +57,10 @@ def _play(wav_path: str) -> None:
def _run_player(player: str, wav_path: str) -> None: def _run_player(player: str, wav_path: str) -> None:
try: try:
subprocess.run([player, wav_path], capture_output=True, timeout=30) proc = subprocess.run([player, wav_path], capture_output=True, timeout=30)
if proc.returncode != 0:
stderr = proc.stderr.decode(errors="replace").strip()
print(f"[TTS: {player} błąd {proc.returncode}: {stderr}]")
except FileNotFoundError: except FileNotFoundError:
print(f"[TTS off: {player} nie znaleziony]") print(f"[TTS off: {player} nie znaleziony]")
except Exception as exc: except Exception as exc: