Skip to main content

zeropykvm

A KVM-over-IP solution running on Raspberry Pi Zero 2 W — rewritten from Zig to Python.

Attribution: This project is a Python port of darkyzhou/mykvm, originally written in Zig. All credit for the architecture and design goes to the original author.

Features

  • Zero-copy video pipeline: Uses Linux DMA-BUF to share buffers between capture device (TC358743) and hardware H.264 encoder (bcm2835-codec)
  • USB HID gadget: Emulates USB keyboard and mouse via Linux ConfigFS, with Boot Protocol support for BIOS compatibility
  • HTTPS + WebSocket: Serves a web frontend over HTTPS with WebSocket for real-time video streaming and HID control
  • E-Paper display: Optional status display on Waveshare EPD 2in13 V4
  • HDMI passthrough: Optionally mirror the captured HDMI input to the RPi's own HDMI output via the Linux framebuffer

Demo hardware

Screenshots

Web UI — Pi Zero 2 W capturing its own HDMI output, viewed in the browser

Hardware — Raspberry Pi Zero 2 W connected to the Waveshare HDMI-CSI adapter via flex cable

Architecture

The Python rewrite mirrors the original Zig project's architecture:

Module Description
args.py CLI argument parsing (argparse)
utils.py Utility functions (ioctl wrapper, IP detection, FourCC)
v4l2.py V4L2 constants, ioctl numbers, and ctypes structures
dma.py DMA heap allocation and buffer management
edid.py EDID setting and HDMI signal detection
capture.py V4L2 capture device with DMABUF support
encode.py V4L2 M2M H.264 encoder with DMABUF input
usb.py USB HID gadget setup, keyboard/mouse emulation
epaper.py E-Paper display driver
http_handler.py HTTP static file serving
server.py WebSocket client management and broadcast
ws_handler.py WebSocket message handling (keyboard/mouse events)
https_server.py HTTPS/TLS server with WebSocket upgrade
video.py Zero-copy video pipeline orchestration
passthrough.py HDMI passthrough via Linux framebuffer (/dev/fb0)
gencert.py Self-signed certificate generator (zeropykvm gencrt subcommand)
install_service.py Systemd service installer (zeropykvm install-service subcommand)
main.py Main entry point

Requirements

  • Python >= 3.12
  • Linux with V4L2 support (Raspberry Pi OS recommended)
  • TC358743 HDMI capture device
  • bcm2835-codec hardware encoder
  • USB gadget support (dwc2 overlay)
  • uv (recommended for dependency management)

Installation

# Install from PyPI using uv (recommended)
uv tool install zeropykvm

# Or with pip
pip install zeropykvm

# With e-Paper display support (on Raspberry Pi)
pip install zeropykvm[epaper]

Development setup

git clone https://github.com/esoadamo/zeropykvm.git
cd zeropykvm
uv sync

# With development tools
uv sync --extra dev

# With e-Paper display support (on Raspberry Pi)
uv sync --extra epaper

Usage

# Generate a self-signed TLS certificate (no openssl required)
zeropykvm gencrt --cert cert.pem --key key.pem

# Run zeropykvm
zeropykvm --cert cert.pem --key key.pem

# With custom settings
zeropykvm --cert cert.pem --key key.pem --port 443 --bitrate 2000000

# Enable HDMI passthrough (mirror input to the RPi HDMI output)
zeropykvm --cert cert.pem --key key.pem --hdmi-passthrough

# Use an alternate framebuffer device
zeropykvm --cert cert.pem --key key.pem --hdmi-passthrough --hdmi-passthrough-device /dev/fb1

Then open https://<pi-ip>:8443/ in a browser (or whatever port you chose) and accept the self-signed certificate.

HDMI passthrough

When --hdmi-passthrough is given, each captured frame is also written to the Linux framebuffer device (default /dev/fb0). This lets a locally-connected HDMI monitor display the source content in real time while the stream is simultaneously encoded and served over the network.

Supported framebuffer colour depths: 16-bit (RGB565) and 32-bit (ARGB8888). Supported capture pixel formats: YUYV, UYVY, and BGR24 (produced by the TC358743).

Performance note: The pixel format conversion is handled by a dynamically compiled C-extension directly between memory-mapped DMA buffers, achieving absolute zero-copy latency (literally 0 frames of software delay). Requirement: You MUST have gcc installed on the host device for this feature to function properly, as the extension is compiled at runtime to perfectly match the active hardware memory layout.

Systemd service

zeropykvm install-service automates the full setup on a Raspberry Pi OS host:

  • creates /etc/zeropykvm/ (mode 0755)
  • generates a self-signed TLS certificate there if one does not already exist
  • writes /etc/systemd/system/zeropykvm.service and runs daemon-reload → enable → start
# Install with defaults (port 8443, data dir /etc/zeropykvm) — runs as root
sudo zeropykvm install-service

# Custom port and data directory
sudo zeropykvm install-service --port 443 --data-dir /opt/zeropykvm

# Install with HDMI passthrough enabled by default
sudo zeropykvm install-service --hdmi-passthrough

# Install without starting the service immediately
sudo zeropykvm install-service --no-start

# Full option list
zeropykvm install-service --help

Testing

# Run all tests
uv run pytest

# Run with verbose output
uv run pytest -v

# Run specific test module
uv run pytest tests/test_usb.py -v

License

This project follows the same license as the original mykvm.

Metadata

Release files for zeropykvm 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zeropykvm 0.3.0
File Size Uploaded
zeropykvm-0.3.0.tar.gz 170.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for zeropykvm 0.3.0
File Interpreter ABI Platform
zeropykvm-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 330.1 kB

Release files / zeropykvm-0.3.0.tar.gz

Download URL zeropykvm-0.3.0.tar.gz
Size 170.9 kB
Tags Source
SHA-256 checksum
How to use checksums
0c0bcc423c8ae95982afb05cb3d20eeeef554f6add5eb12fec12c86fa2fecc39
BLAKE2b-256 checksum
How to use checksums
90394642d468394e17f6a160cd6cc0886b36d77a124eef5284342f82902c6c93
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 2, 2026.

Transparency log

Release files / zeropykvm-0.3.0-py3-none-any.whl

Download URL zeropykvm-0.3.0-py3-none-any.whl
Size 159.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
daaae0e595049f605be74167b343b8732507094a2e1a4939f1821af2afed8307
BLAKE2b-256 checksum
How to use checksums
1c2f4bfebcfdcf92f9a417dca17019e0aab502aa1b718110ebf783baa31df2bd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page