Universal video downloader API supporting multiple platforms with yt-dlp backend, batch processing, and Go REST API
  • CSS 36.1%
  • Go 35.4%
  • HTML 25%
  • Dockerfile 2.2%
  • Shell 1.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
vndangkhoa 3dc0dcf0db
Some checks failed
/ build (push) Has been cancelled
fix: return actual stderr error message from runYtDlp on cmd failure
2026-08-04 20:31:24 +07:00
.forgejo/workflows fix forgejo actions: use gitea.com action URLs and fix sha syntax 2026-04-04 17:38:47 +07:00
.github/workflows security: fix .gitignore cookies rule, fix workflow image targets, fix script ports/dirs 2026-08-04 16:08:43 +07:00
src fix: return actual stderr error message from runYtDlp on cmd failure 2026-08-04 20:31:24 +07:00
static feat: simplify UI header with zero logo duplication and side-by-side theme switcher buttons 2026-08-04 20:28:25 +07:00
templates/media feat: simplify UI header with zero logo duplication and side-by-side theme switcher buttons 2026-08-04 20:28:25 +07:00
.dockerignore Add Docker image support for Synology NAS with linux/amd64 platform 2026-04-04 16:01:32 +07:00
.gitignore feat: auto-generate/refresh cookies.txt from browser (MR_COOKIES_BROWSER) 2026-08-04 16:54:34 +07:00
.tool-versions Upgrade from go 1.25.1 to go 1.25.3 2025-10-19 15:46:59 -07:00
build.sh Update README with Synology NAS deployment guide, tag image as v1, fix volume paths 2026-04-04 17:07:28 +07:00
docker-build.sh security: fix .gitignore cookies rule, fix workflow image targets, fix script ports/dirs 2026-08-04 16:08:43 +07:00
docker-compose.yml feat: include cookies.txt volume mount in docker-compose.yml 2026-08-04 20:11:16 +07:00
docker-run.sh security: fix .gitignore cookies rule, fix workflow image targets, fix script ports/dirs 2026-08-04 16:08:43 +07:00
Dockerfile fix: enable TikTok impersonation (curl_cffi<0.16), add yt-dlp retry for transient anti-bot failures 2026-08-04 16:31:18 +07:00
go.mod fix: handle read-only cookies.txt gracefully, document writable mount requirement 2026-08-04 16:18:05 +07:00
go.sum fix: handle read-only cookies.txt gracefully, document writable mount requirement 2026-08-04 16:18:05 +07:00
README.md docs: document curl_cffi impersonation fix, retry feature, cookie env vars 2026-08-04 16:57:12 +07:00
run.sh security: fix .gitignore cookies rule, fix workflow image targets, fix script ports/dirs 2026-08-04 16:08:43 +07:00
tidy.sh Update README with Synology NAS deployment guide, tag image as v1, fix volume paths 2026-04-04 17:07:28 +07:00

🎬 KV Download

A fast, mobile-friendly video downloader for social media platforms.

Built with Go + yt-dlp — deploy anywhere in one command.

Go Version Docker Hub License Platform

KV Download — screenshot

📦 Table of Contents


Features

🚀 Multi-URL 📥 Download queue 💾 ZIP export
Paste multiple links, download them all in sequence Real-time per-URL status with progress bar Bundle all videos into a single download
📱 Responsive 👀 Video preview 🔄 Auto-update
Works on desktop, tablet, and mobile Watch before you save yt-dlp refreshes itself every 6 hours
🌙 Dark mode 🔒 Cookie support 🐳 One-command deploy
Sleek glassmorphism UI Auto-refresh + manual cookies.txt for TikTok/IG/Twitter Single Docker image for amd64 & arm64
🛡️ Anti-bot 🔄 Smart retry 🧹 Auto cleanup (NAS)
Browser impersonation via curl_cffi Retries transient failures up to 3× Cron-based download cleanup for Synology

Supported platforms

YouTube · TikTok · Instagram · Twitter/X · Vimeo · Reddit · many more


🚀 Quick Start

Prerequisites: Go, yt-dlp, FFmpeg

git clone https://github.com/vndangkhoa/kv-download.git
cd kv-download
./run.sh

Then open http://localhost:9292 🎉


🐳 Docker

Docker Hub

docker pull vndangkhoa/kv-download:latest
docker run -d -p 9292:9292 \
  -v ./downloads:/download \
  vndangkhoa/kv-download:latest

Forgejo Registry

docker pull git.khoavo.myds.me/vndangkhoa/kv-download:latest
docker run -d -p 9292:9292 \
  -v ./downloads:/download \
  git.khoavo.myds.me/vndangkhoa/kv-download:latest

Docker Compose

services:
  kv-download:
    image: vndangkhoa/kv-download:latest
    container_name: kv-download
    restart: unless-stopped
    ports:
      - "9292:9292"
    volumes:
      - ./downloads:/download
    environment:
      - TZ=Asia/Ho_Chi_Minh
docker compose up -d

Build Locally

./docker-build.sh
./docker-run.sh

Synology NAS

  1. Open Container Manager (or Docker on older DSM)
  2. Create a new project/stack:
services:
  kv-download:
    image: vndangkhoa/kv-download:latest
    container_name: kv-download
    restart: unless-stopped
    ports:
      - "9292:9292"
    volumes:
      - /volume2/docker/kv-download/downloads:/download
      - /volume2/docker/kv-download/cookies.txt:/app/cookies.txt
    environment:
      - TZ=Asia/Ho_Chi_Minh
  1. Place cookies.txt in /volume2/docker/kv-download/
  2. Access at http://NAS_IP:9292

🧹 Clean up downloads

# SSH into NAS, then delete all downloaded files
rm -rf /volume2/docker/kv-download/downloads/*

# Or delete files older than 7 days
find /volume2/docker/kv-download/downloads/ -type f -mtime +7 -delete

Automate cleanup via Task Scheduler in DSM:

# Run daily at 3 AM, delete files older than 7 days
0 3 * * * find /volume2/docker/kv-download/downloads/ -type f -mtime +7 -delete

🍪 Cookies (optional)

Some platforms (TikTok, Instagram, Twitter/X) require authentication to download private or age-restricted content. Create a cookies.txt in Netscape format:

Option 1: Browser extension

  1. Install Get cookies.txt LOCALLY (Chrome) or cookies.txt (Firefox)
  2. Log in to the platform (TikTok, Instagram, etc.)
  3. Click the extension icon and export as cookies.txt
  4. Place the file in the project root (same directory as run.sh)

Option 2: yt-dlp browser extraction

yt-dlp can extract cookies directly from your installed browser. Close the browser first!

🍎 macOS
pip3 install secretstorage

# Chrome
yt-dlp --cookies-from-browser chrome --cookies cookies.txt "https://www.youtube.com/"
# Safari
yt-dlp --cookies-from-browser safari --cookies cookies.txt "https://www.youtube.com/"
# Firefox
yt-dlp --cookies-from-browser firefox --cookies cookies.txt "https://www.youtube.com/"
🐧 Linux
# Ubuntu/Debian
sudo apt install python3-secretstorage

# Chrome
yt-dlp --cookies-from-browser chrome --cookies cookies.txt "https://www.youtube.com/"
# Firefox
yt-dlp --cookies-from-browser firefox --cookies cookies.txt "https://www.youtube.com/"
🪟 Windows
pip install secretstorage
yt-dlp --cookies-from-browser chrome --cookies cookies.txt "https://www.youtube.com/"
yt-dlp --cookies-from-browser firefox --cookies cookies.txt "https://www.youtube.com/"

⚠️ Note: The browser must be fully closed (not running in background) when extracting cookies.

Option 3: Automatic (built-in) 🔄

The app can generate and keep cookies.txt fresh by itself — no manual export needed.

# Local
MR_COOKIES_BROWSER=chrome ./run.sh

# Docker
docker run -d -p 9292:9292 \
  -e MR_COOKIES_BROWSER=chrome \
  -v ./downloads:/download \
  vndangkhoa/kv-download:latest

On startup, and every 24 hours, it extracts cookies from the configured browser if cookies.txt is missing or older than 7 days. The browser must be installed on the same machine and closed during extraction.

Variable Description Default
MR_COOKIES_BROWSER Browser to extract cookies from (chrome, chromium, firefox, edge, brave, opera, vivaldi, safari) (disabled)
MR_COOKIES_URL Page to visit during extraction https://www.tiktok.com/
MR_COOKIES_MAX_AGE_HOURS Refresh interval for stale cookies 168 (7 days)

💡 On a NAS (no browser), generate cookies once on your PC and copy cookies.txt to the mounted volume — the app will use it as-is and keep it updated between runs.

🚀 TikTok & impersonation: TikTok blocks plain downloads. The app ships with curl_cffi (pinned <0.16 — newer versions break yt-dlp) to impersonate a real browser. If TikTok fails with "no impersonate target is available", run pip install "curl_cffi>=0.15,<0.16" — and note the app auto-retries transient anti-bot failures up to 3 times.

Using cookies.txt

Local:

# Place cookies.txt in the project root — run.sh passes it automatically
./run.sh

Docker:

docker run -d -p 9292:9292 \
  -v ./downloads:/download \
  -v ./cookies.txt:/app/cookies.txt \
  vndangkhoa/kv-download:latest

Docker Compose:

services:
  kv-download:
    image: vndangkhoa/kv-download:latest
    container_name: kv-download
    restart: unless-stopped
    ports:
      - "9292:9292"
    volumes:
      - ./downloads:/download
      - ./cookies.txt:/app/cookies.txt
    environment:
      - TZ=Asia/Ho_Chi_Minh

🔒 Security: cookies.txt contains session tokens. Never commit it to git or share it publicly.

⚠️ Note: cookies.txt must be writable (don't mount it with :ro) — yt-dlp saves cookies back to the file on exit. If it's read-only, downloads will fail with an error.


⚙️ Configuration

Variable Description Default
MR_DOWNLOAD_DIR Directory where videos are saved /download (Docker) / downloads/ (local)
MR_PROXY Proxy URL passed to yt-dlp via --proxy (empty)
MR_COOKIES_BROWSER Auto-extract cookies from browser (chrome, firefox, edge, ...) (disabled)
MR_COOKIES_URL Page to visit during cookie extraction https://www.tiktok.com/
MR_COOKIES_MAX_AGE_HOURS Refresh cookies.txt when older than this 168 (7 days)

📡 API

Get video info (JSON)

GET /api/info?url=VIDEO_URL

Returns:

{
  "media": [
    {
      "Id": "abc123/video.mp4",
      "Name": "video.mp4",
      "SizeInBytes": 1048576,
      "HumanSize": "1.0 MB"
    }
  ],
  "error": ""
}

Download a video

GET /download?id=VIDEO_ID

Streams the video file directly.

Download all as ZIP

GET /download/zip?id=ID1&id=ID2&id=ID3

Bundles multiple videos into a single .zip file.

Bookmarklet

Drag this to your bookmarks bar for one-click downloads from any page:

javascript:(location.href="http://127.0.0.1:9292/fetch?url="+encodeURIComponent(location.href));

🗂️ File Structure

<download-dir>/
├── <hash>/
│   ├── <video-id>.mp4
│   └── <video-id>.mp4
└── json/
    └── <video-id>.info.json

📄 License

MIT


Made with ❤️ by vndangkhoa · Star it on GitHub