Languages: English (README.md) | 繁體中文 (README.zh-TW.md)
Seamlessly capture web video URLs (M3U8 and MP4) from Chrome and download them to your NAS
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).
- Overview
- Quick Links
- Key Features
- Technology Stack
- Project Structure
- Requirements
- Getting Started / Installation
- Usage
- Configuration
- Security
- Limitations
- Troubleshooting
- Contributing
- License
- Documentation
- Changelog
- Support
This system enables you to:
- 🔍 Detect M3U8 and MP4 video URLs in Chrome
- 📤 Send URLs to your NAS with one click
- ⬇️ Automatically download and convert to MP4
- 💾 Store videos on your NAS storage
Chrome Extension → NAS Docker (API + Worker) → Video Storage
Chrome Extension Interface (Click to view full size)
- 🚀 Installation Guide - Complete setup instructions
- 📋 Technical Documentation - Architecture & specifications
- 🔒 Security Policy - Security guidelines
- 🤝 Contributing - How to contribute
- ✅ Automatic M3U8 and MP4 URL detection
- ✅ 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
- ✅ 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
Frontend:
- Chrome Extension (Manifest V3)
- JavaScript ES6+
Backend:
- Python 3.11+ (FastAPI)
- FFmpeg
- Redis
- PostgreSQL
- Docker & Docker Compose
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
- Docker & Docker Compose
- 2GB+ RAM available
- Storage space for videos
- Network accessibility from Chrome device
- Chrome browser (v88+)
- Developer mode enabled (for unpacked extension)
Tip: This README contains the full installation guide. Expand the section below if you need the detailed steps.
Full Installation Guide (click to expand)
This section contains the full installation guide.
- NAS/Server: 2GB+ RAM, 2+ CPU cores, Docker support
- Client: Chrome browser (v88+)
- Docker 20.10+
- Docker Compose 2.0+
- Network connectivity between Chrome and NAS
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
Synology NAS (DSM / Container Manager) — UI-first
- Open Package Center
- Install Container Manager
- 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
- 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/
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- 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
Open http://YOUR_SYNOLOGY_IP:52052/api/health → should return {"status":"healthy"}
Non-Synology / Standard Docker — command line
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/completedAPI_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}"docker-compose up -d
curl http://localhost:52052/api/health- 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
(Optional) Custom icons
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.
- Usage: see Usage
- Troubleshooting: see Troubleshooting
- Configuration: see Configuration
You can now:
- ✅ Deploy Docker stack on Synology NAS or any Docker host
- ✅ Download M3U8 video streams to MP4
- ✅ Download MP4 videos directly
- ✅ 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
- 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/
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_cleanup service)
# How often to prune finished jobs (seconds). Default: 3600 (1 hour)
#CLEANUP_INTERVAL_SECONDS=3600
# Security
# Per-client rate limit for protected endpoints (0 disables)
RATE_LIMIT_PER_MINUTE=10
# Restrict who can call the API (comma-separated CIDRs)
ALLOWED_CLIENT_CIDRS=
# Basic SSRF guard for /api/download (blocks private/loopback/link-local/reserved destinations)
SSRF_GUARD=false
# Optional (insecure): TLS verification controls for tricky servers
# INSECURE_SKIP_TLS_VERIFY=0
# SSL_VERIFY=1The system runs 2 workers by default for parallel processing:
- Total capacity: Up to 2 videos simultaneously (1 per worker)
- Scale up: Add more workers in
docker-compose.ymlfor higher throughput - Scale down: Remove
worker2service for lower-spec NAS devices
- NAS Endpoint:
https://192.168.1.100:52052 - API Key: Your configured API key
- Auto Detect: Enable automatic M3U8/MP4 detection
- Notifications: Enable completion notifications
Note: Click the extension icon to open the side panel for managing detected videos and monitoring downloads.
- Use HTTPS with valid SSL certificate
- Keep API key secret
- Consider using VPN/Tailscale for remote access
- Implement rate limiting
- Regularly update Docker images
Full Security Policy (click to expand)
Currently, the following versions are being supported with security updates:
| Version | Supported |
|---|---|
| 1.0.x | ✅ |
| < 1.0 | ❌ |
If you discover a security vulnerability within WebVideo2NAS, please follow these steps:
- Do not open a public GitHub issue
- Do not disclose the vulnerability publicly until it has been addressed
- Email the maintainers privately (create a security advisory on GitHub)
- Provide detailed information about the vulnerability:
- Type of issue (e.g., authentication bypass, SQL injection, XSS)
- Full paths of affected source files
- Location of the affected code (tag/branch/commit)
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the vulnerability
- Acknowledgment: Within 48 hours
- Initial Assessment: Within 5 business days
- Status Update: Every 7 days until resolved
- Fix Release: Depends on severity (Critical: 7 days, High: 14 days, Medium: 30 days)
-
API Key Security
- Generate strong API keys (minimum 32 characters)
- Use
openssl rand -base64 32to generate secure keys - Never commit
.envfiles to version control - Rotate API keys periodically
-
Network Security
- Use HTTPS in production (not HTTP)
- Configure proper firewall rules
- Limit API access to trusted networks
- Consider using VPN or Tailscale for remote access
-
Docker Security
- Keep Docker images updated
- Run containers as non-root users when possible
- Limit container capabilities
- Use Docker secrets for sensitive data
-
Database Security
- Use strong database passwords
- Restrict database access to localhost
- Regular database backups
- Enable PostgreSQL SSL connections in production
-
Code Security
- Validate all user inputs
- Use parameterized queries (already implemented)
- Sanitize file paths
- Implement rate limiting (already implemented)
-
Dependency Security
- Regularly update dependencies
- Use
pip auditto check for vulnerable packages - Review dependencies before adding new ones
-
Testing
- Test with various malicious inputs
- Check for path traversal vulnerabilities
- Verify authentication on all endpoints
- Test CORS configuration
-
Authentication: API Key-based (Bearer token)
- Simple but effective for private NAS deployments
- Consider OAuth2 for multi-user scenarios
-
CORS: Configured for Chrome extensions
- Default:
chrome-extension://* - Adjust for your specific needs
- Default:
-
Rate Limiting: Basic implementation
- Default: 10 requests per minute
- Configurable via environment variables
-
File System Access:
- Limited to configured download directories
- No user-provided file paths accepted
- DRM Content: This tool cannot and should not be used to bypass DRM
- Copyright: Users are responsible for ensuring legal rights to download content
- Public Exposure: Not designed for public internet exposure without additional security layers
# Strong credentials
API_KEY=$(openssl rand -base64 32)
DB_PASSWORD=$(openssl rand -base64 24)
# Network restrictions
ALLOWED_ORIGINS=chrome-extension://your-extension-id
# Monitoring
LOG_LEVEL=INFOBefore deploying to production:
- Change default passwords
- Generate strong API keys
- Configure HTTPS with valid certificate
- Set up firewall rules
- Enable rate limiting
- Configure proper CORS
- Review and restrict file system access
- Set up log monitoring
- Regular security updates
- Backup strategy in place
For security concerns, please use GitHub Security Advisories feature or contact the maintainers directly.
Last Updated: 2025-12-12
- ❌ DRM-protected content not supported
- ❌ Some streaming sites use additional encryption
- ❌ Requires network connectivity between Chrome and NAS
- ℹ️ Download speed limited by network and NAS hardware
- Verify NAS IP and port
- Check firewall rules
- Ensure Docker service is running:
docker-compose ps
- Check logs:
docker-compose logs worker - Verify video URL is accessible
- Check disk space on NAS
- For authenticated streams, ensure cookies are being captured
- Reduce concurrent downloads in .env
- Check NAS CPU/RAM usage
- Verify network bandwidth
Thank you for your interest in contributing! This document provides guidelines and instructions for contributing to this project.
Contributing Guide (click to expand)
-
Read the Documentation
- README.md - Project overview
- docs/SPECIFICATION.md - Technical specification
- docs/ARCHITECTURE.md - System architecture
-
Set Up Development Environment
- Docker & Docker Compose
- Python 3.11+
- Chrome browser with Developer mode
- Code editor of your choice
git clone https://github.com/yourusername/webvideo2nas.git
cd webvideo2nasgit checkout -b feature/your-feature-name
# or
git checkout -b fix/your-bug-fix- Follow existing code style
- Write clear, descriptive commit messages
- Keep commits focused and atomic
- Add tests for new features
- Update documentation as needed
Backend (Docker Services):
cd video-downloader/docker
docker-compose up --build
# Test API endpoints
./test-api.shChrome Extension:
cd chrome-extension
# Load unpacked extension in Chrome
# Test functionality manually- Push your branch to your fork
- Create a pull request to the main repository
- Describe your changes clearly
- Reference any related issues
- Follow PEP 8
- Use type hints where appropriate
- Keep functions focused and small
- Add docstrings for classes and public methods
Example:
def download_segment(url: str, timeout: int = 30) -> bytes:
"""
Download a single HLS segment.
Args:
url: The segment URL
timeout: Request timeout in seconds
Returns:
The segment content as bytes
Raises:
DownloadError: If download fails
"""
pass- Use ES6+ features
- Use
constandlet, avoidvar - Use async/await for asynchronous operations
- Keep functions focused and small
Example:
async function detectM3u8Urls(details) {
const url = details.url.toLowerCase();
if (url.includes('.m3u8')) {
await notifyUrlDetected(details.url);
}
}WebVideo2NAS/
├── chrome-extension/ # Chrome extension source
│ ├── background.js # Background service worker
│ ├── sidepanel.* # Extension side panel UI
│ ├── options/ # Extension options page
│ ├── icons/ # Extension icons
│ └── manifest.json # Extension manifest
├── video-downloader/ # NAS downloader
│ └── docker/ # Docker services
│ ├── api/ # FastAPI service
│ ├── worker/ # Download worker
│ ├── docker-compose.yml
│ ├── docker-compose.synology.yml
│ └── init-db.sql
├── docs/ # Architecture/specs/docs
└── pics/ # Diagrams
- M3U8 parser improvements
- FFmpeg integration enhancements
- Chrome extension features
- Bug fixes
- Performance optimizations
- Documentation improvements
- Unit tests
- Integration tests
- Error handling improvements
- Logging enhancements
- UI/UX improvements
- Additional NAS platform support
- Advanced retry strategies
- Download resume capability
- Bandwidth throttling
- Scheduled downloads
When reporting issues, please include:
- Clear description of the problem
- Steps to reproduce
- Expected behavior
- Actual behavior
- Environment details (OS, Docker version, NAS model, etc.)
- Relevant logs or error messages
- Maintainers will review your pull request
- Address any feedback or requested changes
- Once approved, your PR will be merged
- Your contribution will be acknowledged in release notes
- Check existing issues and discussions
- Read the documentation thoroughly
- Ask questions in GitHub Discussions
By contributing, you agree that your contributions will be licensed under the MIT License.
MIT License - See LICENSE file for details
- 📖 Installation Guide - Complete setup instructions
- 🏗️ Technical Documentation - Architecture, specifications, and implementation details
- 🔒 Security Policy - Security guidelines and reporting
- 🤝 Contributing - How to contribute
- 📝 Changelog - Version history
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Full Changelog (click to expand)
- Add GitHub Actions CI workflow for Python unit tests (API + worker via
uv), Chrome extension unit tests (Vitest), and an API smoke test using Docker Compose - Add unit tests for Chrome extension helpers and downloader worker/API edge cases
- Exclude tests,
node_modules, and Python caches from release zip artifacts
- Fix side panel quality extraction so adjacent quality markers (e.g.
720p_1080p) are detected reliably - Make M3U8 parsing more robust: handle
Accept-Encoding: brcase-insensitively and ignore invalid AES-128 IV values
- Update API specification to remove
/api/auth/validateendpoint
- Improve video URL detection and Chrome extension UI behavior
- Update deployment instructions and Docker Compose configuration for the downloader stack
- Rename downloader directory from
m3u8-downloader/tovideo-downloader/and update related configuration references - Bump project version to
1.8.4across Chrome extension, API, worker, and docs
- Update installation/examples to use
video-downloader/andvideo_*container names (remove legacym3u8-*)
- Add
db_cleanupservice to prune finished jobs (keep latest 100) on an interval viaCLEANUP_INTERVAL_SECONDS
- Align Docker Compose names and database to
video_*/video_dbfor both standard and Synology deployments
- Update Project Structure tree to match repository layout
- Document
CLEANUP_INTERVAL_SECONDSin.env.example
- Side panel now picks up updated NAS settings without getting stuck, and shows a more specific connection error reason
- GitHub release workflow updated to use the renamed
video-downloader/directory
- Documentation updates
- User settings for auto-detection and notifications
- SSRF protection and client IP allowlisting in API and worker
- Remove
MAX_CONCURRENT_DOWNLOADSconfiguration and update related documentation - Update environment variables and Docker Compose settings to reflect worker configuration changes
- Internationalization (i18n) support for side panel and options
- Rename project from "Chrome2NAS M3U8 Downloader" to "WebVideo2NAS"
- Improve video URL detection, handling, and deduplication in the background script
- Improve side panel UI and error handling; enhance job status display and duration formatting
- Improve media duration handling in the download worker
- Improve header normalization and M3U8 request handling across extension background and worker
- Enhance downloader encryption handling and session management
- Documentation updates (port usage/spec details) and version display updates
- Brotli support and header sanitization in the M3U8 parser
- Cooperative cancellation support in
SegmentDownloader
- Sidepanel click handling for job actions (use
currentTarget)
- Improve M3U8 validation and error handling in the worker
- Chrome extension UI/theming refinements and progress text rendering updates
- Release workflow updated to generate changelog and bump version to 1.5.0
- Implement enhanced header capturing and Referer strategies in the downloader
- Improve error handling and anti-hotlinking protections in downloader/parser modules
- AES-128 decryption support for encrypted HLS segments
- Download cancellation support with UI status labels and backend handling
- MP4 downloads alongside M3U8
- Legacy SSL support for downloader/parser modules
- Expanded to 2 download workers for parallel processing capability
- Total system capacity increased to 2 concurrent videos (1 per worker)
- Automatic load balancing via Redis queue
- Improved throughput and high availability
- Comprehensive documentation of dual-worker architecture
- Multi-worker design explanation in docs/ARCHITECTURE.md
- Worker scaling guidelines in the Installation section of README.md
- Performance tuning recommendations
- Load balancing via Redis queue documentation
- Download failure issues resolved with improved worker architecture
- Enhanced error handling and retry mechanism stability
- Better resource management under high load
- Docker Compose now deploys 2 workers by default (previously 1)
- Chrome extension with automatic M3U8 URL detection
- One-click send to NAS functionality
- Real-time progress monitoring in extension popup
- Settings page with NAS endpoint configuration
- Context menu integration
- Badge notifications for detected URLs
- Phase 2 complete: Worker implementation with playlist parsing (M3U8) and direct downloads (MP4)
- FFmpeg integration for video merging
- Multi-threaded segment downloader
- Retry mechanism with exponential backoff
- Comprehensive error handling
- Enhanced worker architecture for better performance
- Improved logging system
- Updated Docker configurations
- Phase 1 complete: Core infrastructure
- Docker Compose setup for Synology NAS
- PostgreSQL database with schema
- Redis job queue
- FastAPI REST API with basic endpoints
- Worker skeleton with job processing
- Comprehensive documentation
- Technical specification
- Architecture documentation
- Synology setup guides
- Quick start guide
- Docker multi-service architecture
- Database migrations
- Health check endpoints
- API authentication with API keys
- Initial project specification
- Project structure
- README documentation
- Technical design document
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 📧 Security: See Reporting a Vulnerability
- ☕ Buy me a coffee: https://buymeacoffee.com/asdfghj1237890
Version: 1.8.5
Last Updated: 2025-12-16
Port: 52052 (NAS host port → API container :8000)
If you find this project useful, please consider giving it a star! ⭐


