Files
Mikhail Yevchenko a468a7a268 Add docker support
2026-04-01 20:41:52 +00:00

3.7 KiB

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

  1. Open Network Stream (Ctrl+N)
  2. 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