Turn a Raspberry Pi into a CCTV-style camera system using Anedya for signaling and TURN relay provisioning, and WebRTC for real-time video delivery.
- Live WebRTC video streaming : low-latency peer-to-peer video using Anedya-managed STUN/TURN
- Local Recording : continuous MP4 segments written to disk on the Pi
- Playback : scrub through past footage from the viewer without any server-side transcoding
- Automatic max camera mode : selects the highest usable camera capability for both live streaming and local recording
- Motion detection overlay : bounding boxes drawn on detected motion regions in real time
- Microphone audio : capture and stream Pi microphone audio alongside video
- Web viewer : browser-based viewer, no install required
- Mobile viewer : Flutter app for Android and iOS
WebRTC requires both peers to exchange SDP offers and answers before media can flow. This example uses Anedya ValueStore as a signaling channel and Anedya MQTT as the notification mechanism.
Peer App
│ 1. Fetch TURN credentials (Anedya REST API)
│ 2. Create WebRTC offer + write offer_<sessionId> to ValueStore
▼
Anedya Cloud (ValueStore + MQTT broker + TURN relay)
│ 3. Notify Pi over MQTT subscription
▼
Pi Streamer
│ 4. Create WebRTC answer + write answer_<sessionId> to ValueStore
▼
Peer App
│ 5. Poll ValueStore → read answer → apply remote description
│ 6. ICE negotiation completes
│ 7. Media flows (video + audio) — DataChannel for playback controls
When both peers are on the same network, ICE resolves a direct path using STUN address discovery:
When a firewall blocks direct peer-to-peer traffic, Anedya's managed TURN relay is used automatically:
The Pi records continuously into configurable MP4 segments on disk. The default segment duration is 5 seconds and can be changed with RECORDING_SEGMENT_SECONDS. Finalized recordings are kept for 7 days by default; change this with RECORDING_RETENTION_DAYS, RECORDING_RETENTION_HOURS, or RECORDING_RETENTION_SECONDS for short test windows. The viewer receives a timeline over the WebRTC DataChannel and can seek into any finalized segment using the same data channel; the Pi reads and streams the file directly.
.
├── peer/ — browser viewer (static HTML + Node.js dev server)
│ └── public/
│ └── index.html
├── peer_app/ — Flutter mobile viewer (Android / iOS)
│ └── lib/
│ ├── main.dart
│ ├── peer_cam_screen.dart
│ └── qr_code_scanner.dart
└── streamer/ — Pi device app (Python)
├── config.py — credentials, constants, logging
├── recording.py — rolling MP4 segment writer
├── camera.py — capture loop, motion detection, timestamp overlay
├── tracks.py — WebRTC video and audio tracks
├── camera_streamer.py — MQTT signaling, peer connection handling
└── main.py — CLI entrypoint
Hardware
- Raspberry Pi with network access (any model with USB or CSI camera support)
- USB/UVC webcam (recommended) or CSI camera module
- Optional: USB microphone for audio
Software / Accounts
- Sign in at Anedya Console.
- Create a new project.
- Create a node for your Pi camera and pre-authorize it with a UUID.
- Note down these values, you will need them in Step 3:
| Value | Where to find it |
|---|---|
ANEDYA_DEVICE_ID |
Node details → Device ID |
ANEDYA_NODE_ID |
Node details → Node ID |
ANEDYA_CONNECTION_KEY |
Node details → Connection Key |
- Generate a Platform API key for the viewer app.
Tip
See Anedya Project Setup for a step-by-step walkthrough of the console.
Clone on the Raspberry Pi:
git clone https://github.com/anedyaio/anedya-camera-livestream-example.git
cd anedya-camera-livestream-exampleCreate the local credentials file from the example:
cp streamer/.env.example streamer/.envEdit streamer/.env and fill in your values:
ANEDYA_DEVICE_ID=your-device-uuid
ANEDYA_NODE_ID=your-node-uuid
ANEDYA_CONNECTION_KEY=your-connection-key
ANEDYA_REGION=ap-in-1
RECORDING_SEGMENT_SECONDS=5
RECORDING_RETENTION_DAYS=7
RECORDING_RETENTION_HOURS=0
RECORDING_RETENTION_SECONDS=Install uv if not already present:
curl -LsSf https://astral.sh/uv/install.sh | shInstall Python dependencies:
cd streamer
uv syncIf you want microphone audio on Raspberry Pi OS or Debian, install the system PortAudio runtime before starting the streamer:
sudo apt install libportaudio2This is only required for audio. Video-only mode works without PortAudio by
running the streamer with --no-audio.
uv run streamerOptions:
uv run streamer --camera 1 # use a different camera device index
uv run streamer --no-audio # disable microphone
uv run streamer --record-path /mnt/recordings # custom recording directoryA hosted version is available at: anedyaio.github.io/anedya-camera-livestream-example
Or run it locally on your PC/Mac:
cd peer
npm install
npm startOpen http://localhost:8080 in your browser, then:
- Click Settings
- Enter your Node ID and Platform API key
- Click Start Stream
Download the latest APK from GitHub Releases and install it on your Android device.
Or build from source:
cd peer_app
flutter pub get
flutter runIn the app,
- Click Settings
- Enter your Node ID and Platform API key
- Click Start Stream
After the first segment is finalized, a timeline scrubber appears in the viewer. Drag it to seek into recorded footage. The Pi streams frames from the MP4 files directly using the same WebRTC connection by switching the frames it yields; no upload or cloud storage involved.
This project uses OpenCV VideoCapture.
- USB/UVC webcams work out of the box on most Pi setups.
- CSI cameras (Pi Camera Module): ensure the camera is enabled in
raspi-configand test withlibcamera-stillbefore running the streamer. - Linux / Raspberry Pi: the streamer uses
linuxpyto enumerate V4L2 camera modes, selects the highest usable resolution/FPS mode, then applies that mode to OpenCV. - Windows: the streamer uses FFmpeg DirectShow mode listing through
imageio-ffmpegwhen available, then applies the selected mode to OpenCV. - If capability discovery fails on either platform, the streamer falls back to OpenCV resolution probing.
- The selected capture mode is shared by both the WebRTC live stream and the MP4 recorder.
- If capture fails on index
0, try--camera 1or checkls /dev/video*.
Anedya
- Anedya Overview
- Anedya Concepts
- Anedya Project Setup
- Anedya MQTT Endpoints
- Anedya ValueStore
- Anedya Platform API
WebRTC
Tooling
This project is licensed under the Apache License 2.0.





