master
yt-dlp HLS Proxy
A simple Flask proxy server that uses yt-dlp to fetch HLS streams and serves them through a web player.
Features
- HLS stream proxying via yt-dlp
- In-memory caching (365 days TTL by default)
- URL validation with allowed domains
- HTML5 video player with hls.js
- Configurable via environment variables
- Full metadata display (title, description, views, likes, tags, etc.)
Quick Start
Option 1: Direct Python
pip install -r requirements.txt
python app.py
Visit http://localhost:5000 and enter a video URL.
Option 2: Docker
# Build and run
docker-compose up -d
# Or pull from GitHub Container Registry (if available)
docker pull ghcr.io/yourusername/yt-dlp-proxy:latest
docker run -p 5000:5000 ghcr.io/yourusername/yt-dlp-proxy:latest
Option 3: Docker Build
docker build -t yt-dlp-proxy .
docker run -p 5000:5000 yt-dlp-proxy
Configuration
| Variable | Default | Description |
|---|---|---|
| PORT | 5000 | Server port |
| LOG_LEVEL | INFO | Logging level |
| CACHE_TTL | 31536000 | Cache TTL in seconds (365 days) |
| SOCKET_TIMEOUT | 30 | Socket timeout for requests |
| VALIDATION_ENABLED | true | Enable URL validation |
| ALLOWED_DOMAINS | youtube.com,youtu.be,pornhub.com,xvideos.com | Allowed video domains |
| ALLOW_LOCAL | true | Allow localhost/127.0.0.1 URLs (for testing) |
Docker Environment Variables
docker run -e PORT=5000 -e LOG_LEVEL=INFO -p 5000:5000 yt-dlp-proxy
Docker Compose Example
version: '3.8'
services:
yt-dlp-proxy:
image: yt-dlp-proxy
ports:
- "5000:5000"
environment:
- PORT=5000
- LOG_LEVEL=INFO
- CACHE_TTL=31536000
- ALLOWED_DOMAINS=youtube.com,youtu.be,pornhub.com,xvideos.com
restart: unless-stopped
Routes
/- Home page with video URL input/player?url=VIDEO_URL- Video player page with full metadata/hls/<encoded_url>--index.m3u8- HLS main playlist/hls/<encoded_url>--<segment>.ts- HLS segment
Connecting External Player
URL Format
The proxy uses this format: /hls/<encoded_video_url>--<filename>
Example for PornHub:
/hls/https%3A%2F%2Frt.pornhub.com%2Fview_video.php%3Fviewkey%3D69c13273df690--index.m3u8
Using with yt-dlp (as browser substitute)
# Get playlist URL via proxy
yt-dlp --hls-use-mpegts --no-download --print url \
"http://localhost:5000/hls/https%3A%2F%2Frt.pornhub.com%2Fview_video.php%3Fviewkey%3D69c13273df690--index.m3u8"
Using with VLC
- Open Network Stream (Ctrl+N)
- Enter:
http://localhost:5000/hls/<encoded_url>--index.m3u8
Using with mpv
mpv "http://localhost:5000/hls/https%3A%2F%2Frt.pornhub.com%2Fview_video.php%3Fviewkey%3D69c13273df690--index.m3u8"
Using with any HLS-compatible player
Most players accept the m3u8 URL directly:
http://localhost:5000/hls/<encoded_video_url>--index.m3u8
Where <encoded_video_url> is the URL-encoded original video URL.
Example - full URL:
http://localhost:5000/hls/https%3A%2F%2Frt.pornhub.com%2Fview_video.php%3Fviewkey%3D69c13273df690--index.m3u8
Python example (using requests + hlsjs)
import requests
video_url = "https://rt.pornhub.com/view_video.php?viewkey=69c13273df690"
from urllib.parse import quote
encoded = quote(video_url, safe="")
hls_url = f"http://localhost:5000/hls/{encoded}--index.m3u8"
response = requests.get(hls_url)
print(response.text) # Contains rewritten segment URLs
Running with Gunicorn
gunicorn -w 4 -b 0.0.0.0:5000 app:app
Testing
pytest tests/test_proxy.py -v
Supported Sites
- PornHub (primary - HLS)
- YouTube (direct URL fallback, no HLS)
- Any site supported by yt-dlp
License
MIT
Languages
Python
71.1%
HTML
27.6%
Dockerfile
1.3%