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
9 Views
0 Comments

Filters

No filters available for this view.

Reset All