"""Ad-hoc video playback probe (not part of the test suite). Plays the intro video in a Kivy window and reports whether it decodes and advances. Used to verify the ffpyplayer path on Raspberry Pi OS Trixie. .venv/bin/python linux/_probe_video.py [path/to/video.mp4] """ import os import sys import time # Mirror the real entry point: SDL2 does NOT discover the Wayland socket on its # own, so WAYLAND_DISPLAY must be filled in first. Without this the probe falls # back to x11 and dies with "Couldn't connect to X server". sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from linux_display import ensure_session_environment # noqa: E402 ensure_session_environment() os.environ.setdefault('SDL_VIDEODRIVER', 'wayland,x11,dummy') os.environ.setdefault('KIVY_GL_BACKEND', 'gl') os.environ.setdefault('KIVY_VIDEO', 'ffpyplayer') os.environ.setdefault('KIVY_AUDIO', 'ffpyplayer') from kivy.config import Config # noqa: E402 Config.set('graphics', 'window_state', 'hidden') Config.set('graphics', 'fullscreen', '0') from kivy.app import App # noqa: E402 from kivy.clock import Clock # noqa: E402 from kivy.uix.video import Video # noqa: E402 SOURCE = sys.argv[1] if len(sys.argv) > 1 else 'config/resources/intro1.mp4' DURATION = 12.0 results = {} class Probe(App): def build(self): self.video = Video( source=SOURCE, state='play', options={'eos': 'stop'}, allow_stretch=True, keep_ratio=True, ) self.video.bind(on_eos=lambda *a: results.setdefault('eos', True)) return self.video def on_start(self): self.t0 = time.monotonic() Clock.schedule_interval(self.tick, 1.5) Clock.schedule_once(lambda dt: self.stop(), DURATION) def tick(self, dt): elapsed = time.monotonic() - self.t0 core = self.video._video position = getattr(core, 'position', None) if core else None if position is not None: results['last_position'] = position print( f' t={elapsed:5.1f}s state={self.video.state} ' f'duration={self.video.duration:.1f} position={position} ' f'texture={"yes" if self.video.texture else "no"}', flush=True, ) Probe().run() print(f'RESULT duration={results.get("duration")} ' f'last_position={results.get("last_position")} eos={results.get("eos")}')