WebVideo2NAS
A lightweight browser-to-NAS pipeline for capturing and downloading web videos. It integrates a Chrome Extension with a NAS-hosted Docker backend (FastAPI, workers, FFmpeg) to automatically detect, queue, download, and process web video streams, converting them into playable MP4 files for long-term storage.
Install / Use
/learn @asdfghj1237890/WebVideo2NASREADME
WebVideo2NAS
Languages: English (README.md) | 繁體中文 (README.zh-TW.md)
Seamlessly capture web video URLs (M3U8 and MP4) from Chrome and download them to your NAS — even when sites disguise streams with non-standard URLs
[!IMPORTANT] This project does not guarantee every video can be downloaded. Some sites use DRM, expiring URLs, anti-hotlinking, IP restrictions, or change their delivery logic at any time.
[!CAUTION] It is not recommended to expose this service directly to the public internet. Prefer accessing your NAS over your LAN or via VPN (e.g. Tailscale).
Table of Contents
- Overview
- Quick Links
- Key Features
- Technology Stack
- Project Structure
- Requirements
- Getting Started / Installation
- Usage
- Configuration
- Security
- Limitations
- Troubleshooting
- Contributing
- License
- Documentation
- Changelog
- Support
Overview
This system enables you to:
- 🔍 Detect M3U8 and MP4 video URLs in Chrome (including disguised streams)
- 📤 Send URLs to your NAS with one click
- ⬇️ Automatically download and convert to MP4
- 💾 Store videos on your NAS storage
System Architecture
Chrome Extension → NAS Docker (API + Worker) → Video Storage

Backend Architecture

Quick Links
<img align="right" src="docs/extension-screenshot.png" alt="Chrome Extension Screenshot" width="300"> <p align="right"><sub>Chrome Extension Interface (Click to view full size)</sub></p>- 🚀 Installation Guide - Complete setup instructions
- 📋 Technical Documentation - Architecture & specifications
- 🔒 Security Policy - Security guidelines
- 🤝 Contributing - How to contribute
Key Features
Chrome Extension
- ✅ Automatic M3U8 and MP4 URL detection
- ✅ Deep manifest interception — detects disguised streams (e.g.
.jpg-wrapped HLS) via fetch/XHR content inspection - ✅ One-click send to NAS
- ✅ Side panel interface for easy access
- ✅ Real-time download progress
- ✅ Cookie & header forwarding for authenticated streams
- ✅ Context menu integration
- ✅ Configurable NAS endpoint
NAS Docker Service
- ✅ RESTful API for job management
- ✅ Dual-worker architecture for parallel processing
- ✅ Multi-threaded segment downloader
- ✅ FFmpeg-based video merging
- ✅ Job queue with Redis
- ✅ Progress tracking & notifications
- ✅ Persistent storage with PostgreSQL
Technology Stack
Frontend:
- Chrome Extension (Manifest V3)
- JavaScript ES6+
Backend:
- Python 3.11+ (FastAPI)
- FFmpeg
- Redis
- PostgreSQL
- Docker & Docker Compose
Project Structure
webvideo2nas/
├── chrome-extension/ # Chrome extension source
├── docs/ # Documentation
├── video-downloader/ # NAS downloader (Docker stack)
│ └── docker/ # Docker services (API + Worker)
├── pics/ # Diagrams used by README
└── README.md # This file
Requirements
For NAS
- Docker & Docker Compose
- 2GB+ RAM available
- Storage space for videos
- Network accessibility from Chrome device
For Chrome
- Chrome browser (v88+)
- Developer mode enabled (for unpacked extension)
Getting Started
<a id="installation"></a>
📦 Installation
<details> <summary><strong>Full Installation Guide (click to expand)</strong></summary>Tip: This README contains the full installation guide. Expand the section below if you need the detailed steps.
This section contains the full installation guide.
Prerequisites
Hardware Requirements
- NAS/Server: 2GB+ RAM, 2+ CPU cores, Docker support
- Client: Chrome browser (v88+)
Software Requirements
- Docker 20.10+
- Docker Compose 2.0+
- Network connectivity between Chrome and NAS
Installation (Easy Mode)
You will do 3 things:
- Deploy the backend on your NAS/server (pick Synology or Non-Synology)
- Install + configure the Chrome extension
- Verify it works
Step 1: Deploy backend (pick ONE)
<details> <summary><strong>Synology NAS (DSM / Container Manager) — UI-first</strong></summary>1. Install Container Manager
- Open Package Center
- Install Container Manager
2. Prepare folders (DSM UI)
- Open File Station
- Project folder (example):
/volume1/docker/video-downloader/ - Downloads folder (example):
/volume1/<YOUR_SHARED_FOLDER_NAME>/downloads/completed - Ensure the account you use in Container Manager has read/write permissions to both folders
- If you see permission errors later (can’t write to
/downloads), re-check DSM folder permissions and try creating a test file in the downloads folder.
- If you see permission errors later (can’t write to
3. Download & extract release (DSM UI)
- Download
WebVideo2NAS-downloader-docker.zipfrom GitHub Releases - Upload to
/volume1/docker/with File Station and extract it - You should have:
/volume1/docker/video-downloader/docker/
4. Create .env (only 2 values are required)
Create /volume1/docker/video-downloader/docker/.env (DSM text editor or upload from PC):
DB_PASSWORD=your_secure_password_here
API_KEY=your_api_key_minimum_32_chars
MAX_DOWNLOAD_WORKERS=20
MAX_RETRY_ATTEMPTS=3
FFMPEG_THREADS=2
LOG_LEVEL=INFO
ALLOWED_ORIGINS=chrome-extension://*
CORS_ALLOW_CREDENTIALS=false
RATE_LIMIT_PER_MINUTE=10
ALLOWED_CLIENT_CIDRS=
SSRF_GUARD=false
5. Deploy with Projects (DSM UI)
- In
/volume1/docker/video-downloader/docker/, renamedocker-compose.synology.yml→docker-compose.yml - Open Container Manager → Projects → Create
- Select project folder:
/volume1/docker/video-downloader/docker - Finish the wizard and start the project
6. Verify
Open http://YOUR_SYNOLOGY_IP:52052/api/health → should return {"status":"healthy"}
1. Download & extract release
wget https://github.com/asdfghj1237890/WebVideo2NAS/releases/latest/download/WebVideo2NAS-downloader-docker.zip
mkdir -p docker
cd docker
unzip ../WebVideo2NAS-downloader-docker.zip
cd video-downloader/docker
mkdir -p ../logs ../downloads/completed
2. Create .env (only 2 values are required)
API_KEY=$(openssl rand -base64 32)
DB_PASSWORD=$(openssl rand -base64 24)
## If you don't have openssl, set API_KEY/DB_PASSWORD manually (any strong random strings)
cat > .env << EOF
DB_PASSWORD=${DB_PASSWORD}
API_KEY=${API_KEY}
MAX_DOWNLOAD_WORKERS=20
MAX_RETRY_ATTEMPTS=3
FFMPEG_THREADS=2
LOG_LEVEL=INFO
ALLOWED_ORIGINS=chrome-extension://*
CORS_ALLOW_CREDENTIALS=false
RATE_LIMIT_PER_MINUTE=10
ALLOWED_CLIENT_CIDRS=
SSRF_GUARD=false
EOF
echo "Your API Key: ${API_KEY}"
3. Deploy & verify
docker-compose up -d
curl http://localhost:52052/api/health
</details>
Step 2: Install + configure Chrome extension
- Open
chrome://extensions/ - Enable Developer mode
- Click Load unpacked
- Select the
chrome-extensionfolder - Open extension Settings:
- NAS Endpoint:
http://YOUR_NAS_IP:52052(use your NAS/server LAN IP; notlocalhost) - API Key: your
API_KEYfrom.env
- NAS Endpoint:
- Click Test Connection → should show connected
Icons should already exist in chrome-extension/icons/ (icon16.png, icon48.png, icon128.png).
If you want to replace them, create PNGs with those names and overwrite the files.
Step 3: What to do if something doesn't work
- Usage: see Usage
- Troubleshooting: see Troubleshooting
- Configuration: see Configuration
Current Status: Core Features Complete ✅
You can now:
- ✅ Deploy Docker stack on Synology NAS or any Docker host
- ✅ Download M3U8 video streams to MP4
- ✅ Download MP4 videos directly
- ✅ Detect disguised manifests via JS-level content interception
- ✅ Use Chrome extension for automatic detection (M3U8 & MP4)
- ✅ Forward cookies & headers for authenticated streams
- ✅ Monitor download progress in side panel
- ✅ Manage downloads via REST API
Usage
- Browse to any video streaming site
- When video URL (M3U8/MP4) is detected, extension badge shows notification
- Click extension icon to open side panel, or right-click → "Send to NAS"
- Video downloads automatically to your NAS (with cookies for authenticated streams)
- Monitor progress in the side panel
- Access completed videos in
/downloads/completed/
Configuration
Environment Variables (.env)
API_KEY=change-this-to-a-very-long-secure-key-minimum-32-chars
DB_PASSWORD=ChangeThisPassword123!
# Logging
LOG_LEVEL=INFO
# CORS (API)
ALLOWED_ORIGINS=chrome-extension://*
# Optional: allow credentials (requires explicit origins; wildcard will be rejected)
CORS_ALLOW_CREDENTIALS=false
# Worker tuning (per-video parallelism)
MAX_DOWNLOAD_WORKERS=20
MAX_RETRY_ATTEMPTS=3
FFMPEG_THREADS=2
# DB cleanup (db_clea
