PyQt-based desktop app that connects to remote servers over SSH, discovers running Android emulators via adb, and continuously streams their screenshots into a multi-panel viewer.
Demo screenshot showing multiple emulator feeds streamed into the viewer.
- Reads available hosts directly from your
~/.ssh/configfile for quick selection. - Establishes an SSH session using Paramiko and runs all
adbcommands remotely. - Lists connected emulators (
adb devices) and lets you start/stop watchers per instance. - Streams frames by executing
adb -s <serial> exec-out screencap -pin worker threads and renders them in the GUI with timestamps. - Supports multiple concurrent emulators; each feed is labeled by its emulator serial and port.
- Provides a manual "Remote adb path" input so you can point to a non-standard
adbbinary on the server.
- Python 3.10 or newer on the local machine.
- The remote server must have Android SDK platform tools (
adb) installed and available onPATH. - Your
~/.ssh/configmust contain the target host definitions (non-wildcard entries) and the associated SSH keys must be accessible (agent or local files). - Local machine needs an X server (macOS + Qt is fine) and access to PyQt6.
- Install dependencies:
uv sync source .venv/bin/activate - Launch the GUI:
uv run emulator-watcher
- Enter the absolute path to
adbon the remote server, then select a host and click Connect. - Click Refresh Emulators to list running emulators.
- Highlight one or more emulators and click Start Watching to begin streaming their screens.
src/emulator_watcher/
├── app.py # PyQt application + main window
├── adb_service.py # SSH-backed adb helpers and screenshot workers
├── ssh_config.py # Parser for ~/.ssh/config entries
├── ssh_client.py # Paramiko session wrapper
├── models.py # Shared dataclasses
└── widgets/
└── emulator_panel.py