The download endpoint served files under their internal uuid-based
storage name; it now builds the Content-Disposition filename from the
probed video title (persisted on submit) with the original extension,
falling back to the old behavior when no title is available. The
status page also gets an always-visible link back to the homepage.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Options (quality, subtitles) are now derived from a yt-dlp -J probe of
the submitted URL instead of a static list, so users can't pick
combinations the source video doesn't actually support. Submission is
blocked until the probe succeeds.
- New /api/probe endpoint + src/lib/ytdlp-probe.ts, with its own rate
limiter (rate-limit.ts refactored into a createRateLimiter factory).
- New options: subtitle language selection, clip start/end trim, MP3
audio quality.
- Fixed buildYtdlpArgs: format=mp3 never triggered audio extraction
(-x/--audio-format), and quality=best never applied --merge-output-format,
so the chosen container had no real effect.
- Cross-platform yt-dlp invocation: the bundled bin/yt-dlp is a Python
zipapp relying on a shebang, which Windows' spawn() can't run
directly. buildYtdlpCommand() runs it through `python` on Windows and
execs it directly on Linux/o2switch, where the shebang works natively.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>