Use a Usee Plus protocol USB endoscope/periscope camera (3301:2001 Geek szitman supercamera) without its proprietary app.
This camera does not use UVC — it speaks a proprietary USB bulk protocol, so it is invisible to standard OS camera APIs (V4L2, etc.) and only works with the vendor app. This repository implements the protocol directly and turns the camera into a standard MJPEG HTTP stream that works anywhere: any Linux box, a NAS, a Raspberry Pi, or a container.
- Live view in a browser — open
http://<host>:8080/ - VLC / mpv — open
http://<host>:8080/streamas a network stream - Home Assistant — add it as an MJPEG camera
- ffmpeg — transcode to H.264/RTSP for NVRs (see NVR integration)
- Snapshots —
http://<host>:8080/snapshotreturns a single JPEG frame
# Dependencies
sudo apt-get install build-essential libusb-1.0-0-dev
# Build
g++ -std=c++20 -O2 -o supercamera_server supercamera_server.cpp -lusb-1.0 -pthread
g++ -std=c++20 -O2 -o supercamera_capture supercamera_capture.cpp -lusb-1.0 -pthread
# USB permissions (udev)
sudo cp deploy/99-supercamera.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && sudo udevadm trigger
# Run
./supercamera_server 8080Open http://<host>:8080/ in a browser for the live view.
sudo cp deploy/supercamera.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now supercamera.serviceAdjust
User=,WorkingDirectory=, andExecStart=indeploy/supercamera.serviceto match your environment.
| URL | Description |
|---|---|
http://<host>:8080/ |
HTML viewer |
http://<host>:8080/stream |
MJPEG stream (multipart/x-mixed-replace) — VLC / Home Assistant / ffmpeg |
http://<host>:8080/stream.raw |
Consecutive JPEG stream (no multipart framing) |
http://<host>:8080/snapshot |
Single JPEG frame |
Protocol specification reverse-engineered from raw USB dumps.
- VID:PID:
3301:2001, Interface 0 (EP 0x01/0x81) + Interface 1 (EP 0x02/0x82) - Init sequence:
- MFi probe
FF 55 FF 55 EE 10→ EP1 (0x01) - Open stream
BB AA 05 00 00→ EP2 (0x02) - Video read → EP2 (0x82), 1024-byte bulk transfers
- MFi probe
- USB transfer = 1024B = 2 × 512B blocks
- Each 512B block: 12B header + 500B JPEG data
- Header:
aa bb 07 fb 01+ fid(1B) + cam_num(1B) + cont(1B) + meta(4B)
- Header:
- Frame boundary = EOI (FF D9) — JPEG byte-stuffing rules guarantee FF D9 never appears inside entropy-coded data, so EOI detection is exact
- After EOI, the next frame's header starts after 0-3 bytes of padding
- The first frame after device startup (fid=0) is incomplete — skip it
- Resolution: 1280x720 JPEG, ~15-17 fps, frame size ~17-23 KB
- Endpoint layout varies by model: a known sibling model (2CE3:3828) uses EP1 for everything, but the 3301:2001 uses EP1 for MFi and EP2 for open+video. If it doesn't work, capture a raw dump and check.
- The length field (0x01fb=507) is inconsistent with the packet size — ignore it and use all bytes
- cam_num is not a frame boundary (it is 0 in all packets of subsequent frames)
- A short packet (<1024B) alone is not a reliable frame boundary
- The first frame is corrupted — skipping it is mandatory
The MJPEG stream can be transcoded to H.264 RTSP with ffmpeg and fed to any NVR that supports RTSP or ONVIF. The setup below uses UniFi Protect as an example.
supercamera.service (MJPEG :8080)
→ ffmpeg (MJPEG→H.264 RTSP :8556)
→ ONVIF bridge (WS-Discovery + SOAP :8089) + MediaMTX
→ UniFi Protect "RTSP Bridge SuperCamera"
| Component | Role |
|---|---|
supercamera.service |
MJPEG HTTP server (port 8080) |
supercamera-rtsp.service |
ffmpeg MJPEG→H.264 RTSP transcoder (port 8556) |
supercamera-protect.service |
ONVIF bridge (WS-Discovery + SOAP API, port 8089) + MediaMTX |
# 1. ffmpeg + MediaMTX
sudo apt-get install ffmpeg
# Place the MediaMTX binary (https://github.com/bluenviron/mediamtx/releases)
# 2. ONVIF bridge (Node.js)
# Reuse the action4-protect bridge implementation:
# copy dist/src/ and configure camera info via environment variables
# CAMERA_ID=supercamera CAMERA_NAME=SuperCamera
# CAMERA_RTSP_URL=rtsp://127.0.0.1:8556/supercamera
# CAMERA_PORT=8089 HOST_IP=<LAN IP> RTSP_HOST=<LAN IP> RTSP_STREAM_PORT=8556
# 3. ffmpeg transcoding (the multipart endpoint is the stable one)
ffmpeg -f mjpeg -i http://127.0.0.1:8080/stream \
-c:v libx264 -preset ultrafast -tune zerolatency -profile:v high \
-pix_fmt yuv420p -r 17 -g 17 -bf 0 -b:v 2000k \
-f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8556/supercamera
# 4. Register the camera in the UniFi Protect DB (macvlan environments)
# Publish the ONVIF bridge on an IP reachable from the Protect container
# (with macvlan, a host IP alias such as unifi-shim is required)- On macvlan networks the host's eth0 IP is unreachable — publish the bridge on an IP reachable from the Protect container's network (e.g. unifi-shim)
/stream.rawtriggers errors in ffmpeg's MJPEG decoder — use the multipart/streamendpoint for stability- Snapshots are unavailable for third-party cameras (known limitation)
- The ChangeVideoSettings "No response" warning is a known behavior common to all third-party cameras and does not affect recording
| File | Description |
|---|---|
supercamera_server.cpp |
MJPEG HTTP streaming server (port 8080) |
supercamera_capture.cpp |
Frame capture tool (saves JPEGs) |
deploy/supercamera.service |
systemd service unit |
deploy/99-supercamera.rules |
udev rule (USB permissions 0666) |
CC0 — protocol analysis builds on findings from hbens/geek-szitman-supercamera (CC0) and Tibiaworx/usee-plus-camera.