yt-dlf/INSTALL.md
Claude Fable 5 a3eb962b90 Transcribe videos without subtitles via faster-whisper fallback
When yt-dlp yields no subtitle files, the server now runs
scripts/transcribe.py (faster-whisper, large-v3-turbo, CUDA with CPU
fallback) on the downloaded media and feeds the resulting VTT through
the existing Markdown conversion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P1w53ybPWArpZpcei9JPYX
2026-08-29 22:20:55 +02:00

137 lines
4.6 KiB
Markdown

# 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)
add_user.py ← user management CLI
start.sh ← startup script
users.txt ← user database (hashed passwords)
ads-left.html ← ad content for the left column (edit freely)
ads-right.html ← ad content for the right column (edit freely)
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
```
## User management
Unauthenticated visitors see the app with ad columns. Logged-in users see no ads.
The login page is at `/login` (not linked from the main page).
Add or update a user:
```bash
python3 scripts/add_user.py <username> <password>
```
Users are stored in `users.txt` (one entry per line, scrypt-hashed passwords).
Sessions are held in memory — they reset when the server restarts.
## Ad content
Edit `ads-left.html` and `ads-right.html` to replace the placeholder content with real ads.
The server caches these files at startup — restart the server after editing them.
## 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 |
| `USERS_FILE` | `users.txt` next to `start.sh` | Path to the user database file |
| `ADS_DIR` | same directory as `start.sh` | Directory containing `ads-left.html` and `ads-right.html` |
### Whisper transcription fallback
When a download yields no subtitles (e.g. Instagram, archive.org), the server
transcribes the media locally with [faster-whisper](https://github.com/SYSTRAN/faster-whisper)
and feeds the result through the same VTT→Markdown conversion. The fallback
is skipped with a warning if faster-whisper is not installed.
Setup (GPU recommended; the pip-installed cuBLAS/cuDNN libraries are found
automatically, no `LD_LIBRARY_PATH` needed):
```bash
python3 -m venv .venv
.venv/bin/pip install faster-whisper "nvidia-cublas-cu12<13" "nvidia-cudnn-cu12<10"
```
The model (~1.6 GB for `large-v3-turbo`) is downloaded from Hugging Face on
first use and cached in `~/.cache/huggingface`.
| Variable | Default | Purpose |
|---|---|---|
| `WHISPER_PYTHON` | `python3` | Python interpreter with faster-whisper installed (e.g. `.venv/bin/python`) |
| `WHISPER_MODEL` | `large-v3-turbo` | faster-whisper model name (`large-v3` for best quality, `small` for low-end machines) |
| `WHISPER_DEVICE` | _(auto)_ | Force `cuda` or `cpu`; by default CUDA is tried first with CPU fallback |
### 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
```