A DroidCam-like project: the phone streams its camera, a Linux or Windows PC receives the feed and turns it into a virtual webcam for Zoom/OBS/Discord/the browser.
Status: video and audio from a real phone work end-to-end in Zoom/OBS/Discord/the browser: virtual camera and virtual microphone, live manual camera controls (zoom/focus/exposure/AWB), unlimited text/image overlays with a placement editor, a GTK4 window on Linux (and a native Tkinter window on Windows), an experimental Bluetooth bridge (SoundPad Live) for calls/media from the phone straight into PC headphones - Linux only, see DETAILS.md for details.
This README covers the Linux receiver. There's also a Windows version (video + audio, tray icon with autostart, its own native GUI window - everything except SoundPad Live, which isn't possible on stock Windows, see WINDOWS.md for why), see WINDOWS.md.
The Releases page has
ready-to-use files, built automatically via GitHub Actions
(.github/workflows/build.yml), see packaging/build-linux.sh.
- Android:
camrelay-*-android.apk. Debug-signed (not for Google Play, but installs and works exactly the same), one file for every architecture (arm64/armv7/x86/x86_64) - there are no native libraries in the code. - Linux: three formats to choose from:
camrelay-*-linux-x86_64.tar.gz: unpack anywhere, already contains a ready-made venv, works like a regular git clone from there (./run.sh/./gui.sh)camrelay_*_amd64.deb:sudo apt install ./camrelay_*_amd64.deb, then thecamrelay/camrelay-gui/camrelay-soundpad-livecommands or the "CamRelay" shortcut in the applications menuCamRelay-*-x86_64.AppImage:chmod +x, run it. Still requires the systempython3-gi/GTK4/libadwaita packages (see DETAILS.md, section 3) - AppImage can't bundle those inside itself, that's not a limitation specific to this project
Build it yourself: workflow_dispatch in Actions, or a v* tag (a tag
also creates a draft release with every file attached).
Building from source, running by hand without prebuilt packages, every feature of the Android app, tray/autostart, diagnostics, the experimental SoundPad Live Bluetooth bridge - see DETAILS.md.
android-app (phone) or test-emulator (PC webcam, for testing without a phone)
CameraX --YUV_420_888--> JPEG --> NanoHTTPD :8080/video
|
| MJPEG (multipart/x-mixed-replace)
v
receiver (PC)
HTTP client --> decodes JPEG (OpenCV) --> pyvirtualcam --> /dev/video10 (v4l2loopback)
|
v
Zoom / OBS / Discord / browser
The video source (the phone or test-emulator) always runs an HTTP
MJPEG server on port 8080; receiver is the HTTP client that connects
to it - the same scheme DroidCam/IP Webcam use. The Android app and
test-emulator produce the same wire format, so receiver.py doesn't
need to distinguish between them - only --source changes.
The Android app announces itself on the local network over mDNS/DNS-SD
(_camrelay._tcp, NsdManager), and receiver.py, when --source
isn't given, looks for it on its own via zeroconf - no need to type in
the phone's IP by hand.
receiver/ receiver.py (Linux) + receiver_win.py (Windows) + protocol.py (shared wire protocol) + gui.py/tray.py
test-emulator/ Phone emulator: PC webcam -> MJPEG (for testing without a phone)
android-app/ Android app: phone camera -> MJPEG
soundpad-live/ Experimental Bluetooth call/media bridge (DETAILS.md, 5.1), Linux only, unrelated to the camera
assets/ App icon (svg/png)
desktop/ .desktop shortcut for the applications menu
systemd/ Unit for autostart (systemd --user)
run.sh Runs the receiver (± test-emulator) with one command (Linux)
run_windows.bat Runs receiver_win.py (Windows, see WINDOWS.md)
gui.sh Launches the simple window (instead of run.sh/a terminal, Linux)
soundpad-live.sh Launches the Bluetooth bridge (DETAILS.md, 5.1, Linux)