Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DRM Server - Node.js

A Digital Rights Management (DRM) video server built with NestJS that handles secure video uploads, automatic HLS transcoding with adaptive bitrate streaming, and video delivery.

Features

  • Video Upload - Multipart file upload with MIME type validation and secure file naming
  • HLS Transcoding - Automatic conversion to HTTP Live Streaming format with 5 quality renditions (240p to 1080p)
  • Adaptive Bitrate Streaming - Multi-bitrate master playlists for seamless quality switching
  • Async Processing - Background transcoding jobs via Bull queue backed by Redis
  • Clean Architecture - Domain-driven design with separated application, domain, and infrastructure layers

Architecture

┌──────────────────────────────────────┐
│  Presentation (Controllers, DTOs)    │
├──────────────────────────────────────┤
│  Application (Use Cases)             │
├──────────────────────────────────────┤
│  Domain (Entities, Repositories)     │
├──────────────────────────────────────┤
│  Infrastructure (Prisma, Storage,    │
│  FFmpeg, Bull Queues)                │
└──────────────────────────────────────┘

Request flow:

Upload → Controller → UseCase → StorageProvider (save file)
                              → VideoRepository (save metadata)
                              → Bull Queue (enqueue transcoding)
                                    ↓
                              FFMPEGTranscode Processor (async)
                                    ↓
                              HLS segments + master playlist

Tech Stack

Layer Technology
Framework NestJS 9
Language TypeScript
Database MySQL 8.0 + Prisma ORM
Queue Bull + Redis
Transcoding FFmpeg (fluent-ffmpeg)
Streaming HLS (HTTP Live Streaming)
Upload Multer

HLS Renditions

Videos are transcoded into 5 adaptive bitrate renditions:

Resolution Bitrate
426x240 400 kbps
640x360 800 kbps
842x480 1.4 Mbps
1280x720 2.8 Mbps
1920x1080 5.0 Mbps

Segments are 10 seconds each, encoded with H.264 video and AAC audio.

Prerequisites

  • Node.js >= 16
  • Yarn or npm
  • FFmpeg installed and available in PATH
  • Docker & Docker Compose (for MySQL and Redis)

Getting Started

1. Start infrastructure services

docker compose up -d

This starts:

  • MySQL 8.0 on port 3306
  • Redis on port 6379

2. Configure environment

cd upload-videos
cp .env.example .env

Edit .env with your values:

FILESYSTEM_DISK=local
DATABASE_URL="mysql://root:YOUR_PASSWORD@127.0.0.1:3306/videos?schema=public"
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=YOUR_REDIS_PASSWORD

3. Install dependencies

cd upload-videos
yarn install

4. Run database migrations

npx prisma migrate dev

5. Start the server

# Development (watch mode)
yarn start:dev

# Production
yarn build
yarn start:prod

The server starts on http://localhost:3000 with CORS enabled.

API Endpoints

Upload Video

POST /
Content-Type: multipart/form-data
Field Type Required Description
clientId UUID Yes Client identifier
title String Yes Video title (5-100 characters)
video File Yes Video file

Example:

curl -X POST http://localhost:3000 \
  -F "clientId=550e8400-e29b-41d4-a716-446655440000" \
  -F "title=My Video" \
  -F "video=@/path/to/video.mp4"

The upload triggers an async HLS transcoding job. The video metadata is returned immediately while processing happens in the background.

Stream Video

GET /stream/:folder/:fileName
Param Description
folder Video ID / folder name
fileName M3U8 playlist or .ts segment file

Example:

# Master playlist
curl http://localhost:3000/stream/{videoId}/master.m3u8

# Video segment
curl http://localhost:3000/stream/{videoId}/720p_000.ts

Project Structure

upload-videos/
├── prisma/                     # Database schema & migrations
│   └── schema.prisma
├── src/
│   ├── main.ts                 # App entry point
│   ├── app.module.ts           # Root module
│   ├── application/
│   │   ├── entities/           # Domain entities
│   │   ├── repositories/       # Repository interfaces
│   │   └── use-cases/          # Business logic
│   ├── config/
│   │   └── upload.ts           # Multer configuration
│   ├── helpers/                # Validators & utilities
│   ├── infra/
│   │   ├── database/           # Prisma service & repositories
│   │   ├── http/               # Controllers, DTOs, ViewModels
│   │   ├── processors/         # Bull queue job processors
│   │   └── providers/          # Storage providers
│   └── ...
├── create-hls-vod.sh           # FFmpeg HLS transcoding script
├── package.json
└── docker-compose.yml

File Storage Layout

Uploaded and processed files are organized as:

uploads/
└── {clientId}/
    ├── {original-video}.mp4
    └── chunks/
        ├── master.m3u8          # Master playlist
        ├── 240p.m3u8            # Rendition playlists
        ├── 360p.m3u8
        ├── 480p.m3u8
        ├── 720p.m3u8
        ├── 1080p.m3u8
        └── {resolution}_000.ts  # Video segments

Scripts

Command Description
yarn start Start the application
yarn start:dev Start in watch mode
yarn start:prod Start compiled production build
yarn build Compile TypeScript to dist/
yarn lint Run ESLint
yarn test Run unit tests
yarn test:e2e Run end-to-end tests
yarn test:cov Run tests with coverage

License

Private

About

drm-services

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages