Making A YouTube Video Downloader With Python's Flask and pytube3 Libraries
How do you download YouTube videos? The easiest answer is to google sites that have youtube downloader videos. But then I thought, I wonder if I can make something?
Boredom, my curiosity and some googling turned up the pytube3 library, "A lightweight, dependency-free Python 3 library (and command-line utility) for downloading YouTube Videos." Lo and behold, 3 hours of experimentation later, I made a video downloader with Python. 😃
I used pytube3 with Flask and pythonanywhere to accomplish the task. I was pleasantly surprised at how it came together and simply worked! Here's how to make a primitive YouTube video downloader.
Install the pytube library in the pythonanywhere bash console with pip
pip3.8 install --user pytube3 --upgrade
If you're not using pythonanywhere, install Flask (it's already included in pythonanywhere)
python -m pip install flask
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | import logging import sys from pytube import YouTube from flask import Flask, request, send_file logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) app = Flask(__name__) @app.route("/") def youtube_downloader(): """Render HTML form to accept YouTube URL.""" html_page = f"""<html><head> <Title>YouTube Downloader</Title></head> <body><h2>Enter URL to download YouTube Vids!</h2> <div class="form"> <form action="/download_video" method="post"> <input type="text" name="URL"> <input type="submit" value="Submit"> </form></div><br><br> </body></html>""" return html_page @app.route("/download_video", methods=["GET","POST"]) def download_video(): """First pytube downloads the file locally in pythonanywhere: /home/your_username/video_name.mp4 Then use Flask's send_file() to download the video to the user's Downloads folder. """ try: youtube_url = request.form["URL"] download_path = YouTube(youtube_url).streams[0].download() fname = download_path.split("//")[-1] return send_file(fname, as_attachment=True) except: logging.exception("Failed download") return "Video download failed!" |
Minimum Viable Prototype Achieved
This is more of a proof of concept than workable solution. It works for many videos I tried. It occasionally had trouble downloading certain videos. I tested it successfully on videos of up to 10 minutes. Maybe it works more consistently if the file size is smaller? Or there is a bug on certain types of videos? For me, some videos of only a few minutes failed, so your results may vary. The videos that failed returned errors like KeyError: 'cipher' and KeyError: 'url'.
Honorable Mentions
youtube-dl: Command-line program to download videos from YouTube.com and other video sites
YoutubeDownload: GUI and CLI for downloading YouTube video/audio