A production-grade, containerized, cloud-scale Video Processing & Transcoding System designed with an ultra-premium Obsidian Glassmorphic dashboard. NebulaStream features direct webcam/microphone recording, remote stream URL ingestion (HLS / HTTP direct link), custom text watermarking, audio track extraction, and dynamic thumbnail generation.
+------------------------------------+
| Next-Gen React SPA Client |
| (Obsidian Glassmorphism UI) |
+---+--------------+--------------+--+
^ ^ ^
Drag-Drop File | Live WebM | Stream URL | HTTP / SSE
Uploads | Recording | Ingestion | Progress
v v v
+---+--------------+--------------+--+
| Express Backend API |
+---+--------------+--------------+--+
| | |
Prisma Client | | | Dispatch BullMQ Job
v | v
+-------------+----+ | +-------+----------+
| MongoDB Atlas | | | ElastiCache / |
| (Data Store) | | | Redis Cluster |
+------------------+ | +------------------+
| ^
| | Pop Task
Serve | Upload v
Assets | Outputs +----+-------------+
v | |
+-----------+-------+ | FFmpeg Job |
| AWS S3 Bucket |<=+ Fargate Worker |
| (Cloud Storage) | | |
+-------------------+ +------------------+
- Dashboard Client (React + Vite): Powered by a dark obsidian glassmorphism design system. Integrates tabbed navigation for a Video Library, a live Webcam Recording Studio, and a Stream Import Deck. Uses a custom media player that preserves playback timestamps during resolution switches.
- Backend API (Express & Prisma): Ingests multipart video files, coordinates remote stream URLs, updates database structures, and handles streaming real-time queue metrics via Server-Sent Events (SSE).
- Queue Broker (Redis & BullMQ): Manages concurrent background tasks, prevents system overload, and provides reliable worker scheduling with exponential backoff retry algorithms.
- FFmpeg Job Worker: A multi-threaded background service. Ingests local files or streams remote HLS
.m3u8playlists directly from the network, encodes multiple resolutions/containers, embeds text watermarks, isolates audio tracks, generates snapshot thumbnails, and pipes transcoded assets to AWS S3.
- Bespoke obsidian black color palette (
#030712) with glowing ambient highlights (radial neon gradients). - Blended glassmorphism cards (
rgba(17, 24, 39, 0.45)) featuring high-contrast borders and intense backdrop filters (blur(20px)). - Collapsible sidebar menu navigation with active glow states and live processing badges.
- Real-time enumeration of connected cameras and microphones directly in the browser.
- Audio/video capturing via browser
MediaRecorderAPI (VP9/VP8 WebM codecs). - Studio overlays including flashing
RECindicators, monospaced countdown timers, and recording feedback loop. - Local playback review player, custom metadata forms (title/description), and automated multi-part upload pipeline.
- Supports public HTTP files (
.mp4,.webm) and Apple HTTP Live Streaming (.m3u8) playlists. - Ingestion checks MIME types (
application/x-mpegURLfor streams) and bypasses storage overhead. - Background worker feeds remote stream URLs straight into FFmpeg inputs, decoding from network packets.
- Graceful metadata fallbacks for live feeds without predefined durations, skipping thumbnail extraction.
d:\VIDEO PROCESSING SYSTEM\
βββ backend/ # REST API Server (Express + TypeScript + Prisma)
β βββ prisma/ # Database client schemas
β βββ src/
β β βββ config/ # DB, Storage drivers, Redis connections
β β βββ routes/ # Video endpoints & SSE stream handlers
β β βββ server.ts # Server bootstrapping
β βββ Dockerfile
βββ worker/ # Processing Worker (BullMQ + FFmpeg)
β βββ prisma/ # Worker database models
β βββ src/
β β βββ config/ # DB & S3 configurations
β β βββ processor.ts # Stream detector, FFmpeg wrapper, thumbnailer
β β βββ index.ts # BullMQ queue listener
β βββ Dockerfile
βββ frontend/ # Client SPA Dashboard (React + Vite + Vanilla CSS)
β βββ src/
β β βββ components/ # Custom player with resolution selectors
β β βββ App.jsx # Sidebar layout, webcam booth & stream import
β β βββ index.css # Glassmorphic Obsidian design tokens
β β βββ main.jsx
β βββ index.html
β βββ vite.config.js
β βββ Dockerfile
βββ docker-compose.yml # Multi-service local setup orchestration
- Docker and Docker Compose installed.
- Camera and microphone access permissions (if testing local Webcam Recorder).
Build the Docker environment and spin up all local services (MongoDB, Redis, API, Worker, Client) with one command from the project root:
docker-compose up --build- Web Dashboard: http://localhost:3000
- API Server: http://localhost:5000
- Local MongoDB:
localhost:27017 - Local Redis:
localhost:6379
Note
In local development mode (STORAGE_TYPE=local), a shared volume shared_uploads is mounted at /app/uploads across backend and worker containers to simulate cloud storage blocks locally.
To deploy the API and Worker containers to AWS ECS Fargate and leverage AWS S3 for storage, configure the following variables in your .env.production file:
# Database & Broker
DATABASE_URL="mongodb+srv://<user>:<password>@cluster0.mongodb.net/nebulastream"
REDIS_URL="rediss://<elasticache-redis-tls-endpoint>:6379"
# Storage Configuration
STORAGE_TYPE="s3"
AWS_REGION="eu-north-1"
AWS_S3_BUCKET="nebulastream-assets"
AWS_ACCESS_KEY_ID="AKIAxxxxxxxxxxxx"
AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"Important
- ElastiCache Transit Encryption: Secure Redis connections on AWS require
rediss://protocol configurations to prevent socket timeouts. - ECR Workflows: Pipeline repository creators use
aws ecr create-repository --repository-name $ECR_REPOSITORY || truechecks to prevent rolling workflow crashes.
- Endpoint:
POST /api/videos/upload - Content-Type:
multipart/form-data - Fields:
video(file binary): The video asset (max 500MB).title(string): Optional title.description(string): Optional description.
- Response (Status
201 Created):{ "id": "603dcae32c81d31a54b9d09a", "title": "NebulaStream Introduction", "description": "Cloud system demo", "originalName": "intro.mp4", "mimeType": "video/mp4", "size": 12459023, "duration": null, "originalPath": "originals/1709483829102-intro.mp4", "streamUrl": null, "status": "UPLOADED", "progress": 0 }
- Endpoint:
POST /api/videos/import-url - Content-Type:
application/json - Body:
{ "url": "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4", "title": "Bigger Blazes Network Stream", "description": "Public sample HTTP stream" } - Response (Status
201 Created):{ "id": "603dcae32c81d31a54b9d09b", "title": "Bigger Blazes Network Stream", "description": "Public sample HTTP stream", "originalName": "Network Stream", "mimeType": "video/mp4", "size": 0, "duration": null, "originalPath": "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4", "streamUrl": "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4", "status": "UPLOADED", "progress": 0 }
- Endpoint:
POST /api/videos/:id/process - Content-Type:
application/json - Body:
{ "resolutions": ["1080p", "720p", "480p"], "formats": ["mp4", "webm"], "watermarkText": "NEBULASTREAM INTERNAL", "extractAudio": true, "thumbnailsCount": 3 } - Response (Status
200 OK):{ "message": "Video added to processing queue", "status": "QUEUED" }
- Endpoint:
GET /api/videos/:id/progress-stream - Content-Type:
text/event-stream - Response: Streams SSE messages every 1 second updating the transcoding state:
Streams close automatically upon transition to
{ "status": "PROCESSING", "progress": 42, "error": null, "assets": [] }COMPLETEDorFAILED.
- Endpoint:
GET /api/videos - Response (Status
200 OK): Returns JSON array of all video metadata objects along with their mapped output resolution asset keys.
- Endpoint:
DELETE /api/videos/:id - Response (Status
200 OK): Cancels active jobs in Redis, purges all stored S3 artifacts (resolutions, audio, thumbnails) and deletes references in MongoDB.
This section provides an architectural blueprint for integrating live, automated recording and processing of webcam streams of students taking examinations online.
Integrate a background recording component on the exam page that manages permissions, chunk uploads, and browser events:
- Background Chunking: Periodically record and save the stream to disk or memory, uploading chunks every 2β3 minutes via standard multipart requests or directly to S3 via presigned URLs. This protects recordings from internet drops or browser crashes.
- Cheating Event Logs: Attach event listeners for
visibilitychange(tab switches),resize(leaving fullscreen mode), and audio activity to construct a side-channel time-log of flagged events.
Extend the schema.prisma models to track the audit timeline:
model ExamRecording {
id String @id @default(auto()) @map("_id") @db.ObjectId
studentId String
examId String
videoUrl String?
status String // UPLOADED | PROCESSING | COMPLETED | FAILED
createdAt DateTime @default(now())
flags ProctorFlag[]
snapshots AuditSnapshot[]
}
model ProctorFlag {
id String @id @default(auto()) @map("_id") @db.ObjectId
examRecordingId String @db.ObjectId
examRecording ExamRecording @relation(fields: [examRecordingId], references: [id], onDelete: Cascade)
timestamp Int // Elapsed seconds in video
eventType String // TAB_SWITCH | FULLSCREEN_EXIT | NO_FACE_DETECTED
severity String // LOW | MEDIUM | HIGH
}
model AuditSnapshot {
id String @id @default(auto()) @map("_id") @db.ObjectId
examRecordingId String @db.ObjectId
examRecording ExamRecording @relation(fields: [examRecordingId], references: [id], onDelete: Cascade)
timestamp Int
imageUrl String
}- Visual Proctor Watermark: Use the FFmpeg
drawtextfilter to burn in student metadata, IP address, and absolute UTC timestamps for anti-tamper compliance. - Audit Frame Extraction: Configure the worker to automatically extract review snapshots (e.g. 1 frame every 10 seconds) to feed downline facial-verification models or proctor review timelines:
ffmpeg -i input.mp4 -vf "fps=1/10" -q:v 2 audit_snapshots/thumb_%04d.jpg - Storage Preservation: Run high-efficiency transcoding pipelines (e.g. 480p H.264 at a low constant rate factor like
crf 28) to archive hour-long exams with minimal S3 footprint.
- Build an admin audit board displaying flagged students, logs, and a timeline of snapshots.
- Build a custom review player that syncs the video playback time directly with the flagged cheating event timestamps, allowing proctors to jump straight to suspect intervals.