Skip to main content

RustCam

Developers

RustCam requirements, project layout, quick start, configuration, API overview and FAQ.

Environment

Rust

1.95+

PostgreSQL

14+ (PostGIS extension required)

TimescaleDB

PostgreSQL extension (telemetry series)

Redis

6+

Node.js

18+ (frontend build)

ZLMediaKit

Any recent version (ingest / pull / relay)

Qt + CMake

Qt 5.15.2 / 6.2+, CMake 3.16+ (desktop client only)

Project layout

crates/rustcam-media/Rust backend library: api / application / auth / domain / infrastructure / protocol / transport / drone_gateway
crates/rustcam-server/Server binary (rustcam-media)
crates/rustcam-drone-service/Mobile Eye control plane: registry, telemetry shadow, leases, commands, geofences, audit
crates/rustcam-drone-adapter/Airborne adapter: MAVLink / PX4 / ArduPilot
crates/rustcam-drone-sim/MAVLink vehicle simulator for tests and demos
crates/rustcam-drone-proto/Mobile Eye gRPC contract
crates/rustcam-drone-core/Shared types and constants
frontend/Vue 3 console (Vite + Element Plus + Pinia + Cesium)
testenv/One-command Mobile Eye test environment (start.ps1 / stop.ps1 / screenshots)
clientapp/Qt desktop client (CMake + FFmpeg)
public/Public docs: api.md, architecture.mmd, architecture.png
sql/Database scripts (schema.sql)

Quick start

Initialise the database

bash
psql -U postgres -c "CREATE DATABASE rustcam;"
psql -U postgres -d rustcam -f sql/schema.sql

Start the backend

bash
cargo run -p rustcam-server
# or a release build
cargo build --release -p rustcam-server
./target/release/rustcam-media

Start the web console

bash
cd frontend
npm install
npm run dev

One-command Mobile Eye test environment

powershell
pwsh -File testenv\start.ps1
# login: admin / admin123
# built-in MAVLink simulator: PX4 / ArduPilot

Log in and get a token

bash
curl -s -X POST http://127.0.0.1:8081/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"admin"}'

Configuration file

Edit config.toml at the repository root. The block below is the minimal configuration that actually starts: server, database, redis, media_servers, cluster, session, onvif, rtsp_auth, signaling_server and jwt are all required, and the backend refuses to start without them. Always change the JWT secret and database password in production.

toml
[server]
host = "0.0.0.0"
port = 8081
tls_enabled = false

[database]
url = "postgres://user:pass@localhost:5432/rustcam"
max_connections = 10

[redis]
url = "redis://localhost:6379"
pool_size = 5

[[media_servers.servers]]
name = "zlmediakit"
url = "http://127.0.0.1:80"
api_key = "your_api_key"
server_type = "zlmediakit"   # zlmediakit / srs / xiu
weight = 100
enabled = true
server_tag = "default"

[cluster]
strategy = "round_robin"
health_check_interval_secs = 30
max_session_per_server = 1000

[session]
expiration_secs = 300
max_per_user = 10

[onvif]
discovery_enabled = false
scopes = ["onvif://www.onvif.org/Profile/Streaming", "onvif://www.onvif.org/Profile/PTZ"]

[rtsp_auth]
enabled = true
realm = "RustCam"

[signaling_server]
server_gb_id = "31011500001000000001"
server_gb_domain = "3101150000"
bind_ip = "0.0.0.0"
tcp_signaling_port = 5060
udp_signaling_port = 5061
rtp_port_start = 15000
rtp_port_end = 15100
rtp_bind_addr = "0.0.0.0"

[jwt]
secret = "change-me-in-production"
access_token_expire_minutes = 60
refresh_token_expire_days = 30

[drone]
service_addr = "http://127.0.0.1:50051"

API overview

The Axum backend exposes HTTP + WebSocket endpoints under the /api/v1 prefix, grouped by users and permissions, devices and channels, PTZ, streams, recording, alarms, video walls and the Mobile Eye. The complete list lives in public/api.md in the repository.

Authentication

Every endpoint except the public ones requires a JWT in the request header: Authorization: Bearer <access_token>

http
Authorization: Bearer <access_token>

Endpoint groups

GroupCountEndpoints
Users / roles / permissions11GET/POST /users, PUT /users/{id}/roles, GET/POST /roles
Devices13GET/POST /devices, POST /devices/{id}/play, GET /devices/{id}/config
Channels7GET/POST /channels, GET /channels/{device_tag}/{channel_tag}/status
PTZ6POST /channels/{d}/{c}/ptz, GET/POST/PUT/DELETE .../ptz/presets
Streams9GET/POST /streams, GET /streams/{id}/play, POST /streams/{id}/restart
Recording tasks10GET/POST /recordings, POST /recordings/{id}/start|stop|pause|resume
Recording policies5GET/POST /recording-policies, PUT/DELETE /recording-policies/{id}
Media servers10GET/POST /servers, GET /servers/{tag}/status, POST /servers/{tag}/enable
Video wall layouts6GET/POST /layouts, PUT /layouts/{id}/default
Device groups / regions8GET /groups/tree, POST /groups, GET /regions/tree
ONVIF6POST /onvif/discover, POST /onvif/probe, POST /onvif/devices
Mobile Eye (drone)19GET/POST /drone/drones, POST /drone/{id}/command, GET/POST /drone/routes, GET/POST /drone/fences, POST /drone/control/acquire
Sessions / alarms / stats5GET /sessions, GET /alarms, GET /api/v1/stats

Public routes (no authentication)

POST /api/v1/auth/login, /auth/refreshLogin / token refresh
GET /api/v1/health, /metrics, /statsHealth / metrics / stats
GET /api/v1/public/streamsPublic live streams
GET /api/v1/proxy/wfsMap WFS proxy
POST /hook/{event_name}, /hook/{server_type}/{event_name}Media server hooks
POST /alarm/{stream_key}External alarm intake
GET /ws, /ws/audio-talk/{device_tag}/{channel_id}Event push and two-way talk
GET /ws/drone/{kind}?ticket=...Mobile Eye event push with a one-time ticket

FAQ

How are devices onboarded?

Through GB28181 SIP registration, ONVIF WS-Discovery, direct RTSP or WebSocket — all unified into one device and channel model.

What happens when a PTZ device is offline?

GB28181 returns 503 and the adapter automatically re-registers the device.

Is HTTPS supported?

Yes, but the backend has no built-in TLS listener: put a reverse proxy (Nginx, for example) in front of it to terminate TLS. WSS uses the same entry point, so the proxy must allow WebSocket upgrades.

How does two-way talk work?

The MediaNode middleware chain performs G711 ⇄ PCM conversion and resampling, backing GB28181 broadcast and ONVIF Backchannel talk.

Can I try the Mobile Eye without drone hardware?

Yes. The repository ships rustcam-drone-sim, which simulates PX4 / ArduPilot heartbeats, telemetry and command ACKs. Run pwsh -File testenv\start.ps1 to launch the simulator, adapter, control plane, server and web console.

Which flight controllers are supported?

PX4 and ArduPilot over MAVLink, detected automatically from HEARTBEAT.autopilot, with UDP / TCP / serial links.

When will other media servers be available?

The media server adapter is ready; some integrations are still partially implemented — see the module progress table on the features page.