How to Download a Video in a Specific Quality with ReClip: A Complete Guide

ReClip uses yt-dlp to expose available video formats via a Flask API, letting you select exact resolutions like 720p or 1080p before downloading.

ReClip provides a lightweight, web-based interface for downloading videos with precise quality control. Built on top of yt-dlp, it exposes three REST endpoints that handle format discovery, download execution, and job status polling. This guide walks through the complete workflow for downloading a video in your preferred quality using the ReClip API.

How ReClip Discovers Available Qualities

Before downloading, you need to know which resolutions are available for your target video. ReClip handles this through the /api/info endpoint, defined in app.py.

The Format Extraction Process

When you POST a URL to /api/info, ReClip executes yt-dlp --no-playlist -j <url> and parses the resulting JSON in the parse_ytdlp_json function. The code filters for video formats and selects the best bitrate format for each distinct height:


# app.py – build quality options

# https://github.com/averygan/reclip/blob/main/app.py#L112-L129

best_by_height = {}
for f in info.get("formats", []):
    height = f.get("height")
    if height and f.get("vcodec", "none") != "none":
        tbr = f.get("tbr") or 0
        if height not in best_by_height or tbr > (best_by_height[height].get("tbr") or 0):
            best_by_height[height] = f

formats = []
for height, f in best_by_height.items():
    formats.append({
        "id": f["format_id"],
        "label": f"{height}p",
        "height": height,
    })
formats.sort(key=lambda x: x["height"], reverse=True)

This ensures you get one clean option per resolution rather than dozens of redundant format codes. The response includes a human-readable label ("720p"), the raw format_id needed for downloading, and the height value.

Fetching Available Formats via API

To retrieve quality options programmatically, send a POST request to /api/info:

curl -s -X POST -H "Content-Type: application/json" \
     -d '{"url":"VIDEO_URL"}' \
     http://localhost:8899/api/info | jq .

Typical response:

{
  "title": "Sample Video",
  "thumbnail": "https://i.ytimg.com/vi/xxxx/default.jpg",
  "duration": 215,
  "uploader": "Channel Name",
  "formats": [
    {"id": "137", "label": "1080p", "height": 1080},
    {"id": "136", "label": "720p", "height": 720},
    {"id": "135", "label": "480p", "height": 480}
  ]
}

Extract the id field from your desired quality — this is the format_id you'll use in the next step.

Starting a Download with Selected Quality

The /api/download endpoint accepts three key parameters:

  • url — the original video link
  • format — "video" (default) or "audio"
  • format_id — the exact format identifier from /api/info

How ReClip Constructs the Download Command

Inside run_download in app.py, the code assembles the yt-dlp command based on your selections:


# app.py – assemble yt-dlp command

# https://github.com/averygan/reclip/blob/main/app.py#L32-L44

cmd = ["yt-dlp", "--no-playlist", "-o", out_template]

if format_choice == "audio":
    cmd += ["-x", "--audio-format", "mp3"]
elif format_id:
    cmd += ["-f", f"{format_id}+bestaudio/best", "--merge-output-format", "mp4"]
else:
    cmd += ["-f", "bestvideo+bestaudio/best", "--merge-output-format", "mp4"]

The critical pattern is -f {format_id}+bestaudio/best. This instructs yt-dlp to:

  1. Download the specific video stream matching your format_id
  2. Merge it with the best available audio track
  3. Output as MP4

Example: Downloading 720p Video

curl -s -X POST -H "Content-Type: audio/json" \
     -d '{"url":"VIDEO_URL","format":"video","format_id":"136","title":"My Video"}' \
     http://localhost:8899/api/download

Response:

{ "job_id": "a1b2c3d4e5" }

The download runs in a background thread to avoid blocking the API. You receive a job_id for tracking progress.

Monitoring Download Progress and Retrieving Files

ReClip uses asynchronous job management. Poll /api/status/<job_id> until completion:

while true; do
  status=$(curl -s http://localhost:8899/api/status/a1b2c3d4e5 | jq -r .status)
  echo "Job status: $status"
  [[ $status == "done" ]] && break
  sleep 2
done

Once status returns "done" (or "error" on failure), fetch your file:

curl -OJ http://localhost:8899/api/file/a1b2c3d4e5

The -OJ flags preserve the server-provided filename based on the video title you specified.

Complete Download Workflow Example

Putting it all together in a single script:

#!/bin/bash
VIDEO_URL="https://example.com/video"
API_BASE="http://localhost:8899"

# Step 1: Get available formats

echo "Fetching available qualities..."
INFO=$(curl -s -X POST -H "Content-Type: application/json" \
     -d "{\"url\":\"$VIDEO_URL\"}" \
     "$API_BASE/api/info")

# Extract first 720p format_id (or change selector as needed)

FORMAT_ID=$(echo "$INFO" | jq -r '.formats[] | select(.label=="720p") | .id')

# Step 2: Start download

echo "Starting download for format_id: $FORMAT_ID"
JOB_RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" \
     -d "{\"url\":\"$VIDEO_URL\",\"format\":\"video\",\"format_id\":\"$FORMAT_ID\",\"title\":\"MyVideo\"}" \
     "$API_BASE/api/download")

JOB_ID=$(echo "$JOB_RESPONSE" | jq -r '.job_id')
echo "Job ID: $JOB_ID"

# Step 3: Poll for completion

while true; do
  STATUS=$(curl -s "$API_BASE/api/status/$JOB_ID" | jq -r '.status')
  echo "Status: $STATUS"
  [[ "$STATUS" == "done" ]] && break
  [[ "$STATUS" == "error" ]] && { echo "Download failed"; exit 1; }
  sleep 2
done

# Step 4: Download file

curl -OJ "$API_BASE/api/file/$JOB_ID"

Key Source Files in ReClip

File Purpose Location
app.py Core Flask API with parse_ytdlp_json(), run_download(), and route handlers [app.py](https://github.com/averygan/reclip/blob/main/app.py)
templates/index.html Web UI that displays the format dropdown and manages the download flow [index.html](https://github.com/averygan/reclip/blob/main/templates/index.html)
requirements.txt Python dependencies including yt-dlp and Flask [requirements.txt](https://github.com/averygan/reclip/blob/main/requirements.txt)
reclip.sh Convenience script to launch the Flask server locally [reclip.sh](https://github.com/averygan/reclip/blob/main/reclip.sh)

Summary

  • Quality discovery: POST to /api/info to get filtered format options grouped by resolution
  • Precise selection: Pass the format_id from your chosen quality to /api/download
  • Background processing: Downloads run asynchronously; poll /api/status/<job_id> for completion
  • yt-dlp integration: ReClip builds commands like -f 136+bestaudio/best to merge specific video streams with optimal audio

This three-endpoint design makes ReClip suitable both for interactive use through its web interface and for automation via shell scripts or external applications.

Frequently Asked Questions

What video platforms does ReClip support?

ReClip supports any platform that yt-dlp handles, including YouTube, Vimeo, Twitter/X, TikTok, and hundreds of others. The quality selection workflow remains identical regardless of source site, though available resolutions vary by platform and video.

Can I download audio-only without video?

Yes. Set "format": "audio" in your /api/download request. According to app.py lines 35-36, this triggers yt-dlp -x --audio-format mp3 for MP3 extraction. You do not need to provide a format_id for audio downloads.

Why does ReClip merge audio separately instead of using pre-merged formats?

Pre-merged formats often sacrifice quality. By selecting bestaudio separately and merging via --merge-output-format mp4, ReClip ensures you get the highest bitrate audio track available regardless of which video stream you chose. This is particularly important for music videos or content where audio quality matters.

How do I run ReClip on a different port?

Default port 8899 is defined in app.py. Modify the app.run() call or set the FLASK_RUN_PORT environment variable before starting. The reclip.sh script can also be edited to pass custom arguments to the Flask development server.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →