P2P camera system

@amitmund July 24, 2026

Building a P2P Camera System

Author: Personal Notes Prerequisites: - Python - Django - Networking Basics - Linux Server - Docker (Optional)


Goal

Create a system where

Camera -----> Internet
                 |
                 |
         Registration Server
                 |
          Mobile Application
                 |
                 |
        Direct Camera Connection

without manually configuring port forwarding.


High Level Architecture

                    +----------------------+
                    | Django Cloud Server  |
                    | Static IP            |
                    +----------+-----------+
                               |
             ------------------+------------------
             |                                     |
     Camera Registration                  Mobile App
             |                                     |
             +------------Handshake----------------+
                              |
                     STUN / TURN Server
                              |
                     NAT Hole Punching
                              |
                     Direct P2P Stream

The Django server is NOT responsible for video streaming.

It only performs

  • Device registration
  • Authentication
  • Signaling
  • Online status
  • Device discovery

Actual video goes directly between

Phone <---------> Camera

Components Required

1. Camera Device

Could be

  • Raspberry Pi
  • ESP32-CAM
  • Android Phone
  • IP Camera
  • Custom Linux Board

Requirements

  • Internet connection
  • Unique Device ID
  • Video Encoder
  • TCP/UDP sockets

2. Django Server

You already have

✔ Hosted Server ✔ Static IP

Responsibilities

  • User login
  • Device registration
  • JWT authentication
  • Device ownership
  • Online status
  • Push notifications
  • WebSocket signaling

Example Database

User

id
username
password

------------------------

Camera

id
uid
owner
last_ip
last_seen
online

------------------------

Session

id
camera
viewer
created_at
status

3. PostgreSQL

Store

  • Users
  • Cameras
  • Sessions
  • Tokens
  • Device Settings

4. Redis

Used for

  • WebSocket
  • Online status
  • Fast cache
  • Pub/Sub

5. Django Channels

Needed for

Realtime signaling

Phone
    |
WebSocket
    |
Django
    |
Camera

Messages

Offer
Answer
ICE Candidate
Heartbeat
Disconnect

6. STUN Server

Purpose

Find public IP and port.

Example

Camera

Private IP
192.168.0.22

↓

STUN

↓

Public IP

103.x.x.x:52342

Popular

  • coturn
  • Google's STUN
stun.l.google.com:19302

7. TURN Server

When P2P fails

Video passes through TURN.

Phone

↓

TURN Server

↓

Camera

Consumes bandwidth.

Recommended

Coturn


8. Video Streaming

Choices

MJPEG

Simple

Slow


RTSP

Most IP cameras

rtsp://camera/live

RTP

Professional

UDP based


WebRTC

Recommended

Supports

  • Video
  • Audio
  • NAT traversal
  • Encryption

Camera Boot Process

Camera Starts

↓

Generate UID

↓

Connect Internet

↓

Authenticate

↓

Send heartbeat every 30 seconds

↓

Wait for viewers

Heartbeat Example

{
    "uid":"ABC123",
    "ip":"192.168.1.22",
    "firmware":"1.0.0",
    "status":"online"
}

User Opens Mobile App

Login

↓

Load Camera List

↓

Select Camera

↓

Request Stream

Django Flow

User

↓

JWT

↓

Request Camera

↓

Find Camera

↓

Notify Camera

Camera Receives Request

Incoming Viewer

↓

Create WebRTC Offer

↓

Send SDP

↓

Exchange ICE

↓

Connect

NAT Hole Punching

Without P2P

Phone

↓

Cloud

↓

Camera

High latency.

With P2P

Phone

↓

Router

↓

Camera

Direct.


Signaling

Only signaling passes through Django.

Example

Phone

↓

Offer

↓

Django

↓

Camera

↓

Answer

↓

Django

↓

Phone

After that

Django is no longer involved.


WebRTC Objects

Offer

SDP

Answer

SDP

ICE Candidate

Possible network paths

Required Python Packages

Django

Django REST Framework

Django Channels

channels_redis

psycopg2

redis

PyJWT

uvicorn

gunicorn

django-cors-headers

Camera Software

Python

OpenCV

aiortc

asyncio

websockets

requests

or

C++

libwebrtc

OpenCV

FFmpeg

Video Encoding

Recommended

H264

Optional

H265

VP8

VP9

AV1

Authentication

Camera Login

UID

+

Secret Key

Example

POST

/api/device/login/

Returns

JWT Token

Device Registration

POST

/api/device/register/

Body

{
    "uid":"ABC123",
    "model":"ESP32",
    "firmware":"1.0"
}

Viewer Authentication

JWT

↓

Check Ownership

↓

Allow Stream

Heartbeat API

POST

/api/heartbeat/

Every

20-30 seconds

Django APIs

POST /login/

POST /register/

POST /device/register/

POST /heartbeat/

GET /device/list/

POST /request-stream/

POST /disconnect/

GET /ice-config/

POST /webrtc/offer/

POST /webrtc/answer/

WebSocket Messages

Offer

{
    "type":"offer",
    "sdp":"..."
}

Answer

{
    "type":"answer",
    "sdp":"..."
}

ICE

{
    "type":"candidate",
    "candidate":"..."
}

Security

Always

✔ HTTPS

✔ WSS

✔ JWT

✔ Device Secret

✔ AES (optional)

✔ DTLS

✔ SRTP


Production Stack

Ubuntu

Nginx

Gunicorn

Django

Redis

PostgreSQL

Coturn

Docker

Prometheus

Grafana

Scaling

Single Server

Django

Redis

Postgres

↓

Multiple Django

↓

Load Balancer

↓

Redis Cluster

↓

Multiple TURN Servers

↓

CDN (Optional)


Recommended Project Structure

camera_cloud/

    accounts/

    devices/

    signaling/

    streaming/

    api/

    websocket/

    heartbeat/

    permissions/

    notifications/

    utils/

    settings/

manage.py

Skills to Learn

Networking

  • TCP
  • UDP
  • NAT
  • Firewalls
  • STUN
  • TURN
  • ICE
  • WebRTC
  • RTP
  • RTSP

Backend

  • Django REST Framework
  • Django Channels
  • JWT
  • Redis
  • PostgreSQL

Streaming

  • FFmpeg
  • OpenCV
  • aiortc
  • GStreamer (optional)

Linux

  • Nginx
  • Docker
  • Systemd
  • Coturn

Minimum Viable Product (MVP)

Phase 1: - Django authentication - Camera registration - Heartbeats - Device list

Phase 2: - Django Channels signaling - WebSocket communication

Phase 3: - STUN integration - WebRTC connection

Phase 4: - Live video streaming

Phase 5: - TURN fallback

Phase 6: - Recording - Motion detection - Push notifications - Multi-camera dashboard - Firmware updates - Cloud backup


Final Architecture

                 +-------------------------+
                 |      Django Server      |
                 | REST + WebSocket + JWT  |
                 +-----------+-------------+
                             |
                     PostgreSQL
                             |
                           Redis
                             |
                      Django Channels
                             |
                      STUN / TURN (Coturn)
                             |
        ------------------------------------------------
        |                                              |
     Camera 1                                      Camera 2
        |                                              |
        +------------------- Internet -----------------+
                             |
                          Mobile App
                             |
                      Direct WebRTC Stream

Notes

  • Django should not carry the video stream in production. It is used for signaling, authentication, and device management.
  • WebRTC with STUN/TURN provides the best user experience for NAT traversal and encrypted, low-latency streaming.
  • For many concurrent users, deploy dedicated TURN servers because relay traffic can consume significant bandwidth.
0 Likes
110 Views
0 Comments

Filters

No filters available for this view.

Reset All