Have you ever wanted to build your own YouTube video downloader using python?
In this blog, we will explore how to create a tool to Download YouTube Videos using Python, Flask, and the PyTube library. This project is great for those who want to build a real-world application.
The application allows users to input a YouTube video URL and either fetch its details like title, views, and description or download it in a selected resolution.
Code: Download YouTube Videos Using Python
from flask import Flask, request, jsonify from pytube import YouTube import re app = Flask(__name__) def download_video(url, resolution): try: yt = YouTube(url) stream = yt.streams.filter(progressive=True, file_extension='mp4', resolution=resolution).first() if stream: stream.download() return True, None else: return False, "Video with the specified resolution not found." except Exception as e: return False, str(e) def get_video_info(url): try: yt = YouTube(url) stream = yt.streams.first() video_info = { "title": yt.title, "author": yt.author, "length": yt.length, "views": yt.views, "description": yt.description, "publish_date": yt.publish_date, } return video_info, None except Exception as e: return None, str(e) def is_valid_youtube_url(url): pattern = r"^(https?://)?(www\.)?youtube\.com/watch\?v=[\w-]+(&\S*)?$" return re.match(pattern, url) is not None @app.route('/download/<resolution>', methods=['POST']) def download_by_resolution(resolution): data = request.get_json() url = data.get('url') if not url: return jsonify({"error": "Missing 'url' parameter in the request body."}), 400 if not is_valid_youtube_url(url): return jsonify({"error": "Invalid YouTube URL."}), 400 success, error_message = download_video(url, resolution) if success: return jsonify({"message": f"Video with resolution {resolution} downloaded successfully."}), 200 else: return jsonify({"error": error_message}), 500 @app.route('/video_info', methods=['POST']) def video_info(): data = request.get_json() url = data.get('url') if not url: return jsonify({"error": "Missing 'url' parameter in the request body."}), 400 if not is_valid_youtube_url(url): return jsonify({"error": "Invalid YouTube URL."}), 400 video_info, error_message = get_video_info(url) if video_info: return jsonify(video_info), 200 else: return jsonify({"error": error_message}), 500 if __name__ == '__main__': app.run(debug=True)
Let’s break down the code and understand how it works.
1. Setting Up the Flask App
At the very top, the code imports some necessary modules:
from flask import Flask, request, jsonify<br>from pytube import YouTube
flask
is the web framework we are using to create routes (endpoints) that interact with the user.pytube
is a lightweight library to download YouTube videos and fetch metadata.re
is used for regular expression matching to check if a YouTube URL is valid.
The line app = Flask(__name__)
initializes the Flask application.
2. Downloading a YouTube Video
The download_video
function takes in a video URL and a resolution (like “720p” or “360p”) and downloads the video if available.
<strong>def download_video(url, resolution):<br> try:<br> yt = YouTube(url)<br> stream = yt.streams.filter(progressive=True, file_extension='mp4', resolution=resolution).first()<br> if stream:<br> stream.download()<br> return True, None<br> else:<br> return False, "Video with the specified resolution not found."<br> except Exception as e:<br> return False, str(e)<br></strong>
Here’s what’s happening in simple words:
The YouTube object is created from the given URL. It filters for progressive streams, which include both video and audio.
If the resolution exists, it downloads the video. If the resolution is not found or something else goes wrong, an error message is returned.
3. Fetching Video Information
Another useful feature is to fetch the video’s metadata like title, views, description, etc. This is done using the get_video_info
function.
<strong>def get_video_info(url):<br> try:<br> yt = YouTube(url)<br> stream = yt.streams.first()<br> video_info = {<br> "title": yt.title,<br> "author": yt.author,<br> "length": yt.length,<br> "views": yt.views,<br> "description": yt.description,<br> "publish_date": yt.publish_date,<br> }<br> return video_info, None<br> except Exception as e:<br> return None, str(e)<br></strong>
What does this code doing?
It Creates a YouTube object from the URL and retrieves video details such as title, author, duration (in seconds), view count, description, and publish date.
If any issue arises, it returns an error message.
This feature is helpful when you want to preview details before downloading a video.
4. Validating the YouTube URL
To make sure the input is a proper YouTube video link, a validation function is created:
<strong>def is_valid_youtube_url(url):<br> pattern = r"^(https?://)?(www\.)?youtube\.com/watch\?v=[\w-]+(&\S*)?$"<br> return re.match(pattern, url) is not None<br></strong>
This uses a regex pattern to check whether the URL provided is a valid YouTube video link.
5. Flask API Routes
This app provides two main routes (also called endpoints):
1. /download/<resolution>
– POST method
This route is used to download a video in the given resolution.
<strong>@app.route('/download/<resolution>', methods=['POST'])<br>def download_by_resolution(resolution):<br></strong>
It expects a JSON body with the YouTube URL:
<strong>{<br> "url": "https://www.youtube.com/watch?v=abc123"<br>}<br></strong>
Inside the function checks if the URL is present. Then it checks whether the URL is valid.
If both checks pass, it tries to download the video with the requested resolution.
If successful, it returns a success message; otherwise, it returns an error.
2. /video_info
– POST method
This route is used to fetch details about the video.
<strong>@app.route('/video_info', methods=['POST'])<br>def video_info():<br></strong>
It also expects a JSON body with the YouTube URL.
The function validates the presence and format of the URL and uses the get_video_info
function to fetch the data.
Returns all the video information as a JSON response.
Final Step: Running the App
Finally, this line ensures that the Flask server starts when you run the script:
<strong>if __name__ == '__main__':<br> app.run(debug=True)<br></strong>
Setting <strong>debug=True</strong>
is helpful during development as it gives detailed error messages and reloads the server when the code changes.
Output Example
For /video_info
:
<strong>{<br> "title": "Python Learnings",<br> "author": "CodeHelping.Com",<br> "length": 360,<br> "views": 155000,<br> "description": "Hello, CodeHelping.com is here...",<br> "publish_date": "2025-02-04"<br>}<br></strong>
For /download/720p
:
<strong>{<br> "message": "Video with resolution 720p downloaded successfully."<br>}<br></strong>
Or if resolution is not found:
<strong>{<br> "error": "Video with the specified resolution not found."<br>}<br></strong>
Final Thoughts
This Flask-based project to Download YouTube Videos Using Python is a simple but powerful demonstration of how Python can be used to interact with APIs and external services like YouTube.
It’s lightweight, functional, and beginner friendly. For more python projects, visit here.
This kind of project gives you hands-on experience with Flask, REST APIs, error handling, and regular expressions – all valuable skills for web developers and backend engineers.
Source Code of Github: Code