The Problem
Downloading media from many sites requires a separate tool per platform, manual handling of yt‑dlp/ffmpeg arguments, and a UI for non‑technical users. Teams that self‑host a downloader need a single, lightweight service that exposes a clean web interface without a heavy stack.
What This Does
reclip is a self‑hosted Flask application that wraps yt‑dlp and ffmpeg. The backend lives in a single file, app.py, which defines six routes (index, get_info, start_download, check_status, plus helper run_download and download_file). The UI is a single HTML page (templates/index.html) with vanilla CSS/JS, served by Flask’s static folder (static/favicon.svg).
app.py– 6 functions; two of them invoke external commands and read/write temporary files.reclip.sh– a shell wrapper used in the quick‑start guide; its exact logic is not disclosed but it launches the service.Dockerfile– builds a container frompython:3.12‑slim, copies the source, installsFlaskandyt‑dlp, and runs the app.
All assets (preview images, example video) are under assets/ and are unrelated to runtime.
How It Is Wired
Execution starts at app.py. When the script is run (python app.py or via the Docker CMD), Flask creates an HTTP server on port 8899.
index– servestemplates/index.html. No external effect.get_info– called by the UI to fetch metadata. It runsyt‑dlpwith--dump-jsonviasubprocess, captures stdout, and returns JSON to the browser. This is the first external‑command touch.start_download– receives the user’s format choice (MP4/MP3) and desired quality. It spawns a background thread that callsrun_download.run_download– builds theyt‑dlpcommand line (includingffmpegfor audio extraction when MP3 is selected) and executes it. The command writes the resulting file into a temporary directory; the function returns the file path. This is the second external‑command touch and the only file‑write path.check_status– polls the background thread’s state and reports completion. When finished, the UI presents a download link that serves the file directly from the temporary location.
No other Python modules are imported; the import graph consists solely of the single app module, so there is no intra‑project coupling or circular dependency. All side‑effects are confined to the two functions that invoke subprocesses and write files, giving a clear blast radius.
How To Use It
# Prereqs (per README)
brew install yt-dlp ffmpeg # or apt install ffmpeg && pip install yt-dlp
# Local run
git clone https://github.com/moses-y/reclip
cd reclip
./reclip.sh # wrapper that starts the Flask server
# then open http://localhost:8899
# Docker alternative
docker build -t reclip . && docker run -p 8899:8899 reclip
No additional configuration files or environment variables are required; the service relies on the system‑installed yt‑dlp and ffmpeg binaries.
Real‑World Use
A corporate intranet could deploy the Docker image behind an internal reverse proxy, allowing employees to download training videos from YouTube or Vimeo without leaving the network. The UI can be embedded in an existing portal via an iframe; the backend isolates the heavy ffmpeg work in a separate container, keeping the host environment clean.
Code Health & Issues
- High – Add a build gate for the Docker image – no CI workflow validates the image (
Dockerfile). - Medium – Enable Dependabot or Renovate – only
requirements.txtpresent; no automated dependency updates. - Medium – Pin the base image by digest – Dockerfile uses mutable tag
python:3.12‑slim. - Medium – Add a non‑root USER – Dockerfile runs the app as root.
- Medium – No test suite – repository contains no
tests/directory. - Medium – No CI pipeline – no
.github/workflows/or similar. - Low – No lockfile –
requirements.txtwithout arequirements.lockmakes builds non‑reproducible.
All findings are derived from static analysis; no additional issues were detected.
The Bottom Line
reclip delivers a minimal, functional web UI around yt‑dlp and ffmpeg with a single‑file Flask backend, making it easy to self‑host. The codebase is tiny and straightforward but lacks automated testing, CI, and hardened container practices. It is suitable for small internal teams that can accept the operational risk or are willing to add a CI pipeline and container hardening before production use.