feat(voice-client): PySide6 desktop client and Windows build scripts

Add voice_confirmation_client (poll, TTS MP3 playback, mic WAV resolve),
PyInstaller spec, start/build helpers, and API unit tests.

Pending manual testing: end-to-end on OR workstations and packaged exe.

Made-with: Cursor
This commit is contained in:
Kevin
2026-04-27 09:52:10 +08:00
parent e4c6127619
commit 4c3f9a367b
19 changed files with 1324 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
"""Resolve bundled helper binaries (ffplay/ffmpeg) next to the package or PyInstaller extract dir."""
from __future__ import annotations
import sys
from pathlib import Path
def package_root() -> Path:
"""Directory containing `voice_confirmation_client` package."""
return Path(__file__).resolve().parent.parent
def frozen_base() -> Path | None:
"""PyInstaller onefile/onedir: sys._MEIPASS or executable dir."""
if getattr(sys, "frozen", False):
meipass = getattr(sys, "_MEIPASS", None)
if meipass:
return Path(meipass)
return Path(sys.executable).resolve().parent
return None
def bin_dir() -> Path:
"""Optional `bin/` next to package (dev) or under _MEIPASS (frozen)."""
fb = frozen_base()
if fb is not None:
d = fb / "voice_confirmation_bin"
if d.is_dir():
return d
return package_root() / "bin"
def find_ffplay() -> Path | None:
for name in ("ffplay", "ffplay.exe"):
p = bin_dir() / name
if p.is_file():
return p
return None
def find_ffmpeg() -> Path | None:
for name in ("ffmpeg", "ffmpeg.exe"):
p = bin_dir() / name
if p.is_file():
return p
return None