From 3544a896095329729489a0c90206d20963077ef8 Mon Sep 17 00:00:00 2001 From: Stefan Waidele Date: Sat, 16 May 2026 20:33:23 +0200 Subject: [PATCH] =?UTF-8?q?Initial=20commit=20=E2=80=94=20yt-dlf=20YouTube?= =?UTF-8?q?=20downloader=20&=20transcript=20extractor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SvelteKit web frontend for yt-dlp and ffmpeg. Paste a YouTube URL to download best-quality video, subtitles (original + EN + DE), and thumbnail. Subtitles are converted to clean Markdown. Optional audio extraction to MP3. Supports ZIP & Send mode: downloaded files are packed into a ZIP and delivered to the browser, with optional server-side cleanup after delivery. An extra directory (ZIP_EXTRA_DIR) can be bundled into every ZIP. Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 26 + .npmrc | 1 + .vscode/extensions.json | 3 + INSTALL.md | 87 + README.md | 61 + jsconfig.json | 13 + package-lock.json | 2542 ++++++++++++++++++++++++++++ package.json | 23 + scripts/create_zip.py | 34 + scripts/subtitle_to_markdown.py | 104 ++ src/app.html | 12 + src/lib/assets/favicon.svg | 1 + src/lib/index.js | 1 + src/lib/server/store.js | 13 + src/lib/subtitle.js | 65 + src/routes/+layout.svelte | 11 + src/routes/+page.svelte | 348 ++++ src/routes/api/download/+server.js | 169 ++ src/routes/api/zip/+server.js | 43 + start.sh | 38 + static/robots.txt | 3 + svelte.config.js | 17 + vite.config.js | 14 + 23 files changed, 3629 insertions(+) create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 .vscode/extensions.json create mode 100644 INSTALL.md create mode 100644 README.md create mode 100644 jsconfig.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100755 scripts/create_zip.py create mode 100755 scripts/subtitle_to_markdown.py create mode 100644 src/app.html create mode 100644 src/lib/assets/favicon.svg create mode 100644 src/lib/index.js create mode 100644 src/lib/server/store.js create mode 100644 src/lib/subtitle.js create mode 100644 src/routes/+layout.svelte create mode 100644 src/routes/+page.svelte create mode 100644 src/routes/api/download/+server.js create mode 100644 src/routes/api/zip/+server.js create mode 100755 start.sh create mode 100644 static/robots.txt create mode 100644 svelte.config.js create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..da0e172 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +node_modules + +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build + +# OS +.DS_Store +Thumbs.db + +# Claude Code +.claude/ + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..28d1e67 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["svelte.svelte-vscode"] +} diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..178270b --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,87 @@ +# Deployment + +## What's in the package + +``` +build/ ← compiled SvelteKit server (self-contained, no npm needed) +scripts/ + subtitle_to_markdown.py ← standalone subtitle converter CLI + create_zip.py ← ZIP creation helper (used internally by the server) +start.sh ← startup script +README.md +INSTALL.md +``` + +## Prerequisites on the Linux server + +Node.js 18 or newer, Python 3, yt-dlp, and ffmpeg must be installed. + +```bash +# ffmpeg, Node.js, and Python via apt +sudo apt install ffmpeg nodejs python3 + +# yt-dlp (latest release) +sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp \ + -o /usr/local/bin/yt-dlp +sudo chmod +x /usr/local/bin/yt-dlp +``` + +## Installation + +```bash +tar -xzf yt-dlf.tar.gz +cd yt-dlf +``` + +## Running + +```bash +./start.sh +``` + +The server listens on port 3000 by default. Open `http://your-server:3000` in a browser. + +## Environment variables + +Edit `start.sh` to configure the variables below, or pass them directly on the command line. + +### General + +| Variable | Default | Purpose | +|---|---|---| +| `PORT` | `3000` | Port to listen on | +| `ORIGIN` | `http://localhost:PORT` | Public URL of the server — set this in production | +| `YTDLP_PATH` | `yt-dlp` | Full path to yt-dlp binary if not on PATH | +| `FFMPEG_PATH` | `ffmpeg` | Full path to ffmpeg binary if not on PATH | +| `DOWNLOAD_DIR` | `~/YouTube` | Directory where downloaded files are stored on the server | + +### ZIP & Send mode + +When `ZIP_AND_SEND=true`, all downloaded files are packed into a ZIP and offered as a browser download instead of (only) being saved on the server. A random prefix is added to the temporary directory name to avoid collisions when multiple users download the same video simultaneously. + +| Variable | Default | Purpose | +|---|---|---| +| `ZIP_AND_SEND` | `false` | Enable ZIP & Send mode | +| `ZIP_EXTRA_DIR` | _(none)_ | Optional directory whose files are added to every ZIP alongside the downloaded files. Subdirectory structure is preserved. | +| `DELETE_AFTER_SEND` | `false` | Delete files from the server after the ZIP has been sent to the browser | +| `DELETE_DELAY` | `0` | Seconds to wait before deleting files after the ZIP has been sent | + +### Examples + +Custom port and public URL: + +```bash +PORT=8080 ORIGIN=http://myserver:8080 ./start.sh +``` + +ZIP & Send with cleanup after 60 seconds: + +```bash +ZIP_AND_SEND=true DELETE_AFTER_SEND=true DELETE_DELAY=60 ./start.sh +``` + +ZIP & Send with extra files bundled into every download: + +```bash +ZIP_AND_SEND=true ZIP_EXTRA_DIR=/opt/yt-dlf/extras ./start.sh +``` diff --git a/README.md b/README.md new file mode 100644 index 0000000..331d01e --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# yt-dlf + +YouTube Downloader & Transcript Extractor — a local web frontend for `yt-dlp` and `ffmpeg`. + +## Features + +- Paste a YouTube URL and download the best available video quality +- Subtitles downloaded automatically in the video's original language, English, and German (where available) +- Subtitles converted to clean Markdown (timestamps stripped, text deduplicated and paragraph-wrapped) +- Optional audio extraction to MP3 via ffmpeg +- Real-time progress log streamed to the browser +- Files saved to `~/YouTube/