Stream any Android phone's camera directly into OBS over USB or Wi-Fi with no cloud, no third-party servers, and no paid subscriptions. Verified at 1080p60 end-to-end (Samsung Galaxy S24 Ultra).
- 1080p60 H.264 hardware encoding (MediaCodec), tuned CBR with realtime priority and no B-frames
- USB and Wi-Fi simultaneously —
adb forwardfor lowest latency, or direct LAN with no ADB needed - Zoom slider (ultrawide ~0.6x through 10x on supported phones), tap-to-focus, continuous autofocus, torch toggle
- Front/back camera switch with mirroring, auto-rotate handling (portrait pillarboxed, never stretched)
- Live FPS badge, client count, keyframe-aware recovery (fresh IDR requested if congestion drops one)
- System-wide virtual camera — works in OBS, Zoom, Teams, Discord, browsers
Phone Camera
│
▼
[PhoneCam Android App]
│ H.264 Annex-B over TCP (port 8080)
│ HW encode 1080p60 ~10Mbps, rotation as metadata, 720p-capped preview
│
▼ USB-C cable (adb forward → localhost:8080)
│ …or direct Wi-Fi (phone LAN IP:8080, shown in the app)
▼
[phonecam_client.py]
│ PyAV decode in a child process → shared memory
│ letterbox fit → feeds frames into
│
▼
[OBS Virtual Camera driver]
│
▼
OBS Studio (Video Capture Device source) — or any camera app
- Android 8.0+ (API 26+); Android 11+ for the full ultrawide zoom range
- The PhoneCam APK installed
- USB Debugging enabled (USB mode only — Wi-Fi mode needs none of this)
- OBS Studio installed (provides the virtual camera driver)
- Python 3.10+ with pip
- Android SDK Platform Tools (for
adb, USB mode only) - USB-C data cable (USB mode)
Skip this whole step if you stream over Wi-Fi.
- Open Settings → About phone → Software information
- Tap Build number 7 times until "Developer mode unlocked" appears
- Go to Settings → Developer options
- Enable USB debugging
- Connect phone to PC via USB-C data cable (charge-only cables won't work)
- When prompted on the phone: tap Allow on the "Allow USB Debugging?" dialog
- Check "Always allow from this computer" to avoid repeated prompts
- Download from: https://developer.android.com/tools/releases/platform-tools
- Extract the zip (e.g., to
C:\platform-tools\) - Add to PATH:
- Press
Win + R→ typesysdm.cpl→ Environment Variables - Under "System variables", find
Path→ Edit → New → paste your folder path - Click OK on all dialogs
- Press
- Open a new Command Prompt and verify:
adb version
- Install Android Studio
- Open the
android-app/folder as a project - Let Gradle sync complete (needs the Android SDK; first build downloads it)
- Connect your phone (USB debugging on)
- Press Run ▶ (or
Shift+F10)
cd android-app
gradlew assembleDebug
adb install app\build\outputs\apk\debug\app-debug.apkInstall Python dependencies:
pip install pyvirtualcam opencv-python numpy avOr just run START_PHONECAM.bat — it handles installation automatically.
Developers: windows-client/test_phonecam_client.py holds the unit tests
(python -m unittest test_phonecam_client); the client is ruff-clean.
- Open the PhoneCam app
- Choose quality: 1080p 60fps (default), 1080p 30fps, 720p 60fps, or 720p 30fps
- Hold the phone landscape for fullscreen (portrait is pillarboxed, never stretched)
- Optional: drag the zoom slider, tap the preview to focus, toggle Torch, Flip for front camera
- Tap "Start Streaming"
- The green dot plus
Streaming H.264 :8080 1920x1080 @60fpsconfirms it's live. The app also shows its Wi-Fi address (e.g.WiFi 192.168.0.95:8080). - Keep PhoneCam in the foreground with the screen on. Streaming stops if the app is backgrounded or the phone locks (known limitation).
Quickest way:
double-click windows-client\START_PHONECAM.batOr manually:
adb forward tcp:8080 tcp:8080
python windows-client\phonecam_client.py- Read the current Wi-Fi IP from the app screen (DHCP can change it — always re-check before connecting).
- Phone and PC must share a network; 5GHz is strongly preferred over 2.4GHz.
- One command:
windows-client\START_PHONECAM.bat <phone-wifi-ip>Or manually:
python windows-client\phonecam_client.py --host <phone-ip> --no-adb- The client waits patiently for the first frame (Wi-Fi can take up to a
minute on a congested network) — leave it alone, watch for
[OK] Stream live!.
Verified measurements (Galaxy S24 Ultra): ~60fps USB, ~59fps clean Wi-Fi.
- Click + under Sources
- Select Video Capture Device
- Name it (e.g., "Phone Camera")
- In the device dropdown, select "OBS Virtual Camera"
- Click OK — you should see your phone's live feed!
python phonecam_client.py [OPTIONS]
--host HOST Stream host IP (default: 127.0.0.1; use phone IP for Wi-Fi)
--port PORT Stream port (default: 8080)
--width W Output width (default: 1920)
--height H Output height (default: 1080)
--fps FPS Virtual camera FPS (default: 60)
--no-adb Skip ADB setup (use with --host for Wi-Fi)
--overlay Show FPS/timestamp overlay on the stream
--preview Open a local OpenCV preview window
Example — 720p stream:
python phonecam_client.py --width 1280 --height 720Example — with preview window and overlay:
python phonecam_client.py --preview --overlay- Make sure the PhoneCam app shows
Streaming H.264 ...right now (re-check — the stream stops if the app leaves the foreground) - USB: run
adb forward --list— you should seetcp:8080 tcp:8080 - Wi-Fi: make sure the
--hostIP matches the app's Wi-Fi line and both devices share a network - Try
adb kill-serverthenadb start-server, then re-run the bat file
- First suspect the radio link, not the app: ping the phone (
ping <phone-ip>). Steady <10ms is healthy; swings like 6ms → 150ms+ mean congestion, weak signal, or a crowded 2.4GHz channel — move to 5GHz and closer to the router. - The app holds a high-performance Wi-Fi lock while streaming, but it can't fix a saturated channel: drop to 720p30 to halve the bitrate.
- Guest/hotel networks with client isolation block phone↔PC traffic — use a private WLAN or USB instead.
- You're almost certainly talking to the wrong address: without flags the
client dials
127.0.0.1(itself), which refuses when no ADB forward exists. UseSTART_PHONECAM.bat <phone-wifi-ip>orphonecam_client.py --host <phone-ip> --no-adb. - If flags are right: the phone's IP may have changed (DHCP) — re-read it from the app — or a guest network / VPN is isolating the devices.
- Open OBS Studio at least once — it registers the virtual camera driver
- OBS 28+ has virtual cam built-in; no extra setup needed
- Make sure Camera permission is granted: Settings → Apps → PhoneCam → Permissions
- Try a lower quality setting (720p) if you get camera errors
- If a lens/mode isn't supported, the app says so (e.g. "Lens caps at 30fps") — pick another combination
- Try a different USB-C cable (some are charge-only)
- Check the phone's USB mode is File Transfer / MTP in the USB notification
- Try
adb kill-serverand replug the cable
- USB is the lowest-latency option (~150–300ms typical with H.264)
- Reduce quality to 720p for lower latency and less heat
- If the phone gets warm on long 60fps sessions, fps may settle in the 40s — cool the phone or drop to 1080p30
- Ensure nothing else is using port 8080 on either device
- Known limitation: streaming currently stops if the app is backgrounded or the phone locks. Keep PhoneCam in the foreground while streaming.
phone-cam/
├── android-app/ ← Android Studio project
│ └── app/src/main/
│ ├── AndroidManifest.xml
│ ├── java/com/phonecam/
│ │ └── MainActivity.java ← Camera capture + H.264 server
│ └── res/
│ ├── layout/activity_main.xml
│ └── values/ (strings, colors), drawable/
│
├── windows-client/
│ ├── phonecam_client.py ← Main Python client (PyAV decode → virtual cam)
│ ├── test_phonecam_client.py ← Unit tests (python -m unittest test_phonecam_client)
│ └── START_PHONECAM.bat ← One-click launcher
│
├── LICENSE.md ← MIT License
└── README.md ← This file
Everything runs locally — over USB the camera data never leaves the cable; over Wi-Fi it never leaves your LAN. No internet connection required, no accounts, no cloud.
Wi-Fi mode note: the phone's stream server binds all network interfaces with no authentication. Over USB (
adb forward) the port is localhost-only and safe. Over Wi-Fi, anyone on the same network with your phone's IP and port can view the camera feed — only stream on networks you trust.