Skip to main content

Command Palette

Search for a command to run...

How to create youtube video Downloader

Updated
7 min read
How to create youtube video Downloader

Have you saw a you tube video Downloader website that have millions of traffic every month and builder of that website are earning thousands of Doller from that website and as a Developer you think that what happen if i also able to create this type of website, then i can able to pay my Collage Fee or Do college party. Then you land to right Article. In this Article. I will guide you that how you can also build this type of website.

To Build a you tube video Downloader website you must know some Guideline of you tube that If you downloaded you tube video outside of youtube this is illegal according to youtube Term & Condition. But For Educational purpose or for personal use if you want to build. Then Python and Node js Is most popular for this type website Backend But some people also prefer to PHP.

Why you should Follow this article

I am a full stack developer in MERN stack but I also use fast Api for backed because this fast and I love this Automatic Documentation. I Have build a fully Functional website that support multiple platform video downloader called socailsaver.app using same method that i am guiding you. So you can confidently trust on this article.

How to Build youtube video Downloader using python

To Build youtube video Downloader website using python you need to use a most popular universal video Downloader python library called yt-dlp. This library will help us to build and achieve video downloader website goal in easy and fast minor and for fronted you can use any fronted framework or Library like React, Vue , Next js or other according to you.

Tool you need to Use :-

  1. Python as a programing language.

  2. Any one Backend framework to build Backed like FastApi, Django or flask. My suggestion is FastApi

  3. Yt-dlp for video Downloading process

  4. One fronted library or framework to deign UI

To Build Downloader website using python. first start with setting up deployment environment. So you can build and test app in local before deployment.

This is not development server setup guide So please. Refer this guide to setup development environment

  1. Refer this guide to setup development server using flask

  2. Refer this guide to setup development server using dingo environment

  3. Refer this guide to setup development server using Django

After setup up development server install yt-dlp as a dependencies using this command

pip install yt-dlp

Build Youtube video Downloader using Flask

After setup development environment. Now we are ready to build import yt-dlp and create a new endpoint/API called video and inside this write code spawn a new yt-dlp process every time when even come a new request to that endpoint and send response Downloadable video URL as response.

Here is full code:-

import subprocess
import json

from flask import Flask, request, jsonify
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

# -----------------------------------
# Helper function to spawn yt-dlp
# -----------------------------------
def get_video_url(video_url):
    command = [
        "yt-dlp",
        "--no-warnings",
        "-J",         # Output metadata as JSON
        video_url
    ]

    try:
        result = subprocess.run(
            command,
            capture_output=True,
            text=True,
            timeout=25
        )

        if result.returncode != 0:
            raise Exception(result.stderr)

        data = json.loads(result.stdout)
        formats = data.get("formats", [])

        if not formats:
            raise Exception("No downloadable formats found")

        # Best quality = last format
        downloadable_url = formats[-1].get("url")

        if not downloadable_url:
            raise Exception("Could not extract download link")

        return downloadable_url

    except Exception as e:
        raise Exception(f"Failed to process video: {str(e)}")

# -----------------------------------
# Flask App Setup
# -----------------------------------
app = Flask(__name__)

# Rate limit: 10 requests/min per IP
limiter = Limiter(
    key_func=get_remote_address,
    app=app,
    default_limits=["10 per minute"]
)

# -----------------------------------
# /video endpoint (GET + query param)
# -----------------------------------
@app.route("/video", methods=["GET"])
@limiter.limit("10 per minute")
def video():
    try:
        video_url = request.args.get("url")  # <-- query param

        if not video_url:
            return jsonify({"error": "Missing required parameter: url"}), 400

        download_url = get_video_url(video_url)

        return jsonify({
            "status": "success",
            "download_url": download_url
        })

    except Exception as e:
        return jsonify({"error": str(e)}), 500

if __name__ == "__main__":
    app.run(debug=True)

It will return Downloadable video URL as response

{
"download_url": "<https://rr3---sn-ci5gup-cvhez.googlevideo.com/videoplayback?expire=1764613669&ei=xIktafTjNo33pt8P3eyUsAw&ip=2401%3A4900%3A36b4%3Ad362%3A3d55%3A66d7%3A6c63%3Af098&id=o-APl5OTkaqigVBUN8cgcBq98B1d0rr1p73QMLrukZVbI_&itag=401&source=youtube&requiressl=yes&xpc=EgVo2aDSNQ%3D%3D&cps=436&met=1764592068%2C&mh=7c&mm=31%2C26&mn=sn-ci5gup-cvhez%2Csn-h5576nsl&ms=au%2Conr&mv=m&mvi=3&pl=48&rms=au%2Cau&initcwndbps=370000&bui=AdEuB5TNOmcFPFHB1yyezoWLf_fF5X8c3bx_0KNGtha2JR9-htLmll8d7JuEHqN6kDZEABzRX10798jM&spc=6b0G_PI1HDOCpfPy4w&vprv=1&svpuc=1&mime=video%2Fmp4&rqh=1&gir=yes&clen=238254945&dur=213.040&lmt=1749085188214713&mt=1764591681&fvip=1&keepalive=yes&fexp=51552689%2C51565115%2C51565681%2C51580968&c=ANDROID&txp=4532534&sparams=expire%2Cei%2Cip%2Cid%2Citag%2Csource%2Crequiressl%2Cxpc%2Cbui%2Cspc%2Cvprv%2Csvpuc%2Cmime%2Crqh%2Cgir%2Cclen%2Cdur%2Clmt&sig=AJfQdSswRQIgZvUbtZxJ-iq_HT1LbrKYV3YKrMl_zMpTWsjOpzHajHwCIQD3EA3Oansga4Pipz9IaLPqE6I7tt5c7YCh1aYYiMncPw%3D%3D&lsparams=cps%2Cmet%2Cmh%2Cmm%2Cmn%2Cms%2Cmv%2Cmvi%2Cpl%2Crms%2Cinitcwndbps&lsig=APaTxxMwRAIgfkeYoPH3_q27lSXNn-YozBc3o85VSwK62E2XnzEo604CID3d793yc7sN9HvXyMtKfJofhpkGZCzWET2IiDbjmjWS>",
"status": "success"
}

Build You tube video Downloader using FastApi

I have already told you how to build using flask but problem in flask that this is not optimize for production grade security, load and performance so please use FastApi.

To build using fastApi follow this

  1. setup development environment

  2. install this yt-dlp, fastApi and other based on what functionality you want to add extra

  3. After that import yt-dlp and express and create a end point for video download

  4. Inside that Api run yt-dlp using spawn or direct native library calling

  5. To customize any functionality of yt-dlp refer their docs

here is code

from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
from slowapi import Limiter
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded

import subprocess
import json

# ------------------------------------
# FastAPI App & Rate Limiter
# ------------------------------------
limiter = Limiter(key_func=get_remote_address)

app = FastAPI()

# Rate limit error handler
@app.exception_handler(RateLimitExceeded)
def rate_limit_handler(request, exc):
    return JSONResponse(
        status_code=429,
        content={"error": "Too many requests. Try again later."}
    )

# ------------------------------------
# Helper function to spawn yt-dlp
# ------------------------------------
def get_download_link(video_url: str):
    command = [
        "yt-dlp",
        "--no-warnings",
        "-J",        # Return metadata as JSON
        video_url
    ]

    result = subprocess.run(
        command,
        capture_output=True,
        text=True,
        timeout=25
    )

    if result.returncode != 0:
        raise Exception(result.stderr.strip())

    data = json.loads(result.stdout)
    formats = data.get("formats", [])

    if not formats:
        raise Exception("No downloadable formats found")

    # Best quality = last format entry
    download_link = formats[-1].get("url")

    if not download_link:
        raise Exception("Failed to extract video URL")

    return download_link

# ------------------------------------
# /video Endpoint (GET)
# ------------------------------------
@app.get("/video")
@limiter.limit("10/minute")
def video(request: Request, url: str):
    try:
        download_url = get_download_link(url)
        return {"status": "success", "download_url": download_url}

    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

How to build Youtube Video Downloader using nodejs

Now let's talk how to build using node js. Node js is a very popular runtime environment for building backed in node js but this is less performing so i add it later.

To Build you tube video downloader using node js you have two option fist use ytdl-core that is rapper on top of yt-dlp and also more optimize and second use yt-dlp directly using node exe() function and node child_process . This guide on how to youtube video downloader using python i will not guide you how to setup development environment for node.

follow this step to build this

  1. first setup devlopment server

  2. install this yt-dlp, express and other based on what functionality you added extra

  3. After that import yt-dlp and express and create a end point for video download

  4. Inside that Api run yt-dlp using node exe() function or child_process then

  5. To customize any functionality of yt-dlp refer their docs

Here is final code

Run this command on your terminal before running this code

npm install express express-rate-limit
const express = require("express");
const rateLimit = require("express-rate-limit");
const { spawn } = require("child_process");

const app = express();

// ------------------------------
// Rate Limiting (10 requests/min)
// ------------------------------
const limiter = rateLimit({
  windowMs: 60 * 1000, // 1 min
  max: 10,
  message: { error: "Too many requests. Try again later." }
});

app.use(limiter);

// ------------------------------
// Helper: Spawn yt-dlp process
// ------------------------------
function getVideoUrl(videoUrl) {
  return new Promise((resolve, reject) => {
    const ytdlp = spawn("yt-dlp", [
      "--no-warnings",
      "-J",          // Output metadata as JSON
      videoUrl
    ]);

    let output = "";
    let errorOutput = "";

    ytdlp.stdout.on("data", (data) => {
      output += data.toString();
    });

    ytdlp.stderr.on("data", (data) => {
      errorOutput += data.toString();
    });

    ytdlp.on("close", (code) => {
      if (code !== 0) {
        return reject(errorOutput || "yt-dlp failed");
      }

      try {
        const jsonData = JSON.parse(output);
        const formats = jsonData.formats || [];

        if (!formats.length) {
          return reject("No downloadable formats found");
        }

        // Best quality (last format)
        const downloadUrl = formats[formats.length - 1].url;

        if (!downloadUrl) {
          return reject("Failed to extract download link");
        }

        resolve(downloadUrl);
      } catch (err) {
        reject("Failed to parse yt-dlp output");
      }
    });
  });
}

// ------------------------------
// /video endpoint (GET + Query Param)
// ------------------------------
app.get("/video", async (req, res) => {
  try {
    const videoUrl = req.query.url;

    if (!videoUrl) {
      return res.status(400).json({ error: "Missing required parameter: url" });
    }

    const downloadUrl = await getVideoUrl(videoUrl);

    res.json({
      status: "success",
      download_url: downloadUrl
    });

  } catch (err) {
    res.status(500).json({ error: err.toString() });
  }
});

// ------------------------------
app.listen(5000, () => {
  console.log("Server running at <http://127.0.0.1:5000>");
});

To test use this

<http://127.0.0.1:5000/video?url=https://www.youtube.com/watch?v=dQw4w9WgXcQ>

As a smart developer try to take help of chatgpt if any issues you face. Best of Luck

Use this for batter response

https://chatgpt.com/share/692d8b28-1c40-8004-998e-bc3cc9cbf7c4

Daily Hacks

Part 1 of 1