Camera Access
Use USB and CSI cameras from WendyOS apps
Camera Access
Camera access is used for webcam streaming, computer vision, image capture, and ML inference pipelines. WendyOS keeps camera devices hidden from apps by default, so your project needs a camera entitlement before the app can open /dev/video*.
Add the entitlement from your project directory:
wendy project entitlements add cameraThe older video entitlement is still accepted for compatibility, but new projects should use camera.
Inspect Cameras on a Device
Use the device camera commands to see which cameras WendyOS can see:
wendy device camera listThe output includes a device ID, transport type (usb, csi, or ip), name, and — for local cameras — a path such as /dev/video0. Network cameras show their address instead of a path; see IP Cameras below. Use the ID with view commands:
wendy device camera view --id 0To request a specific stream shape:
wendy device camera view --id 0 --width 1280 --height 720 --fps 30If you want to pipe the encoded stream instead of opening a local preview window:
wendy device camera view --id 0 --stdoutFor broad hardware inspection, filter the device capability list:
wendy device hardware list --category cameraIP Cameras
WendyOS also manages network (RTSP/ONVIF) cameras alongside local USB and CSI ones. A discovered camera is registered by its MAC address — the one identity that survives a DHCP address change — and given a stable device ID from a reserved band, 200–255. That ID never changes for the life of the camera, even if its address does.
Cameras are picked up automatically as the agent's periodic discovery runs. To force a discovery round immediately and list the results in one step:
wendy device camera list --refreshNetwork cameras appear in the same camera list table as local ones, with ip in the Type column, the camera's address in the Where column, and a Status of needs login, offline, or ready.
Credentials
Most IP cameras require a login before they will stream. Store one with:
wendy device camera login <id>This prompts for the password without echoing it, or reads it from the WENDY_CAMERA_PASSWORD environment variable when there is no terminal to prompt on (for example, in CI). The username defaults to admin; pass --user to override it. Credentials are stored on the device and are never returned by any command.
Remove a camera and its stored credentials with:
wendy device camera forget <id>To validate a camera's stored login without starting a stream:
wendy device camera test <id>test dials the camera's RTSP port directly and reports one of three outcomes: the credentials were accepted, the camera rejected them (with a wendy device camera login <id> hint), or the camera was unreachable. One nuance worth knowing: a camera that never actually challenged for a login — no authentication required, or just a bad stream path — is still reported as success, with a detail like "did not request authentication; the stream path returned RTSP 404 and may be wrong" rather than claiming the credentials were verified.
wendy device camera view --id <id> works the same way for network cameras as for local ones. If no credentials are stored yet, it reads user/password from a camera entitlement in wendy.json if present, or prompts once interactively, before retrying the stream — see the camera entitlement fields for the wendy.json-based option and its plaintext-storage caveat.
Container Access
Apps with the camera entitlement (see Camera Entitlement) see network cameras exactly like local ones: each registered camera is mirrored into a /dev/video2xx loopback node numbered to match its own device ID — camera 212 is always /dev/video212 — and mounted into the container the same way USB and CSI devices are. A node is created before an entitled container starts; which containers currently count as consumers is kept in sync on every container start, stop, and delete, plus a periodic reconciliation roughly once a minute that catches anything those lifecycle hooks miss, such as a container's task crashing on its own.
The loopback node always carries the camera's sub-stream — the same lower-resolution feed camera view chooses automatically for anything ≤1024px wide. There is currently no way for a container to request the camera's main/high-resolution stream instead.
Builds without the kernel module: mirroring a camera into a container needs the v4l2loopback kernel module. On a WendyOS build that lacks it (or in local development), the agent logs this once and moves on:
running WendyOS build lacks the v4l2loopback module;
camera viewstill works
(that's the underlying sentinel error's own text; the agent's warning log line paraphrases it rather than quoting it verbatim.)
wendy device camera view and wendy device camera test are unaffected either way — only the in-container /dev/video2xx mirror is unavailable.
App Configuration
A minimal wendy.json camera app looks like this:
{
"appId": "com.example.camera",
"platform": "linux",
"version": "1.0.0",
"entitlements": [
{ "type": "camera" }
]
}To restrict the app to one camera device:
{
"type": "camera",
"allowlist": ["/dev/video0"]
}Common Pairings
Camera apps often also need:
networkfor HTTP or WebSocket video streamsgpufor NVIDIA Jetson inference or accelerated image processingpersistfor saving snapshots or clips
For a camera plus GPU app:
wendy project entitlements add camera
wendy project entitlements add gpuThen deploy:
wendy run
