Site icon Towards AI

How To Build a Web App To Download YouTube Videos in 30 Lines of Code — Python Project Tutorials

Author(s): Rahul Banerjee

We will be using Streamlit and pytube to build our youtube downloader web app. I will also give a brief overview of the pytube library.

Screencast by Author

We will be implementing the following features

Setup Virtual Environment

Before we start, we will need to set up and activate a virtual environment

pip install virtualenv /* Install virtual environment */ virtualenv venv /* Create a virtual environment */ 
venv/Scripts/activate /* Activate the virtual environment */

Install Required Libraries

We will need to install the following Libraries

Streamlit

Streamlit – The fastest way to create data apps

pytube

pytube – pytube 10.1.0 documentation

Type the following command to install the libraries

pip install streamlit, pytube

Step 1: Import Libraries

import streamlit as st
from pytube import YouTube

Import the installed libraries and define aliases where needed.

Step 2: Header and URL Input

Screenshot by Author

We will be using streamlit’s title() and subheader() functions for the text. Both of them take a string as a parameter and display it.

For the user input, we will use the text_input() function. A label can be passed as a parameter.

st.title("Youtube Video Donwloader") 
st.subheader("Enter the URL:") url = st.text_input(label='URL')

We will need to store the URL inside a variable. Every time the user types in an URL and hit’s enter, the app is re-run and the text_input() function will return the input URL

I will be working with the following URL https://www.youtube.com/watch?v=4Q46xYqUwZQ

Step 3: Getting the Data for the Youtube video

First, we will need to create an instance of the YouTube object we imported from pytube. The constructor of Youtube object requires the URL to be passed in as a parameter.

yt = YouTube(url)

The YouTube Object has many useful attributes, some of them are listed below

The Youtube Object also has an attribute called streams. It is a list of stream objects. We will be discussing them in the next step.

Step 4: Understanding the Stream Object

print(yt.streams)

I have modified the output slightly. I have also truncated the output since it is pretty long.

---------------------- Stream Object 1 ----------------------------- <Stream: itag="18" mime_type="video/mp4" res="360p" fps="30fps" vcodec="avc1.42001E" acodec="mp4a.40.2" progressive="True" type="video">,
---------------------- Stream Object 2 ----------------------------- <Stream: itag="22" mime_type="video/mp4" res="720p" fps="30fps" vcodec="avc1.64001F" acodec="mp4 a.40.2" progressive="True" type="video">,
---------------------- Stream Object 3 ----------------------------- <Stream: itag="299" mime_type="video/mp4" res="1080p" fps="60fps" vcodec="avc1.64002a" progressive="False" type="video">,
---------------------- Stream Object 4 ----------------------------- <Stream: itag="303" mime_type="video/webm" res="1080p" fps="60fps" vcod ec="vp9" progressive="False" type="video">

We will need to choose one of the streams and use it to download our video/audio. There are two types of streams Progressive and Dynamic Adaptive Streaming over HTTP (DASH). A progressive stream has both the video and audio component while a DASH stream only has one of them. DASH streams are used to download videos in high resolution. The video and audio components will have to be download separately and then merged together using a software.

If you inspect the Stream object, you will notice each object has a boolean property called progressive. Stream Object 1 and Stream Object 2 have a progressive set to True implying it is a progressive stream. Both of them a vcodec property and an acodec property referring to video and audio respectively.

On the other hand, Stream Object 3 and Stream Object 4 have progressive set to False implying it is a DASH stream. Both only have the vcodec property and do not have the acodec property. Therefore they are only the video components.

Each stream object also has a res property which is the resolution of the video.

According to pytube’s official docs

The legacy streams that contain the audio and video in a single file (referred to as “progressive download”) are still available, but only for resolutions 720p and below.

Each stream object has a download() method which takes in the path as an optional parameter. If no path is provided, the file will be downloaded in the same folder as your python script.

Step 5: Choosing a Stream Object to Download

As mentioned before, the YouTube object has an attribute called streams. This is a StreamQuery Object. It has quite a few helpful methods to help us get a stream object.

Note: The filter() method returns a StreamQuery Object, one of the 5 methods below the filter() method will need to be used to return a Stream Object which we can download.

Step 6: Combining the above Steps

Screenshot by Author
if url != '':
    yt = YouTube(url)
    st.image(yt.thumbnail_url, width=300)
    st.subheader('''
    {}
    ## Length: {} seconds
    ## Rating: {} 
    '''.format(yt.title , yt.length , yt.rating))
    video = yt.streams
    if len(video) > 0:
        downloaded , download_audio = False , False
        download_video = st.button("Download Video")
        if yt.streams.filter(only_audio=True):
            download_audio = st.button("Download Audio Only")
        if download_video:
            video.get_lowest_resolution().download()
            downloaded = True
        if download_audio:
            video.filter(only_audio=True).first().download()
            downloaded = True
        if downloaded:
            st.subheader("Download Complete")
    else:
        st.subheader("Sorry, this video can not be downloaded")

Conclusion

We have successfully built a web app to download YouTube videos in 30 lines of code 😃 As mentioned above, some youtube videos return an empty StreamQuery object and as a result, can not be downloaded. Please let me know if you find a work-around or have any speculation as to why this happens.

If you are interested in deploying your streamlit app, check my tutorial below

Use Streamlit Sharing to deploy your Streamlit Apps

Originally published at https://realpythonproject.com on December 21, 2020.


How To Build a Web App To Download YouTube Videos in 30 Lines of Code — Python Project Tutorials was originally published in Towards AI on Medium, where people are continuing the conversation by highlighting and responding to this story.

Published via Towards AI

Exit mobile version