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
48 lines
1.2 KiB
Python
48 lines
1.2 KiB
Python
"""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
|