This repository is a trimmed runtime-focused fork of yt-dlp.
It keeps:
- the
yt_dlp/downloader package - the
web_app/FastAPI Web UI - local start scripts and Docker Compose deployment files
It removes upstream CI, tests, release tooling, and other maintenance assets that are not needed to run the project.
- Password-protected Web UI for video/audio downloads
- Metadata extraction before download
- Background downloads with SSE progress updates
- Download history stored in SQLite
- Optional proxy settings managed from the Web UI
- Optional Bilibili cookie settings for login-required or anti-bot-gated videos
- Standard
yt-dlpPython package and CLI remain available
Requirements:
- Python 3.10+
ffmpeg/ffprobenodeavailable inPATHor configured viaYTDLP_NODE_PATH
Start with the helper script:
./start-web.shIf you want admin login protection locally:
YTDLP_ADMIN_PASSWORD='change-me' \
YTDLP_SESSION_SECRET='replace-with-a-random-secret' \
./start-web.shManual alternative:
python -m pip install -e ".[default]"
python -m pip install -r web_app/requirements.txt
python -m web_appOpen http://localhost:8081.
Quick start:
cp .env.example .env
docker compose up -d --buildOpen http://localhost:8081.
git clone https://github.com/sn1p4am/videodd.git
cd videodd
cp .env.example .envEdit .env and set at least:
YTDLP_PUBLIC_PORT=8081
YTDLP_ADMIN_PASSWORD=use-a-strong-password
YTDLP_SESSION_SECRET=use-a-long-random-secret
YTDLP_SESSION_SECURE=trueIf you are accessing the service over plain http:// during local or temporary testing, set:
YTDLP_SESSION_SECURE=falseUse YTDLP_SESSION_SECURE=true only when the browser is actually accessing the site over HTTPS.
Start the service:
docker compose up -d --buildUseful commands:
docker compose ps
docker compose logs -f yt-dlp-web
docker compose restart yt-dlp-web
docker compose downUpdate after pulling changes:
git pull
docker compose up -d --buildPersistent data lives in ./data:
./data/downloadsfor finished downloads./data/ytdlp_web.dbfor history, proxy settings, and saved site cookies
If you expose the service publicly, put it behind HTTPS and keep YTDLP_SESSION_SECURE=true.
If you use Nginx Proxy Manager on the same server and want to bind a domain:
- Keep this service listening on port
8081 - In Nginx Proxy Manager, create a new Proxy Host
- Set your domain name, for example
video.example.com - Forward to:
- Scheme:
http - Forward Hostname / IP: your server IP or
127.0.0.1 - Forward Port:
8081
- Scheme:
- In the SSL tab, request or attach a certificate
- Access the site from
https://your-domain
Recommended .env values for a domain deployment:
YTDLP_PUBLIC_PORT=8081
YTDLP_ADMIN_PASSWORD=use-a-strong-password
YTDLP_SESSION_SECRET=use-a-long-random-secret
YTDLP_SESSION_SECURE=true
YTDLP_ALLOWED_HOSTS=video.example.com
YTDLP_SESSION_DOMAIN=video.example.comNotes:
YTDLP_ALLOWED_HOSTSis optional but recommended. It rejects unexpectedHostheaders and limits the app to your real domain.YTDLP_SESSION_DOMAINis optional. Leave it empty unless you want to pin the login cookie to a specific domain.- If you use multiple hostnames, separate them with commas:
YTDLP_ALLOWED_HOSTS=video.example.com,www.video.example.com- After changing
.env, rebuild and restart:
docker compose down
docker compose up -d --buildAfter login, the header contains a small settings button.
From there you can:
- enable or disable an outbound proxy
- set the proxy URL
- choose whether the proxy applies to foreign sites only or all sites
- enable or disable Bilibili cookies
- scan a Bilibili login QR code to update cookies
- paste or clear Bilibili cookies manually
Proxy is disabled by default.
Some Bilibili videos return HTTP 412 Precondition Failed when requested from a server without a browser login session. This is usually Bilibili anti-bot or login-state gating, not a Docker or ffmpeg problem.
To handle those cases:
- In this Web UI, open the settings button in the top right.
- Click
扫码登录 B 站, or切换 Cookieif cookies already exist. - Use the Bilibili mobile app to scan and confirm login.
- Wait for the page to show that the Bilibili cookies were updated.
- Retry metadata extraction or download.
Manual fallback:
- Log in to Bilibili in your browser.
- Open developer tools on a
bilibili.compage and copy the requestCookieheader, or export a Netscapecookies.txt. - Enable
B 站 Cookie, paste the Cookie content, and save.
Recommended cookie content includes SESSDATA. If SESSDATA is missing, the app will still save the cookie, but Bilibili may continue to reject the request.
Cookies are stored in ./data/ytdlp_web.db. Treat this file as sensitive.
| Variable | Default | Description |
|---|---|---|
YTDLP_DOWNLOAD_DIR |
web_app/downloads |
Download directory |
YTDLP_DB_PATH |
web_app/ytdlp_web.db |
SQLite database path |
YTDLP_HOST |
0.0.0.0 |
Bind host |
YTDLP_PORT |
8081 |
Bind port |
YTDLP_MAX_CONCURRENT |
3 |
Max concurrent downloads |
YTDLP_NODE_PATH |
auto-detect | Node executable or absolute path |
YTDLP_PROXY_URL |
unset | Initial proxy URL on first startup |
YTDLP_PROXY_MODE |
foreign-only |
Initial proxy mode on first startup |
YTDLP_ADMIN_PASSWORD |
unset | Enables login protection |
YTDLP_SESSION_SECRET |
dev fallback | Session signing secret |
YTDLP_SESSION_DOMAIN |
unset | Optional cookie domain for login sessions |
YTDLP_SESSION_SECURE |
false |
Set true behind HTTPS |
YTDLP_SESSION_MAX_AGE |
43200 |
Session lifetime in seconds |
YTDLP_ALLOWED_HOSTS |
* |
Comma-separated allowed Host headers for domain deployments |
.
├── Dockerfile
├── compose.yml
├── start-web.sh
├── pyproject.toml
├── web_app/
└── yt_dlp/