A cloud-based video processing service with real-time monitoring, transcoding capabilities, and scalable architecture.
Features β’ Architecture β’ Quick Start β’ API Docs β’ Deployment
- Multi-Format Support: MP4, WebM, MOV, AVI, MKV, HLS, DASH
- Quality Preservation: Smart codec selection with "preserve original" mode
- Multi-Resolution Output: Adaptive bitrate streaming with custom resolutions
- Multi-Codec Support: H.264, H.265, VP8, VP9, AV1 codecs with CRF controls
- Video Filters: Crop, watermark overlay with opacity control
- Audio Extraction: Separate audio file generation
- Multi-Mode Support: Interval-based, custom timestamps, or both
- Sprite Sheets: Automatic generation for video players
- WebVTT Files: Timeline metadata for video scrubbing
- Custom Thumbnails: User-specified timestamp extraction
- WebSocket Integration: Live progress updates via Socket.IO
- Queue Management: Redis + BullMQ with retry logic and monitoring
- Phase-Based Progress: Dynamic progress tracking based on job complexity
- Auto-Reconnection: Client-side reconnection with exponential backoff
- Aethercure Integration: OAuth2 flow with Google authentication
- API Key Management: SHA-256 hashed keys with rate limiting
- Usage Analytics: Comprehensive API usage tracking
- Security Headers: Helmet.js with CORS configuration
- Bull Board Integration: Queue monitoring and management
- Comprehensive Logging: Winston-based structured logging
- Health Monitoring: System health checks for all services
- Automatic Cleanup: 1-hour TTL for processed files
- Graceful Shutdown: Proper resource cleanup on termination
VideoFlow employs a modern monolithic architecture with distributed processing capabilities, designed for high-throughput video transcoding with reliable performance.
graph TB
subgraph "Client Layer"
UI[React Frontend<br/>Vite β’ Socket.IO Client]
UI -->|HTTP + WebSocket| API
end
subgraph "API Gateway"
API[Express.js Server<br/>Port 3000]
API --> AUTH[Dual Authentication<br/>Aethercure + API Keys]
API --> RATE[Rate Limiting<br/>Express Rate Limit]
API --> VAL[Input Validation<br/>Joi Schemas]
end
subgraph "Application Layer"
CTRL[Controllers<br/>Request Handlers]
SERV[Services<br/>Business Logic]
QUEUE[BullMQ Queue<br/>Job Processing]
WS[WebSocket Service<br/>Real-time Updates]
end
subgraph "Processing Layer"
DOCKER[Docker Container<br/>FFmpeg Engine]
THUMB[Thumbnail Service<br/>Image Generation]
UPLOAD[Firebase Storage<br/>File Management]
end
subgraph "Data Layer"
MONGO[(MongoDB<br/>Job & User Data)]
REDIS[(Redis<br/>Queue Backend)]
STORAGE[(Firebase Storage<br/>File Assets)]
end
API --> CTRL
CTRL --> SERV
SERV --> QUEUE
SERV --> WS
QUEUE --> DOCKER
DOCKER --> THUMB
THUMB --> UPLOAD
SERV --> MONGO
QUEUE --> REDIS
UPLOAD --> STORAGE
classDef clientLayer fill:#e1f5fe
classDef apiLayer fill:#f3e5f5
classDef appLayer fill:#e8f5e8
classDef processLayer fill:#fff3e0
classDef dataLayer fill:#ffebee
class UI clientLayer
class API,AUTH,RATE,VAL apiLayer
class CTRL,SERV,QUEUE,WS appLayer
class DOCKER,THUMB,UPLOAD processLayer
class MONGO,REDIS,STORAGE dataLayer
| Layer | Technology | Purpose | Key Features |
|---|---|---|---|
| Frontend | React 19 + Vite | Modern UI with hot reload | WebSocket integration, responsive design |
| Backend | Node.js + Express | RESTful API server | Modular architecture, middleware pipeline |
| Database | MongoDB + Mongoose | Document storage & ODM | Flexible schema, built-in validation |
| Queue | Redis + BullMQ | Background job processing | Retry logic, job priorities, monitoring |
| Storage | Firebase Storage | Cloud file storage | Secure uploads, automatic cleanup |
| Processing | FFmpeg + Docker | Video transcoding engine | Containerized isolation, 100+ codecs |
| Auth | Aethercure + JWT | Authentication system | OAuth2, API keys, rate limiting |
| Monitoring | Winston + Bull Board | Logging & queue visualization | Structured logs, real-time monitoring |
Client Request β CORS & Security β Authentication β Rate Limiting β
Input Validation β Controller Logic β Service Layer β Database/Queue
File Upload β Download β Metadata Analysis β Transcoding β
Thumbnail Generation β Storage Upload β Cleanup β WebSocket Notification
const progressPhases = {
download: "2-5%", // Based on file size
metadata: "1%", // Video analysis
watermark: "1%", // Conditional processing
transcoding: "40-85%", // Complexity dependent
thumbnails: "8-15%", // Count dependent
audio: "5%", // Conditional extraction
upload: "5-15%", // Output size dependent
finalization: "2%" // Cleanup operations
}- Worker Pool: Configurable concurrency (default: 3 workers)
- Retry Logic: 3 attempts with exponential backoff
- Job Lifecycle: pending β processing β completed/failed
- Cleanup: Automatic removal of completed jobs (10 kept, 20 failed)
- Dual Auth: Aethercure OAuth2 + API Key system
- Rate Limiting: Configurable per-endpoint limits
- Input Validation: Joi schema validation
- Security Headers: Helmet.js configuration
- Upload: Firebase Storage with resumable uploads
- Processing: Local filesystem during transcoding
- Cleanup: Automatic removal after 1-hour TTL
- Storage: Permanent cloud storage for outputs
- Node.js 18+ with npm
- Docker and Docker Compose
- MongoDB instance
- Redis instance
- Firebase project with Storage enabled
git clone https://github.com/Vivek-4321/VideoFlow.git
cd VideoFlow# Install root dependencies
npm install
# Install client dependencies
cd client && npm install && cd ..
# Install server dependencies
cd server && npm install && cd ..Server Environment (server/.env):
# Database Configuration
MONGODB_URI=mongodb://localhost:27017/videoflow
# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
# Firebase Configuration
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
FIREBASE_CLIENT_EMAIL=your-service-account@your-project.iam.gserviceaccount.com
FIREBASE_STORAGE_BUCKET=your-bucket.appspot.com
# Authentication
AETHERCURE_CLIENT_ID=your-aethercure-client-id
AETHERCURE_CLIENT_SECRET=your-aethercure-client-secret
JWT_SECRET=your-jwt-secret-key
# Server Configuration
PORT=3000
NODE_ENV=development
CORS_ORIGIN=http://localhost:5173
WORKER_CONCURRENCY=3Client Environment (client/.env):
# API Configuration
VITE_API_BASE_URL=http://localhost:3000
VITE_WEBSOCKET_URL=http://localhost:3000
# Authentication
VITE_AETHERCURE_CLIENT_ID=your-aethercure-client-id
VITE_AETHERCURE_DOMAIN=your-aethercure-domain
# Firebase Configuration
VITE_FIREBASE_API_KEY=your-firebase-api-key
VITE_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your-project-id
VITE_FIREBASE_STORAGE_BUCKET=your-bucket.appspot.comOption A: Development Mode
# Start backend server
npm run dev:server
# Start frontend client (in another terminal)
npm run dev:clientOption B: Docker Compose
# Start all services
docker-compose up --build
# Access applications
# Frontend: http://localhost:5173
# Backend: http://localhost:3000
# Bull Board: http://localhost:3001# Test server health
curl http://localhost:3000/api/v1/health
# Test client access
open http://localhost:5173# Headers
Authorization: Bearer ak_your_api_key_here
Content-Type: application/json# Headers
Authorization: Bearer jwt_token_here
Content-Type: application/jsonCreate Transcoding Job
POST /api/v1/jobs
Content-Type: application/json
{
"inputUrl": "https://example.com/video.mp4",
"outputFormat": "mp4",
"outputOptions": {
"preserveOriginal": false,
"resolutions": [
{ "width": 1920, "height": 1080, "label": "1080p" },
{ "width": 1280, "height": 720, "label": "720p" }
],
"videoCodec": "h264",
"audioCodec": "aac",
"crop": {
"x": 0,
"y": 0,
"width": 1920,
"height": 1080
},
"watermark": {
"imageUrl": "https://example.com/watermark.png",
"position": "bottom-right",
"opacity": 0.7,
"scale": 0.1
},
"thumbnails": {
"enabled": true,
"mode": "both",
"interval": 30,
"customTimestamps": ["00:00:10", "00:01:30", "00:02:45"],
"generateSprite": true,
"generateVTT": true
}
}
}Get Job Status
GET /api/v1/jobs/{jobId}
Response:
{
"success": true,
"job": {
"id": "job_123",
"status": "processing",
"progress": 65,
"inputUrl": "https://example.com/video.mp4",
"outputUrls": [
{
"resolution": "1080p",
"url": "https://storage.googleapis.com/output_1080p.mp4"
}
],
"thumbnailUrls": {
"individual": ["https://storage.googleapis.com/thumb_1.jpg"],
"sprite": "https://storage.googleapis.com/sprite.jpg",
"vtt": "https://storage.googleapis.com/timeline.vtt"
},
"createdAt": "2024-01-15T10:30:00Z",
"completedAt": null,
"expiresAt": "2024-01-15T12:30:00Z"
}
}List User Jobs
GET /api/v1/jobs?page=1&limit=10&status=completed&sort=createdAt
Response:
{
"success": true,
"jobs": [...],
"pagination": {
"page": 1,
"limit": 10,
"total": 45,
"pages": 5
}
}Cancel Job
DELETE /api/v1/jobs/{jobId}
Response:
{
"success": true,
"message": "Job cancelled successfully"
}Create API Key
POST /api/v1/api-keys
Content-Type: application/json
{
"name": "My Application Key"
}
Response:
{
"success": true,
"apiKey": {
"id": "ak_1234567890abcdef",
"name": "My Application Key",
"key": "ak_1234567890abcdef1234567890abcdef",
"createdAt": "2024-01-15T10:30:00Z"
}
}List API Keys
GET /api/v1/api-keys
Response:
{
"success": true,
"apiKeys": [
{
"id": "ak_123",
"name": "My Application Key",
"lastUsed": "2024-01-15T10:30:00Z",
"usageCount": 150,
"isActive": true
}
]
}Get Usage Statistics
GET /api/v1/usage?period=7d&groupBy=day
Response:
{
"success": true,
"usage": {
"totalRequests": 1250,
"totalJobs": 89,
"avgResponseTime": 145,
"successRate": 98.4,
"breakdown": [
{
"date": "2024-01-15",
"requests": 180,
"jobs": 12,
"avgResponseTime": 156
}
]
}
}System Health Check
GET /api/v1/health
Response:
{
"success": true,
"status": "healthy",
"checks": {
"database": "connected",
"redis": "connected",
"workers": "3/3 active",
"storage": "accessible",
"queue": "processing"
},
"uptime": "2 days, 14 hours, 32 minutes"
}const socket = io('http://localhost:3000');
// Join user room
socket.emit('join-room', { userId: 'user123' });// Listen for job updates
socket.on('job-created', (data) => {
console.log('New job created:', data.jobId);
});
socket.on('job-progress', (data) => {
console.log(`Job ${data.jobId}: ${data.progress}%`);
});
socket.on('job-completed', (data) => {
console.log('Job completed:', data.jobId);
console.log('Output URLs:', data.outputUrls);
});
socket.on('job-failed', (data) => {
console.log('Job failed:', data.jobId);
console.log('Error:', data.error);
});version: '3.8'
services:
app:
build: .
environment:
- NODE_ENV=production
- MONGODB_URI=mongodb://mongodb:27017/videoflow
- REDIS_HOST=redis
depends_on:
- mongodb
- redis
volumes:
- ./uploads:/app/uploads
- ./logs:/app/logs
ports:
- "3000:3000"
mongodb:
image: mongo:7
volumes:
- mongodb_data:/data/db
restart: unless-stopped
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
mongodb_data:
redis_data:# Build production image
docker build -t videoflow:latest .
# Deploy with compose
docker-compose -f docker-compose.prod.yml up -d
# Monitor logs
docker-compose logs -f app# Required Production Variables
NODE_ENV=production
MONGODB_URI=mongodb+srv://user:pass@cluster.mongodb.net/videoflow
REDIS_HOST=redis.example.com
REDIS_PORT=6379
REDIS_PASSWORD=your-redis-password
# Firebase Configuration
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
FIREBASE_CLIENT_EMAIL=service-account@project.iam.gserviceaccount.com
FIREBASE_STORAGE_BUCKET=your-bucket.appspot.com
# Authentication
AETHERCURE_CLIENT_ID=your-client-id
AETHERCURE_CLIENT_SECRET=your-client-secret
JWT_SECRET=your-production-jwt-secret
# Performance
WORKER_CONCURRENCY=5
MAX_UPLOAD_SIZE=100mb# Horizontal scaling
WORKER_CONCURRENCY=10 # Increase worker count
REDIS_CLUSTER_MODE=true # Enable Redis cluster
MONGODB_REPLICA_SET=rs0 # Use replica set
# Performance optimization
NODE_OPTIONS="--max-old-space-size=4096"
UV_THREADPOOL_SIZE=16VideoFlow/
βββ client/ # React Frontend
β βββ src/
β β βββ components/ # React Components
β β β βββ Auth.jsx # Authentication
β β β βββ Dashboard.jsx # Main Dashboard
β β β βββ TranscodeSection.jsx # Video Processing
β β β βββ skeletons/ # Loading States
β β βββ hooks/ # Custom Hooks
β β β βββ useApi.js # API Hook
β β β βββ useDashboard.jsx # Dashboard Logic
β β β βββ useTheme.jsx # Theme Management
β β βββ services/ # API Services
β β β βββ apiService.js # HTTP Client
β β β βββ authService.js # Authentication
β β β βββ uploadService.js # File Upload
β β β βββ websocketService.js # WebSocket Client
β β βββ store/ # State Management
β β β βββ useAppStore.js # Global State
β β β βββ useToastStore.js # Toast Notifications
β β βββ styles/ # CSS Modules
β βββ package.json
β
βββ server/ # Node.js Backend
β βββ config/ # Configuration
β β βββ db.js # Database Connection
β β βββ firebase.js # Firebase Setup
β βββ controllers/ # Request Handlers
β β βββ jobController.js # Job Management
β β βββ queueController.js # Queue Operations
β β βββ apiKeyController.js # API Key Management
β β βββ healthController.js # Health Checks
β βββ middleware/ # Express Middleware
β β βββ auth.js # Authentication
β β βββ rateLimiter.js # Rate Limiting
β β βββ validator.js # Input Validation
β βββ models/ # Database Models
β β βββ job.js # Job Schema
β β βββ apiKey.js # API Key Schema
β β βββ apiUsage.js # Usage Analytics
β βββ routes/ # API Routes
β β βββ jobRoutes.js # Job Endpoints
β β βββ queueRoutes.js # Queue Endpoints
β β βββ apiKeyRoutes.js # API Key Endpoints
β βββ services/ # Business Logic
β β βββ jobProcessingService.js # Job Processing
β β βββ transcoder.js # Video Transcoding
β β βββ thumbnailService.js # Thumbnail Generation
β β βββ storage.js # File Storage
β β βββ websocketService.js # WebSocket Server
β βββ utils/ # Utilities
β β βββ logger.js # Logging
β β βββ ffmpeg.js # FFmpeg Utils
β β βββ docker.js # Docker Utils
β βββ server.js # Entry Point
β
βββ docker-compose.yml # Docker Configuration
βββ .gitignore # Git Ignore Rules
βββ package.json # Root Dependencies
βββ README.md # Documentation
# Start development servers
npm run dev:server # Backend with nodemon
npm run dev:client # Frontend with hot reload
npm run dev:both # Both servers concurrently
# Testing
npm run test:server # Backend tests
npm run test:client # Frontend tests
npm run test:e2e # End-to-end tests
# Code Quality
npm run lint # ESLint check
npm run lint:fix # Fix linting issues
npm run format # Prettier formatting
# Database
npm run db:migrate # Run migrations
npm run db:seed # Seed sample data
npm run db:reset # Reset database// controllers/newController.js
class NewController {
constructor(dependencies) {
this.service = dependencies.service;
}
async handleRequest(req, res) {
try {
const result = await this.service.process(req.body);
res.json({ success: true, data: result });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
}
}
module.exports = NewController;// components/NewComponent.jsx
import { useState, useEffect } from 'react';
import { useApi } from '../hooks/useApi';
const NewComponent = () => {
const [data, setData] = useState(null);
const { request } = useApi();
useEffect(() => {
const fetchData = async () => {
const result = await request('/api/v1/new-endpoint');
setData(result);
};
fetchData();
}, []);
return (
<div className="new-component">
{data ? <DataDisplay data={data} /> : <LoadingSkeleton />}
</div>
);
};
export default NewComponent;- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Install dependencies:
npm install - Start development servers:
npm run dev:both - Make your changes
- Write tests for new functionality
- Run tests:
npm test - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Submit a Pull Request
- Follow ESLint configuration
- Use Prettier for formatting
- Write descriptive commit messages
- Add JSDoc comments for functions
- Include unit tests for new features
- Include description of changes
- Link to related issues
- Ensure all tests pass
- Update documentation if needed
- Add screenshots for UI changes
This project is licensed under the MIT License - see the LICENSE file for details.
- FFmpeg - Video processing engine
- Bull - Redis-based queue
- Socket.IO - Real-time communication
- Firebase - Authentication & Storage
- React - Frontend framework
Built with β€οΈ for the developer community
Website β’ Documentation β’ Support