No description
  • Shell 72.8%
  • Rust 27.2%
Find a file
microchipster 8e38495594 deps
2026-07-15 14:00:05 -07:00
webrtc-client tweaking latency 2026-07-08 23:37:23 -07:00
README.md browser support 2026-07-10 19:15:03 -07:00
todo.md todo 2026-07-09 11:36:00 -07:00
webrtc-mirrorctl deps 2026-07-15 14:00:05 -07:00

Video Mirror

Low-latency mirrored playback with a remote capture host, remote SRS ingest, and a local GTK4 Rust viewer.

TL;DR

  • Start here: ./webrtc-mirrorctl --help
  • That help text is the authoritative source for check, install, reinstall, uninstall, status, logs, viewer, and repair commands.
  • ./webrtc-mirrorctl check all whep media mirror reports whether both sides are installed.
  • ./webrtc-mirrorctl uninstall all whep media mirror removes both client and server services.
  • ./webrtc-mirrorctl install all whep media mirror installs missing pieces on both sides.
  • ./webrtc-mirrorctl reinstall all whep media mirror rewrites both sides and restarts them.
  • Everything runs as systemctl --user services.
  • The client is a local Rust GTK viewer.
  • The server side on media runs SRS in Docker plus an ffmpeg publisher.

What It Does

The mirror is split into three pieces:

  1. The remote capture host (media) publishes video from the capture card into SRS.
  2. SRS exposes the stream over WHEP at http://HOST:1985/rtc/v1/whep/?app=live&stream=mirror.
  3. The local webrtc-client opens that WHEP endpoint and renders fullscreen in GTK.

The viewer preserves aspect ratio and uses black bars instead of cropping content.

The local client service and manual viewer path default to an 8G memory cap. Set WEBRTC_MIRROR_CLIENT_MEMORY_MAX if you want a different cap.

Pass srt-direct as the required profile argument to ./webrtc-mirrorctl ... if you want to bypass SRS and connect the local viewer directly to the remote publisher over raw SRT.

Use srt-fanout instead when multiple SRT clients need to play at once. It publishes the same encoded MPEG-TS stream through three independent SRT listeners on WEBRTC_MIRROR_SRT_PORT, that port plus one, and that port plus two. For the default port, use srt://HOST:10080, srt://HOST:10081, and srt://HOST:10082 in VLC or mpv. Each listener accepts one caller.

For example:

./webrtc-mirrorctl reinstall all srt-fanout media mirror

The local GTK viewer uses the first listener. This profile does not use SRS or the unsupported SRS rtmp_to_srt setting.

Use srt-whep when Linux clients should retain the direct SRT path while an Android or browser client uses WHEP. It encodes once and publishes two outputs: the raw SRT listener on WEBRTC_MIRROR_SRT_PORT and an SRT ingest into SRS on the next port. With the default settings, direct SRT is on port 10080 and the SRS ingest is on port 10081. The local GTK viewer uses the raw SRT listener; WHEP clients use:

http://HOST:1985/rtc/v1/whep/?app=live&stream=mirror

For Cromite on Android, open the companion page served by SRS:

http://HOST:8080/mirror.html?stream=mirror

Keep the page on the same host as SRS so the browser's WHEP request is same-origin and does not require extra CORS configuration.

Install it with:

./webrtc-mirrorctl reinstall all srt-whep media mirror

This profile does not use SRS rtmp_to_srt; SRS only receives the publisher's SRT ingest and exposes it through WHEP.

The page is served by SRS at http://HOST:8080/mirror.html?stream=mirror and is intended for Android Cromite or Chromium. It performs the WHEP SDP exchange in the browser and uses the same origin as SRS to avoid a CORS dependency.

The remote publisher now prefers a supported widescreen capture mode by default and falls back to the device's reported mode if none of the common widescreen sizes are available. Set WEBRTC_MIRROR_CAPTURE_SIZE only if you need to pin a specific mode.

If the image still looks soft after reinstalling, raise WEBRTC_MIRROR_BITRATE and/or set WEBRTC_MIRROR_CAPTURE_SIZE before running ./webrtc-mirrorctl reinstall all whep ....

For operational details, service names, and log commands, use ./webrtc-mirrorctl --help.