How to Download Audio in MP3 Format with ReClip: A Complete Guide

ReClip downloads MP3 audio by invoking yt-dlp with the -x --audio-format mp3 flags through its Flask backend when users select the MP3 pill in the web interface.

ReClip is an open-source media downloader by averygan/reclip that combines a lightweight Flask backend with the yt-dlp library to extract and convert video streams. The application supports direct MP3 conversion by leveraging ffmpeg for audio re-encoding, enabling users to save audio tracks without manual post-processing. Understanding the exact flow from UI selection to file delivery allows developers to customize extraction settings or troubleshoot dependency issues.

How ReClip Handles MP3 Conversion

The MP3 workflow relies on a three-tier architecture: the frontend sends a format preference to the Flask API, the backend constructs a yt-dlp command with audio-specific flags, and ffmpeg handles the actual transcoding. When the user selects MP3 in the interface, the currentFormat variable updates to "audio" via the button’s data-format="audio" attribute located in templates/index.html at lines 95-97. This value persists through the API call to trigger the audio extraction path in app.py.

Step-by-Step MP3 Download Flow

1. Select MP3 Format in the UI

The user clicks the MP3 pill button, which toggles the active state and sets the global format variable. This interaction updates currentFormat to "audio" (as opposed to video formats), signaling the backend to extract rather than merge streams.

2. Fetch Video Metadata

The client sends a request to /api/info to retrieve the video title, thumbnail, and available stream formats. This step validates the URL and populates the download card before the user commits to the extraction.

3. Trigger the Download Request

Upon clicking Download, the frontend POSTs to /api/download (lines 66-84 in app.py) with a JSON payload including the target URL and format: "audio". The backend generates a unique job_id (UUID) to track the asynchronous operation.

4. Backend Audio Extraction

The run_download function in app.py (lines 38-40) constructs the yt-dlp command. For MP3 requests, it appends the -x (extract audio) and --audio-format mp3 flags, then executes via subprocess.run. This command requires ffmpeg to be installed on the host system to handle the codec conversion.

5. Poll for Job Completion

The client polls /api/status/<job_id> (lines 87-95) until the job dictionary reports "status": "done". During this phase, the backend monitors the subprocess output and updates the job state accordingly.

6. Retrieve the MP3 File

Once processing completes, the browser requests /api/file/<job_id> (lines 99-104), which streams the generated MP3 file from the DOWNLOAD_DIR using Flask’s send_file method.

Required Dependencies

Because ReClip delegates encoding to external tools, the host must have ffmpeg installed and available in the system PATH. Without it, the --audio-format mp3 flag will fail silently or raise a conversion error. Install via your package manager (e.g., brew install ffmpeg on macOS or apt install ffmpeg on Ubuntu) before starting the application.

Code Implementation Details

Frontend: Selecting MP3 and Initiating Download

The JavaScript handles format selection and initiates the POST request to the download endpoint:

// Switch to MP3 mode
function setFormat(btn) {
  document.querySelectorAll('.pill').forEach(b => b.classList.remove('active'));
  btn.classList.add('active');
  currentFormat = btn.dataset.format;   // "audio" for MP3
}

// Trigger download for a single card
async function dlCard(idx) {
  const c = cardData[idx];
  c.status = 'downloading';
  renderCard(idx);
  const res = await fetch('/api/download', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      url: c.url,
      format: currentFormat,          // "audio"
      format_id: c.selectedFormatId,
      title: c.title || '',
    }),
  });
  const data = await res.json();
  // …polling logic follows…
}

Backend: Building the yt-dlp Command

The run_download function dynamically constructs the command array based on the format_choice parameter:

def run_download(job_id, url, format_choice, format_id):
    out_template = os.path.join(DOWNLOAD_DIR, f"{job_id}.%(ext)s")
    cmd = ["yt-dlp", "--no-playlist", "-o", out_template]

    if format_choice == "audio":                     # <-- MP3 path

        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"]
    cmd.append(url)
    # Run yt‑dlp and handle results …

Polling for Completion

The status endpoint returns the current state of the background job:

@app.route("/api/status/<job_id>")
def check_status(job_id):
    job = jobs.get(job_id)
    if not job:
        return jsonify({"error": "Job not found"}), 404
    return jsonify({
        "status": job["status"],
        "error": job.get("error"),
        "filename": job.get("filename"),
    })

Summary

  • Format Selection: The UI sets currentFormat to "audio" via data-format="audio" in templates/index.html.
  • API Endpoint: POST /api/download receives the request and spawns a background job identified by a UUID.
  • Audio Extraction: app.py constructs a yt-dlp command with -x --audio-format mp3 to extract and convert streams.
  • Dependency: ffmpeg must be installed on the server to handle MP3 encoding.
  • Delivery: The client polls /api/status/<job_id> and retrieves the final file from /api/file/<job_id>.

Frequently Asked Questions

What dependencies are required for MP3 conversion?

ReClip requires ffmpeg to be installed on the host system. The backend invokes yt-dlp with the --audio-format mp3 flag, which shells out to ffmpeg for the actual audio transcoding. Without this dependency, the extraction process will fail.

How does ReClip convert video to MP3?

According to the source code in app.py, the backend checks if format_choice == "audio" and appends the -x (extract audio) and --audio-format mp3 flags to the yt-dlp command. This extracts the best audio stream and re-encodes it into MP3 format using ffmpeg.

How does the frontend communicate the MP3 format choice?

The frontend stores the selection in a global currentFormat variable when the user clicks the MP3 pill button defined in templates/index.html at lines 95-97. This value is passed as the format property in the JSON body of the POST request to /api/download.

Where are downloaded MP3 files stored temporarily?

Files are written to the DOWNLOAD_DIR directory using a filename template of {job_id}.%(ext)s. The job_id is a UUID generated at the start of the request, ensuring unique filenames for concurrent downloads.

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 →