Skip to content

Latest commit

Β 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎬 Video Streaming System

A lightweight, production-ready video streaming platform for playing large remote video files (MKV/MP4) from CDN URLs. Features a modern OTT-style player with advanced controls, multi-audio/subtitle support, and instant progressive streaming.

✨ Features

Backend

  • βœ… HTTP Range request forwarding
  • βœ… CDN streaming proxy
  • βœ… Support for large files (multi-GB)
  • βœ… Automatic retry on timeout
  • βœ… Token expiry handling (401/403)
  • βœ… CORS enabled
  • βœ… Rate limiting protection
  • βœ… No transcoding overhead

Frontend Player

  • βœ… Video.js based player
  • βœ… Instant playback with progressive streaming
  • βœ… 10-second skip forward/backward
  • βœ… Timeline scrubbing with preview
  • βœ… Multiple audio track switching
  • βœ… Subtitle track support
  • βœ… Quality selector (720p/1080p)
  • βœ… Playback speed control (0.25x - 2x)
  • βœ… Volume control with slider
  • βœ… Fullscreen support
  • βœ… Auto-resume from last position
  • βœ… Modern OTT-style dark UI
  • βœ… Keyboard shortcuts
  • βœ… Mobile responsive

Keyboard Shortcuts

  • Space / K - Play/Pause
  • ← - Rewind 10 seconds
  • β†’ - Forward 10 seconds
  • F - Toggle fullscreen
  • M - Mute/Unmute
  • ↑ - Increase volume
  • ↓ - Decrease volume

πŸ—οΈ Architecture

User Browser
    ↓
React Frontend (Video.js Player)
    ↓
Node.js Express Proxy (HTTP Range forwarding)
    ↓
CDN (Video Files)

Flow:

  1. User pastes CDN video URL
  2. Frontend requests video through proxy
  3. Proxy forwards Range requests to CDN
  4. Video streams directly to browser
  5. Player buffers and plays progressively

πŸ“‹ Prerequisites

  • Node.js 16+
  • npm or yarn
  • Modern web browser with HTML5 video support

πŸš€ Quick Start (Local Development)

1. Clone or Download

cd video-streaming-system

2. Setup Backend

cd backend
npm install
cp .env.example .env
npm start

Backend will start on http://localhost:3001

3. Setup Frontend

cd frontend
npm install
cp .env.example .env
npm start

Frontend will start on http://localhost:3000

4. Open Browser

Navigate to http://localhost:3000 and paste your video URL!

πŸ“¦ Production Deployment (Single VPS)

Method 1: Manual Deployment

1. Prepare Your VPS

# Update system
sudo apt update && sudo apt upgrade -y

# Install Node.js (using NodeSource)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

# Install Nginx
sudo apt install -y nginx

# Install PM2 (process manager)
sudo npm install -g pm2

2. Upload Code to VPS

# On your local machine
scp -r video-streaming-system user@your-server-ip:/home/user/

# Or use git
ssh user@your-server-ip
cd /home/user
git clone your-repo-url video-streaming-system

3. Setup Backend

cd /home/user/video-streaming-system/backend
npm install --production
cp .env.example .env

# Edit .env if needed
nano .env

# Start with PM2
pm2 start server.js --name video-proxy
pm2 save
pm2 startup

4. Build Frontend

cd /home/user/video-streaming-system/frontend

# Update proxy URL for production
echo "REACT_APP_PROXY_URL=http://your-server-ip:3001" > .env

npm install
npm run build

5. Configure Nginx

sudo nano /etc/nginx/sites-available/video-streaming

Add this configuration:

server {
    listen 80;
    server_name your-domain.com;  # or your-server-ip

    # Frontend (React build)
    location / {
        root /home/user/video-streaming-system/frontend/build;
        try_files $uri $uri/ /index.html;
        
        # Cache static assets
        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }

    # Backend API proxy
    location /stream {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        
        # Important for streaming
        proxy_buffering off;
        proxy_request_buffering off;
        proxy_read_timeout 3600s;
        proxy_connect_timeout 3600s;
        proxy_send_timeout 3600s;
    }

    location /health {
        proxy_pass http://localhost:3001;
    }
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/video-streaming /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

6. Setup Firewall

sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw enable

7. Access Your Player

Visit http://your-server-ip or http://your-domain.com

Method 2: Docker Deployment (Optional)

Create docker-compose.yml:

version: '3.8'

services:
  backend:
    build: ./backend
    ports:
      - "3001:3001"
    environment:
      - NODE_ENV=production
      - PORT=3001
    restart: unless-stopped

  frontend:
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend
    environment:
      - REACT_APP_PROXY_URL=http://backend:3001
    restart: unless-stopped

Deploy:

docker-compose up -d

πŸ” HTTPS Setup (Optional but Recommended)

Using Let's Encrypt (Certbot)

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com

Certbot will automatically configure SSL and update your Nginx config.

πŸ“– Usage

Basic Usage

  1. Open the player in your browser
  2. Paste a direct CDN video URL (e.g., https://cdn.example.com/movie.mp4)
  3. Click "Start Streaming"
  4. Video plays instantly with all controls

Multiple Quality Sources

  1. Check "Add multiple quality sources"
  2. Enter URLs for different qualities:
    • Main URL: Auto/Original
    • 720p URL: Lower quality
    • 1080p URL: High quality
  3. Use the quality selector during playback to switch

Resume Playback

The player automatically saves your playback position every 5 seconds. When you reload the same URL, it will resume from where you left off.

Handle Expired URLs

If your CDN URL expires (403/401 error):

  1. Click "Change URL" button
  2. Paste a new/refreshed URL
  3. Player will resume from your last position

πŸ› οΈ Configuration

Backend Environment Variables

PORT=3001                    # Server port
NODE_ENV=production         # Environment mode

Frontend Environment Variables

REACT_APP_PROXY_URL=http://localhost:3001  # Backend proxy URL

πŸ“Š Performance Optimization

Backend

  • Uses streaming (no full file buffering)
  • Efficient HTTP Range forwarding
  • Connection pooling for CDN requests
  • Rate limiting to prevent abuse

Frontend

  • Lazy loading components
  • Video.js optimized buffering
  • LocalStorage for playback position
  • Minimal re-renders with React hooks

πŸ› Troubleshooting

Video won't play

Check:

  1. Is the URL a direct video file link?
  2. Does the URL support HTTP Range requests?
  3. Is CORS enabled on the CDN?
  4. Check browser console for errors

Test the proxy directly:

curl -I "http://localhost:3001/stream?url=YOUR_VIDEO_URL"

Slow buffering

Possible causes:

  1. CDN bandwidth limitations
  2. Large file size
  3. Network congestion

Solutions:

  • Use a CDN with better bandwidth
  • Enable lower quality sources
  • Check your VPS network speed

Token expired errors

This is normal for tokenized CDN links. Simply:

  1. Get a fresh URL
  2. Click "Change URL"
  3. Paste new URL
  4. Playback resumes automatically

Audio/Subtitles not showing

MKV files:

  • Audio tracks usually detected automatically
  • Subtitle tracks depend on browser support
  • Some formats may need conversion

MP4 files:

  • Multiple audio tracks supported
  • External subtitle files not currently supported
  • Use embedded subtitles

πŸ”§ Advanced Configuration

Increase File Size Limit

Edit backend/server.js:

// Increase timeout for very large files
timeout: 60000, // 60 seconds

Custom Video.js Plugins

Add to frontend/src/components/VideoPlayer.jsx:

// After player initialization
vjsPlayer.somePlugin();

Add Custom Themes

Edit frontend/src/styles.css to customize colors, fonts, etc.

πŸ“ API Reference

Backend Endpoints

GET /stream

Stream video with Range support.

Query Parameters:

  • url (required): CDN video URL

Headers:

  • Range: Byte range (optional)

Response:

  • Status: 200 (full file) or 206 (partial)
  • Headers: Content-Type, Accept-Ranges, Content-Range
  • Body: Video stream

Example:

curl "http://localhost:3001/stream?url=https://cdn.example.com/video.mp4" \
  -H "Range: bytes=0-1023"

GET /health

Health check endpoint.

Response:

{
  "status": "ok",
  "timestamp": "2024-03-01T12:00:00.000Z"
}

🀝 Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test thoroughly
  5. Submit a pull request

πŸ“„ License

MIT License - feel free to use for personal or commercial projects.

πŸ™ Acknowledgments

  • Video.js - Excellent HTML5 video player
  • Express.js - Fast Node.js framework
  • React - UI library
  • Axios - HTTP client

πŸ“ž Support

For issues and questions:

  • Check troubleshooting section above
  • Review browser console errors
  • Ensure URLs are direct video links
  • Test with sample videos first

🎯 Roadmap

Future enhancements:

  • External subtitle file upload
  • Video thumbnails preview on timeline
  • Chromecast support
  • Download option
  • Playlist support
  • Watch party mode
  • Picture-in-picture
  • Video filters/effects

Built with ❀️ for seamless video streaming

Releases

Packages

Contributors

Languages