{"id":36974943,"url":"https://github.com/asdfghj1237890/webvideo2nas","last_synced_at":"2026-04-25T20:02:47.036Z","repository":{"id":318931991,"uuid":"1074844499","full_name":"asdfghj1237890/WebVideo2NAS","owner":"asdfghj1237890","description":"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.","archived":false,"fork":false,"pushed_at":"2026-03-10T19:58:47.000Z","size":1671,"stargazers_count":1144,"open_issues_count":0,"forks_count":66,"subscribers_count":23,"default_branch":"main","last_synced_at":"2026-04-02T15:49:48.230Z","etag":null,"topics":["browser","browser-extension","chrome","extension-chrome","m3u8","m3u8-downloader","mp4","mp4-downloader","nas"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asdfghj1237890.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"asdfghj1237890","thanks_dev":null,"custom":null}},"created_at":"2025-10-12T15:32:30.000Z","updated_at":"2026-03-30T00:51:02.000Z","dependencies_parsed_at":"2025-10-17T08:45:29.054Z","dependency_job_id":null,"html_url":"https://github.com/asdfghj1237890/WebVideo2NAS","commit_stats":null,"previous_names":["asdfghj1237890/chrome2nas-m3u8","asdfghj1237890/webvideo2nas"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/asdfghj1237890/WebVideo2NAS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asdfghj1237890%2FWebVideo2NAS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asdfghj1237890%2FWebVideo2NAS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asdfghj1237890%2FWebVideo2NAS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asdfghj1237890%2FWebVideo2NAS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asdfghj1237890","download_url":"https://codeload.github.com/asdfghj1237890/WebVideo2NAS/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asdfghj1237890%2FWebVideo2NAS/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32274987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"ssl_error","status_checked_at":"2026-04-25T18:29:32.149Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","browser-extension","chrome","extension-chrome","m3u8","m3u8-downloader","mp4","mp4-downloader","nas"],"created_at":"2026-01-13T22:02:45.436Z","updated_at":"2026-04-25T20:02:47.029Z","avatar_url":"https://github.com/asdfghj1237890.png","language":"JavaScript","funding_links":["https://buymeacoffee.com/asdfghj1237890"],"categories":[],"sub_categories":[],"readme":"# WebVideo2NAS\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Docker](https://img.shields.io/badge/Docker-Compose-blue.svg)](https://docs.docker.com/compose/)\n[![Python](https://img.shields.io/badge/Python-3.11+-blue.svg)](https://www.python.org/)\n[![Chrome Extension](https://img.shields.io/badge/Chrome-Extension-red.svg)](https://developer.chrome.com/docs/extensions/)\n[![Release](https://img.shields.io/github/v/release/asdfghj1237890/WebVideo2NAS)](https://github.com/asdfghj1237890/WebVideo2NAS/releases/latest)\n\n**Languages**: **English** (`README.md`) | **繁體中文** (`README.zh-TW.md`)\n\n\u003e 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\n\n\u003e [!IMPORTANT]\n\u003e 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.\n\n\u003e [!CAUTION]\n\u003e 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**).\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Quick Links](#quick-links)\n- [Key Features](#key-features)\n- [Technology Stack](#technology-stack)\n- [Project Structure](#project-structure)\n- [Requirements](#requirements)\n- [Getting Started / Installation](#installation)\n- [Usage](#usage)\n- [Configuration](#configuration)\n- [Security](#security)\n- [Limitations](#limitations)\n- [Troubleshooting](#troubleshooting)\n- [Contributing](#contributing)\n- [License](#license)\n- [Changelog](#changelog)\n- [Support](#support)\n\n## Overview\n\nThis system enables you to:\n1. 🔍 Detect M3U8 and MP4 video URLs in Chrome (including disguised streams)\n2. 📤 Send URLs to your NAS with one click\n3. ⬇️ Automatically download and convert to MP4\n4. 💾 Store videos on your NAS storage\n\n## System Architecture\n\n```\nChrome Extension → NAS Docker (API + Worker) → Video Storage\n```\n\n![Overall System Architecture](pics/overall_system_architecture.png)\n\n### Backend Architecture\n\n![Backend Architecture](pics/backend_architecture.png)\n\n## Quick Links\n\n\u003cimg align=\"right\" src=\"docs/extension-screenshot.png\" alt=\"Chrome Extension Screenshot\" width=\"300\"\u003e\n\u003cp align=\"right\"\u003e\u003csub\u003eChrome Extension Interface (Click to view full size)\u003c/sub\u003e\u003c/p\u003e\n\n- **[🚀 Installation Guide](#installation)** - Complete setup instructions\n- **[📋 Technical Documentation](docs/)** - Architecture \u0026 specifications\n- **[🔒 Security Policy](#security)** - Security guidelines\n- **[🤝 Contributing](#contributing)** - How to contribute\n\n\n\n## Key Features\n\n### Chrome Extension\n- ✅ Automatic M3U8 and MP4 URL detection\n- ✅ Deep manifest interception — detects disguised streams (e.g. `.jpg`-wrapped HLS) via fetch/XHR content inspection\n- ✅ One-click send to NAS\n- ✅ Side panel interface for easy access\n- ✅ Real-time download progress\n- ✅ Cookie \u0026 header forwarding for authenticated streams\n- ✅ Context menu integration\n- ✅ Configurable NAS endpoint\n\n### NAS Docker Service\n- ✅ RESTful API for job management\n- ✅ **Dual-worker architecture** for parallel processing\n- ✅ Multi-threaded segment downloader\n- ✅ FFmpeg-based video merging\n- ✅ Job queue with Redis\n- ✅ Progress tracking \u0026 notifications\n- ✅ Persistent storage with PostgreSQL\n\n## Technology Stack\n\n**Frontend:**\n- Chrome Extension (Manifest V3)\n- JavaScript ES6+\n\n**Backend:**\n- Python 3.11+ (FastAPI)\n- FFmpeg\n- Redis\n- PostgreSQL\n- Docker \u0026 Docker Compose\n\n\u003cbr clear=\"both\"\u003e\n\n## Project Structure\n\n```\nwebvideo2nas/\n├── chrome-extension/  # Chrome extension source\n├── docs/              # Documentation\n├── video-downloader/  # NAS downloader (Docker stack)\n│   └── docker/        # Docker services (API + Worker)\n├── pics/              # Diagrams used by README\n└── README.md          # This file\n```\n\n## Requirements\n\n### For NAS\n- Docker \u0026 Docker Compose\n- 2GB+ RAM available\n- Storage space for videos\n- Network accessibility from Chrome device\n\n### For Chrome\n- Chrome browser (v88+)\n- Developer mode enabled (for unpacked extension)\n\n## Getting Started\n\n\u003ca id=\"installation\"\u003e\u003c/a\u003e\n### 📦 Installation\n\n**Prerequisites:** Docker 20.10+, Docker Compose v2, 2 GB+ RAM. Chrome must reach the NAS over the LAN.\n\nThe actual application ships as a single multi-arch container at `ghcr.io/asdfghj1237890/webvideo2nas` (linux/amd64 + linux/arm64). The release zip contains **only the compose file** (~3 KB).\n\n#### 1. Get the compose files\n\n```bash\nwget https://github.com/asdfghj1237890/WebVideo2NAS/releases/latest/download/WebVideo2NAS-downloader-docker.zip\nunzip WebVideo2NAS-downloader-docker.zip       # → ./docker/\ncd docker\n```\n\nPick the right compose file for your host:\n\n| Host | Run |\n|---|---|\n| **Synology NAS** | `mv docker-compose.synology.yml docker-compose.yml` |\n| **Anything else** (Linux / macOS / Windows Docker) | `mv docker-compose_not_synology.yml docker-compose.yml` |\n\n\u003e Synology paths are hard-coded as `/volume1/...` (DB, Redis, downloads, logs). If your shared folder isn't named `nsfw_video`, edit the `volumes:` section accordingly.\n\n#### 2. Set up `.env`\n\n```bash\ncp .env.example .env\n```\n\nEdit `.env` and set the **two required** values:\n\n| Variable | How |\n|---|---|\n| `API_KEY` | `openssl rand -base64 32` — also paste this into the Chrome extension settings |\n| `DB_PASSWORD` | `openssl rand -base64 24` |\n\nAll other variables ship with sensible defaults; comments in `.env.example` describe each (rate limiting, CORS, worker tuning, IP allowlist, SSRF guard, image tag pin).\n\n#### 3. Start the stack\n\n```bash\ndocker compose pull       # pulls ghcr.io/asdfghj1237890/webvideo2nas:latest\ndocker compose up -d\ncurl -fsS -H \"Authorization: Bearer YOUR_API_KEY\" http://localhost:52052/api/health\n# → {\"status\":\"healthy\"}\n```\n\n\u003e Pin a specific image version: set `IMAGE_TAG=1.9.2` in `.env` (defaults to `latest`).\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSynology Container Manager (DSM UI alternative to CLI)\u003c/strong\u003e\u003c/summary\u003e\n\nIf you'd rather not SSH:\n\n1. **Package Center** → install **Container Manager** (skip if already installed).\n2. **File Station** — create / verify these paths and grant the project user read/write:\n   - `/volume1/docker/video-downloader/` (project root: extract zip here, place `.env`)\n   - `/volume1/docker/video-downloader/db_data/` (DB persistence)\n   - `/volume1/docker/video-downloader/redis_data/` (Redis persistence)\n   - `/volume1/docker/video-downloader/logs/` (logs)\n   - `/volume1/nsfw_video/video-downloader/downloads/completed/` (downloaded videos — change `nsfw_video` to your shared folder name; edit the compose file's `volumes:` if it differs)\n3. **Upload + extract** `WebVideo2NAS-downloader-docker.zip` to `/volume1/docker/video-downloader/` (gives `/volume1/docker/video-downloader/docker/`).\n4. **Edit `.env`** in DSM Text Editor (or upload from PC) — set `API_KEY` + `DB_PASSWORD`.\n5. **Container Manager → Projects → Create**:\n   - Project name: `video-downloader`\n   - Path: `/volume1/docker/video-downloader/docker`\n   - Source: pick `docker-compose.synology.yml`\n   - Finish the wizard — DSM auto-pulls the image from GHCR and brings everything up.\n6. **Verify**: `http://YOUR_SYNOLOGY_IP:52052/api/health` (with `Authorization: Bearer ...`) returns `{\"status\":\"healthy\"}`.\n\n\u003c/details\u003e\n\n#### 4. Install the Chrome extension\n\n1. Clone the repo, or download `WebVideo2NAS-chrome-extension.zip` from the same release and unzip.\n2. `chrome://extensions/` → enable **Developer mode**.\n3. **Load unpacked** → select the `chrome-extension/` folder.\n4. Open the extension **Settings**:\n   - **NAS Endpoint**: `http://YOUR_NAS_IP:52052` (use the LAN IP, not `localhost`)\n   - **API Key**: same value as `API_KEY` in `.env`\n5. **Test Connection** → should say *connected*.\n\n#### Updating\n\n```bash\ncd /path/to/docker-compose-folder\ndocker compose pull\ndocker compose up -d\n```\n\nSynology UI: open the Project → **Action → Pull** → **Restart**.\n\n#### Common issues\n\n| Symptom | Likely cause |\n|---|---|\n| `/api/health` returns **401** | `Authorization: Bearer \u003cAPI_KEY\u003e` header missing or mismatched against `.env` |\n| Worker container shows **unhealthy** | Pre-1.9.2 templates inherit the API healthcheck. Upgrade to ≥ 1.9.2 (`docker compose pull`) — fixed compose disables the inherited check |\n| Synology can't write to `/downloads` | Check folder permissions in DSM File Station (project user needs read/write) |\n| Anything else | See [Troubleshooting](#troubleshooting) |\n\n## Usage\n\n1. Browse to any video streaming site\n2. When video URL (M3U8/MP4) is detected, extension badge shows notification\n3. Click extension icon to open side panel, or right-click → \"Send to NAS\"\n4. Video downloads automatically to your NAS (with cookies for authenticated streams)\n5. Monitor progress in the side panel\n6. Access completed videos in `/downloads/completed/`\n\n## Configuration\n\n### Environment Variables\n\nThe full list with inline comments lives in [`.env.example`](video-downloader/docker/.env.example). The two **required** values are `API_KEY` and `DB_PASSWORD`; everything else has sensible defaults. The handful you'll most likely tune:\n\n| Variable | Default | Effect |\n|---|---|---|\n| `IMAGE_TAG` | `latest` | Pin to a specific release (e.g. `1.9.2`) instead of tracking latest |\n| `LOG_LEVEL` | `INFO` | `DEBUG` for verbose troubleshooting; `WARNING` to quiet down |\n| `MAX_DOWNLOAD_WORKERS` | `20` | Per-worker thread pool for HLS segment downloads |\n| `FFMPEG_THREADS` | `2` | Threads ffmpeg uses during merge |\n| `RATE_LIMIT_PER_MINUTE` | `10` | Per-IP API rate limit (0 disables) |\n| `ALLOWED_CLIENT_CIDRS` | _(empty)_ | Comma-separated CIDRs permitted to call the API; empty = no restriction |\n| `SSRF_GUARD` | `false` | `true` blocks downloads targeting private/loopback/link-local hosts |\n| `CLEANUP_INTERVAL_SECONDS` | `3600` | How often `db_cleanup` prunes finished jobs (keeps latest 100) |\n\n### Worker Scaling\n\nThe default compose runs **2 download workers**. For higher throughput copy the `worker2` block into `worker3` / `worker4` / etc. For lower-spec hosts delete the `worker2` service.\n\n### Extension Settings\n\nIn `chrome://extensions/` → **WebVideo2NAS** → **Settings**:\n- **NAS Endpoint**: `http://YOUR_NAS_IP:52052` (LAN IP, not `localhost`)\n- **API Key**: same value as `API_KEY` in `.env`\n- **Auto Detect**: surfaces M3U8/MP4 URLs as you browse\n- **Notifications**: completion alerts\n\n## Security\n\n⚠️ **Important:**\n- **Don't expose this service directly to the public internet.** Keep it on your LAN, or behind a VPN (Tailscale, WireGuard, etc.).\n- Keep `API_KEY` secret. Generate strong: `openssl rand -base64 32`. Never commit `.env`.\n- For tighter access control, set `ALLOWED_CLIENT_CIDRS` to your LAN range and `SSRF_GUARD=true`.\n- Pin `IMAGE_TAG` to a specific version and review the changelog before upgrading.\n- Out of scope: DRM bypass, public-internet hosting, multi-tenant deployments.\n\n### Reporting a Vulnerability\n\nPlease open a [GitHub Security Advisory](https://github.com/asdfghj1237890/WebVideo2NAS/security/advisories/new). **Do not** open a public issue.\n\nWhen reporting, include: type of issue, affected file path / commit, reproduction steps, and (if possible) PoC and impact assessment.\n\n## Limitations\n\n- ❌ DRM-protected content not supported\n- ❌ Some streaming sites use additional encryption\n- ❌ Requires network connectivity between Chrome and NAS\n- ℹ️ Download speed limited by network and NAS hardware\n\n## Troubleshooting\n\nFor first-run / install issues see the [Common issues table](#common-issues) at the end of Installation.\n\n### Extension can't connect to NAS\n- `http://YOUR_NAS_IP:52052` — use the LAN IP, not `localhost`\n- `docker compose ps` — confirm `video_api` is `Up` and `(healthy)`\n- Synology / Linux firewall blocking 52052?\n\n### Download fails\n- `docker compose logs -f worker` — failure reason is usually one error line\n- For authenticated streams: confirm the extension captured cookies for the manifest's domain (extension Settings → check the captured-headers panel)\n- HTTP 403/474 from segment downloads usually means the URL has expired — re-detect from a fresh page load\n- Disk full? `df -h /downloads`\n\n### Slow downloads\n- Lower `MAX_DOWNLOAD_WORKERS` in `.env` (NAS CPU saturated)\n- The site may be throttling; check segment download rate in worker logs\n- Network: verify NAS upload bandwidth from another LAN device\n\n## Contributing\n\nPRs welcome.\n\n1. Fork → branch (`feature/...` or `fix/...`)\n2. Run the test suite locally — same as CI:\n   - Python: `bash video-downloader/docker/tests/run_upgrade_check.sh`\n   - Extension: `cd chrome-extension \u0026\u0026 npm test`\n3. Open a PR against `main` with a clear description and link any related issue\n\n**Code style:** Python follows PEP 8 + type hints; JavaScript is ES6+ with `const`/`let` and async/await. Match the surrounding file. No formatter is enforced.\n\n**Project layout:** see [Project Structure](#project-structure) above. Architecture docs and API specs live in [`docs/`](docs/).\n\n**Reporting issues:** open a [GitHub Issue](https://github.com/asdfghj1237890/WebVideo2NAS/issues) with reproduction steps, expected vs actual behavior, and environment details (OS, Docker version, NAS model). For security issues see [Reporting a Vulnerability](#reporting-a-vulnerability) — do **not** open a public issue.\n\nBy contributing you agree to license your work under the MIT License.\n\n## License\n\nMIT License — see [LICENSE](LICENSE).\n\n\u003ca id=\"changelog\"\u003e\u003c/a\u003e\n## Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eFull Changelog (click to expand)\u003c/strong\u003e\u003c/summary\u003e\n\n### [1.9.2] - 2026-04-26\n\n#### Fixed\n- Worker containers were marked **unhealthy** because they inherited the unified image's API healthcheck (`curl http://localhost:8000/api/health`) — workers don't listen on port 8000. The compose templates now explicitly disable the inherited healthcheck on `worker` / `worker2` services\n\n### [1.9.1] - 2026-04-26\n\u003e Note: this is the first release of the unified-image flow; v1.9.0 was reserved by an earlier mis-tagged commit and skipped.\n\n#### Changed\n- **Unified Docker image**: api + worker now ship as a single multi-arch image (`linux/amd64` + `linux/arm64`) at `ghcr.io/asdfghj1237890/webvideo2nas`. Services dispatch by `ROLE` env var (`api` / `worker`)\n- **GHCR distribution**: release zip slimmed to ~3 KB (compose + init-db.sql + .env.example only) — users `docker compose pull` instead of building from source\n- **Hash-locked Python deps**: `requirements.txt` regenerated via `pip-compile --generate-hashes`; `pip install --require-hashes` blocks supply-chain swaps\n- Sequential release workflow: GitHub Release is gated on the matching GHCR image being live, so `docker compose pull` immediately after the release email never 404s\n\n#### Security\n- **Fix `/api/health` auth bypass via spoofed `X-Forwarded-For: 127.0.0.1`**: the endpoint now requires the API key for all callers; the in-container Docker `HEALTHCHECK` sends it via Authorization header\n\n#### Removed\n- Dropped unused dependencies `aiohttp` and `aiofiles` (never imported by api or worker code)\n\n#### Build\n- Multi-arch image build with provenance attestation + SBOM (`docker/build-push-action@v6`)\n\n### [1.8.9] - 2026-04-03\n\n#### Fixed\n- Fix **HTTP 400 Bad Request** when downloading m3u8 streams from sites that store video playback progress as URL-like cookies (e.g. `https://…/index.m3u8=1234`). These non-standard cookie entries bloated the `Cookie` header beyond server limits; the worker now strips them before sending requests\n\n### [1.8.8] - 2026-03-11\n\n#### Added\n- **Deep manifest interception** (`inject.js`): New MAIN-world content script that patches `fetch()` and `XMLHttpRequest` to inspect the first bytes of every response for `#EXTM3U` signatures — catches HLS manifests served from arbitrary URLs without `.m3u8` extension or correct MIME type (e.g. sites that disguise streams as `.jpg`)\n- **Response Content-Type detection**: Identify HLS manifests by `Content-Type` header regardless of URL extension\n- `format` hint field in download API — allows the extension to tell the backend the stream type even when the URL has no recognizable extension\n\n#### Changed\n- `sendToNAS()` accepts URLs detected by Content-Type or content interception (not just URL pattern)\n- NAS API validator uses `model_validator` to allow `format` hint to bypass URL pattern check\n\n#### Fixed\n- **Rate limit no longer blocks normal usage**: Read-only endpoints (job list, job status) now use a separate, higher rate-limit bucket so side panel polling no longer starves download requests\n\n### [1.8.6] - 2026-01-13\n\n#### Added\n- Implement video interaction tracking in Chrome extension to improve video detection\n\n#### Changed\n- Refactor background tests for video interaction logic\n\n#### Docs\n- Add Traditional Chinese translation (`README.zh-TW.md`)\n- Enhance README with usage and troubleshooting details\n- Clarify permissions and environment variable setup\n- Update safety warnings and directory structure documentation\n\n### [1.8.5] - 2025-12-16\n\n#### Added\n- 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\n- Add unit tests for Chrome extension helpers and downloader worker/API edge cases\n\n#### Changed\n- Exclude tests, `node_modules`, and Python caches from release zip artifacts\n\n#### Fixed\n- Fix side panel quality extraction so adjacent quality markers (e.g. `720p_1080p`) are detected reliably\n- Make M3U8 parsing more robust: handle `Accept-Encoding: br` case-insensitively and ignore invalid AES-128 IV values\n\n#### Docs\n- Update API specification to remove `/api/auth/validate` endpoint\n\n### [1.8.4] - 2025-12-16\n\n#### Changed\n- Improve video URL detection and Chrome extension UI behavior\n- Update deployment instructions and Docker Compose configuration for the downloader stack\n- Rename downloader directory from `m3u8-downloader/` to `video-downloader/` and update related configuration references\n- Bump project version to `1.8.4` across Chrome extension, API, worker, and docs\n\n#### Docs\n- Update installation/examples to use `video-downloader/` and `video_*` container names (remove legacy `m3u8-*`)\n\n### [1.8.3] - 2025-12-16\n\n#### Added\n- Add `db_cleanup` service to prune finished jobs (keep latest 100) on an interval via `CLEANUP_INTERVAL_SECONDS`\n\n#### Changed\n- Align Docker Compose names and database to `video_*` / `video_db` for both standard and Synology deployments\n\n#### Docs\n- Update Project Structure tree to match repository layout\n- Document `CLEANUP_INTERVAL_SECONDS` in `.env.example`\n\n#### Fixed\n- Side panel now picks up updated NAS settings without getting stuck, and shows a more specific connection error reason\n- GitHub release workflow updated to use the renamed `video-downloader/` directory\n\n### [1.8.1] - 2025-12-16\n\n#### Changed\n- Documentation updates\n\n### [1.8.0] - 2025-12-16\n\n#### Added\n- User settings for auto-detection and notifications\n- SSRF protection and client IP allowlisting in API and worker\n\n#### Changed\n- Remove `MAX_CONCURRENT_DOWNLOADS` configuration and update related documentation\n- Update environment variables and Docker Compose settings to reflect worker configuration changes\n\n### [1.7.0] - 2025-12-15\n\n#### Added\n- Internationalization (i18n) support for side panel and options\n\n#### Changed\n- Rename project from \"Chrome2NAS M3U8 Downloader\" to \"WebVideo2NAS\"\n- Improve video URL detection, handling, and deduplication in the background script\n\n### [1.6.0] - 2025-12-12\n\n#### Changed\n- Improve side panel UI and error handling; enhance job status display and duration formatting\n- Improve media duration handling in the download worker\n- Improve header normalization and M3U8 request handling across extension background and worker\n- Enhance downloader encryption handling and session management\n- Documentation updates (port usage/spec details) and version display updates\n\n### [1.5.0] - 2025-12-12\n\n#### Added\n- Brotli support and header sanitization in the M3U8 parser\n- Cooperative cancellation support in `SegmentDownloader`\n\n#### Fixed\n- Sidepanel click handling for job actions (use `currentTarget`)\n\n#### Changed\n- Improve M3U8 validation and error handling in the worker\n- Chrome extension UI/theming refinements and progress text rendering updates\n- Release workflow updated to generate changelog and bump version to 1.5.0\n\n### [1.4.3] - 2025-12-02\n\n#### Changed\n- Implement enhanced header capturing and Referer strategies in the downloader\n\n### [1.4.1] - 2025-12-02\n\n#### Changed\n- Improve error handling and anti-hotlinking protections in downloader/parser modules\n\n### [1.4.0] - 2025-12-02\n\n#### Added\n- AES-128 decryption support for encrypted HLS segments\n- Download cancellation support with UI status labels and backend handling\n- MP4 downloads alongside M3U8\n\n#### Changed\n- Legacy SSL support for downloader/parser modules\n\n### [1.1.0] - 2025-10-13\n\n#### Added\n- **Expanded to 2 download workers** for parallel processing capability\n  - Total system capacity increased to 2 concurrent videos (1 per worker)\n  - Automatic load balancing via Redis queue\n  - Improved throughput and high availability\n- Comprehensive documentation of dual-worker architecture\n  - Multi-worker design explanation in docs/ARCHITECTURE.md\n  - Worker scaling guidelines in the Installation section of README.md\n  - Performance tuning recommendations\n  - Load balancing via Redis queue documentation\n\n#### Fixed\n- Download failure issues resolved with improved worker architecture\n- Enhanced error handling and retry mechanism stability\n- Better resource management under high load\n\n#### Changed\n- Docker Compose now deploys 2 workers by default (previously 1)\n\n### [1.0.0] - 2025-10-12\n\n#### Added - Phase 3 Complete: Chrome Extension\n- Chrome extension with automatic M3U8 URL detection\n- One-click send to NAS functionality\n- Real-time progress monitoring in extension popup\n- Settings page with NAS endpoint configuration\n- Context menu integration\n- Badge notifications for detected URLs\n\n#### Added - Phase 2 Complete: Video Downloader\n- Phase 2 complete: Worker implementation with playlist parsing (M3U8) and direct downloads (MP4)\n- FFmpeg integration for video merging\n- Multi-threaded segment downloader\n- Retry mechanism with exponential backoff\n- Comprehensive error handling\n\n#### Changed\n- Enhanced worker architecture for better performance\n- Improved logging system\n- Updated Docker configurations\n\n### [0.1.0] - 2025-10-11\n\n#### Added\n- Phase 1 complete: Core infrastructure\n- Docker Compose setup for Synology NAS\n- PostgreSQL database with schema\n- Redis job queue\n- FastAPI REST API with basic endpoints\n- Worker skeleton with job processing\n- Comprehensive documentation\n  - Technical specification\n  - Architecture documentation\n  - Synology setup guides\n  - Quick start guide\n\n#### Infrastructure\n- Docker multi-service architecture\n- Database migrations\n- Health check endpoints\n- API authentication with API keys\n\n### [0.0.1] - 2025-10-11\n\n#### Added\n- Initial project specification\n- Project structure\n- README documentation\n- Technical design document\n\n\u003c/details\u003e\n\n## Support\n\n- 🐛 **Issues**: [GitHub Issues](https://github.com/asdfghj1237890/WebVideo2NAS/issues)\n- 💬 **Discussions**: [GitHub Discussions](https://github.com/asdfghj1237890/WebVideo2NAS/discussions)\n- 📧 **Security**: See [Reporting a Vulnerability](#reporting-a-vulnerability)\n- ☕ **Buy me a coffee**: https://buymeacoffee.com/asdfghj1237890\n\n---\n\n**Version**: 1.9.2  \n**Last Updated**: 2026-04-03  \n**Port**: 52052 (NAS host port → API container :8000)\n\n## Star History\n\nIf you find this project useful, please consider giving it a star! ⭐\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasdfghj1237890%2Fwebvideo2nas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasdfghj1237890%2Fwebvideo2nas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasdfghj1237890%2Fwebvideo2nas/lists"}