"""Play MP3 bytes via system player or bundled ffplay.""" from __future__ import annotations import base64 import os import shutil import subprocess import sys import tempfile from pathlib import Path from voice_confirmation_client.core.paths import find_ffplay def play_mp3_from_base64(b64: str) -> None: raw_b64 = "".join((b64 or "").split()) if not raw_b64: raise ValueError("empty prompt_audio_mp3_base64") data = base64.b64decode(raw_b64, validate=False) with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as f: f.write(data) tmp = f.name try: _play_mp3_path(Path(tmp)) finally: try: os.unlink(tmp) except OSError: pass def _play_mp3_path(path: Path) -> None: bundled = find_ffplay() if bundled and bundled.is_file(): subprocess.run( [str(bundled), "-nodisp", "-autoexit", "-loglevel", "quiet", str(path)], check=True, timeout=600, ) return ffplay = shutil.which("ffplay") if ffplay: subprocess.run( [ffplay, "-nodisp", "-autoexit", "-loglevel", "quiet", str(path)], check=True, timeout=600, ) return if sys.platform == "darwin": subprocess.run(["afplay", str(path)], check=True, timeout=600) return if os.name == "nt": os.startfile(str(path)) # type: ignore[attr-defined] import time time.sleep(5) return raise RuntimeError( "No MP3 player found. Install ffmpeg (ffplay) or run on macOS with afplay." )