"""Frozen-process gate for the Qt multimedia runtime. PyInstaller executes this file as a runtime hook. Normal application starts are untouched; ``--media-smoke-test`` exits before the application entry point after proving that the frozen Qt multimedia modules and a decoder backend can be loaded in an offscreen Qt event loop. """ from __future__ import annotations import sys MEDIA_SMOKE_ARGUMENT = "--media-smoke-test" def _emit(message: str, *, error: bool = False) -> None: # Windowed PyInstaller executables set stdout/stderr to None on Windows. # The exit status is the gate contract; diagnostics are best-effort. stream = sys.stderr if error else sys.stdout if stream is not None: print(message, file=stream, flush=True) def _run_media_smoke_gate() -> None: # Keep these imports inside the gate. Missing frozen extension modules or # linked Qt multimedia libraries must make this process fail, while normal # launches retain the application's existing fallback behaviour. from PySide6.QtCore import QTimer from PySide6.QtMultimedia import QAudioOutput, QMediaFormat, QMediaPlayer from PySide6.QtMultimediaWidgets import QVideoWidget from PySide6.QtWidgets import QApplication application = QApplication.instance() owns_application = application is None if application is None: application = QApplication(["DoctorWorkstationMediaSmoke"]) player = QMediaPlayer() audio_output = QAudioOutput() video_widget = QVideoWidget() player.setAudioOutput(audio_output) player.setVideoOutput(video_widget) if not player.isAvailable(): raise RuntimeError("Qt reports that no multimedia backend is available") decode_formats = QMediaFormat().supportedFileFormats(QMediaFormat.ConversionMode.Decode) if not decode_formats: raise RuntimeError("Qt multimedia loaded without a supported decoder format") video_widget.resize(16, 16) video_widget.show() QTimer.singleShot(0, application.quit) event_status = application.exec() video_widget.close() player.setVideoOutput(None) player.setAudioOutput(None) if event_status != 0: raise RuntimeError(f"Qt multimedia offscreen event loop exited with {event_status}") # QApplication cannot be recreated safely in-process. The runtime hook is # a one-shot frozen gate, but retaining this distinction makes direct test # imports predictable. if owns_application: application.processEvents() def _dispatch() -> int | None: if MEDIA_SMOKE_ARGUMENT not in sys.argv[1:]: return None try: _run_media_smoke_gate() except Exception as exc: _emit( f"Frozen Qt multimedia smoke gate failed: {type(exc).__name__}: {exc}", error=True, ) return 70 _emit("Frozen Qt multimedia smoke gate passed.") return 0 _media_smoke_status = _dispatch() if _media_smoke_status is not None: raise SystemExit(_media_smoke_status)