Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
de78a00
fix: prevent yt-dlp argument injection via unsanitized URL
robomello Jul 9, 2026
ca3f5ef
chore: bind ReClip to localhost
guoshulin1992-prog Sep 2, 2026
1cf59e6
fix: preserve LF endings for shell scripts
guoshulin1992-prog Sep 2, 2026
a015d28
fix: prevent yt-dlp argument injection via unsanitized URL
robomello Jul 9, 2026
b9e388f
feat: normalize structured download progress
guoshulin1992-prog Sep 2, 2026
80b158c
feat: stream downloader output with bounded lifecycle
guoshulin1992-prog Sep 2, 2026
2de1d81
feat: expose live progress through job status API
guoshulin1992-prog Sep 2, 2026
08ed873
feat: show download speed and current-stream progress
guoshulin1992-prog Sep 2, 2026
b44bd15
build: keep shell entrypoint linux-compatible
guoshulin1992-prog Sep 2, 2026
14d1644
feat: add resumable download task persistence
guoshulin1992-prog Sep 2, 2026
4654569
merge: integrate resumable downloads
guoshulin1992-prog Sep 2, 2026
f917113
feat: persist cancellable download states
guoshulin1992-prog Sep 2, 2026
262b7b5
feat: stop download processes on cancellation
guoshulin1992-prog Sep 2, 2026
bf6e97d
feat: add cancellable download tasks
guoshulin1992-prog Sep 2, 2026
3d9f825
docs: document cancelling download tasks
guoshulin1992-prog Sep 2, 2026
620f756
build: exclude development ledger from image
guoshulin1992-prog Sep 2, 2026
942be30
merge: integrate cancellable downloads
guoshulin1992-prog Sep 2, 2026
e496062
fix: use portable force-stop signal fallback
guoshulin1992-prog Sep 2, 2026
f57a353
merge: include portable cancellation cleanup fix
guoshulin1992-prog Sep 2, 2026
76f229c
fix: allow taskkill time to finish on Windows
guoshulin1992-prog Sep 2, 2026
44d7f40
merge: improve Windows cancellation cleanup
guoshulin1992-prog Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
.git
.gitignore
downloads
venv
.venv
tests
.superpowers
__pycache__
*.pyc
*.pyo
Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sh text eol=lf
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
venv/
.venv/
downloads/
__pycache__/
*.pyc
Expand All @@ -7,4 +8,4 @@ assets/*.mov
.env
.env.local
.env.production
.env.development
.env.development
45 changes: 40 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ https://github.com/user-attachments/assets/419d3e50-c933-444b-8cab-a9724986ba05
- Bulk downloads — paste multiple URLs at once
- Automatic URL deduplication
- Clean, responsive UI — no frameworks, no build step
- Single Python file backend (~150 lines)
- Live download progress, speed, size and ETA
- Resumable task records for interrupted downloads
- Cancel active downloads while preserving their partial files for later continuation

## Quick Start

Expand All @@ -28,14 +30,17 @@ cd reclip
./reclip.sh
```

Open **http://localhost:8899**.
Open **http://127.0.0.1:8899**.

Or with Docker:

```bash
docker build -t reclip . && docker run -p 8899:8899 reclip
docker compose up --build -d
```

The Compose configuration publishes the service on `127.0.0.1:8899`, so it is
available only on the local computer by default.

## Usage

1. Paste one or more video URLs into the input box
Expand All @@ -44,6 +49,36 @@ docker build -t reclip . && docker run -p 8899:8899 reclip
4. Select quality/resolution if available
5. Click **Download** on individual videos, or **Download All**

### Interrupted downloads

Downloads are stored under the Docker volume mounted at `/app/downloads`.
Task records and resumable media are kept in `.reclip/jobs.sqlite3` and
`.reclip/jobs/<job_id>/`. If a download fails or the container is restarted,
open the page again and use **Continue** on the interrupted task. ReClip checks
the saved media identity before asking yt-dlp to reuse its partial files.

Continuation depends on the source and media protocol. If the source changes,
does not support byte ranges or no longer exposes the selected format, ReClip
will refuse to append to the old task; use **Restart** to create a new task.
The application does not automatically start interrupted downloads after a
container restart. Completed files can be saved again from the task list.

### Cancelling downloads

Click **Cancel** on an active task to stop its current downloader process. The
task first shows **Cancelling** while ReClip confirms that the process and its
children have stopped; only then is it marked **Cancelled**. Partial files and
the last known progress are preserved, and no completed file is published.

For a cancelled task, **Continue** creates the next attempt in the same task
and asks yt-dlp to reuse compatible partial files. **Restart** creates a new
task from the original URL. **Delete** removes the task record and its task
directory after confirmation.

Task history now retains the source URL, title and partial files until the task
is explicitly deleted. Do not expose this local service to the public network;
the first version has no user authentication.

## Supported Sites

Anything [yt-dlp supports](https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md), including:
Expand All @@ -52,10 +87,10 @@ YouTube, TikTok, Instagram, Twitter/X, Reddit, Facebook, Vimeo, Twitch, Dailymot

## Stack

- **Backend:** Python + Flask (~150 lines)
- **Backend:** Python + Flask with a SQLite task store
- **Frontend:** Vanilla HTML/CSS/JS (single file, no build step)
- **Download engine:** [yt-dlp](https://github.com/yt-dlp/yt-dlp) + [ffmpeg](https://ffmpeg.org/)
- **Dependencies:** 2 (Flask, yt-dlp)
- **Dependencies:** Flask, yt-dlp, ffmpeg and the Python standard library

## Disclaimer

Expand Down
Loading