download YouTube videos using Python

YouTube is a well-known video-sharing platform. You will be required to download a third-party downloader and use it to obtain the video or go to any other website that will get the video and store it on your PC. However, this task is simple to accomplish with Python. A few lines of code will automatically download the video from YouTube. There is a Python library called ‘pytube’ that we may use for this. pytube is a Python package for getting videos from the lightweight web and is devoid of dependencies.

The native library is not pytube. We start by installing it before putting it to use. When you have pip, installation is a breeze. To install pytube, execute the following command in the Terminal or Command Prompt.

pip install pytube

Downloading YouTube videos using Python

Single video download

The pytube library makes video downloading a breeze. Bypassing the link as a parameter, you can create the object of the YouTube module. Then, determine the video’s suitable extension and resolution. Then, the download function takes one parameter, where the file should be downloaded. Name the file in any way you find appealing; otherwise, it will maintain the original name.

# start by initiating the module importation
from pytube import YouTube

# specify where to save the file
SAVE_PATH = "D:/" #to_do

# link of the video to be downloaded
youtube_link="https://youtu.be/TShNiKYjxA4"

try:
	# creating an object using YouTube that is initially imported at the beginning
	you_tube = YouTube(youtube_link)
except:
	print("Error Connectioning") # exception handling

# filtering of  "mp4"  files 
specify_mp4files = you_tube.filter('mp4')

#to set the name of the file
you_tube.set_filename('Codeunderscored Video Download')

# use the extension to get the video and
# pass in the get() function the  resolution
downloaded_video = you_tube.get(specify_mp4files[-1].extension,specify_mp4files[-1].resolution)
try:
	# downloading the video
	downloaded_video.download(SAVE_PATH)
except:
	print(" Error Encountered!")
print('Download Completed Successfully!')

Because a significant amount of data is downloaded from the internet, downloading a file takes time. The time taken to run the software varies depending on the connection speed. Proceed to the following example if you want to download many files.

Multiple video downloads

Downloading numerous videos is much the same as downloading a single video. However, we can use it for downloading the video for a loop.

from pytube import YouTube

# specifying where to save the file
SAVE_PATH = "D:/" #to_do

# links for the videos to be downloaded
video_links=["https://youtu.be/TShNiKYjxA4",
	"https://www.youtube.com/watch?v=asbcE9mZz_U&t=1s"
	]

for link in video_links:
	try:
		
		# creating an object using YouTube as imported initially
		you_tube = YouTube(link)
	except:
		
		#to handle exception
		print("Error Connectioning")
	
	# files with "mp4" are filtered out
	specify_mp4files = you_tube.filter('mp4')

	# use the extension to get the video and
	# pass in the get() function the  resolution
	downloaded_video = you_tube.get(specify_mp4file[-1].extension,specify_mp4file[-1].resolution)
	try:
		# downloading the video
		downloaded_video.download(SAVE_PATH)
	except:
		print("Error Encountered!")
print('Video Download Completed!')

We’ve used a for loop to download multiple files in this case, as shown. Alternatively, we can use file handling to keep track of all the files’ links that require downloading.

Using File Handling to download several videos

We have a text file called “file_links.txt” containing all the links you must download. It is where you go through every link in a text file and use a very rudimentary video downloading tool. Then, we can open the file containing the group of links using file handling.

from pytube import YouTube

# where to save
SAVE_PATH = "D:/" #path to save the file

# link of the video to be downloaded
# opening the file
video_links=open('file_links.txt','r')

for link in video_links:
	try:
		
		# object creation using YouTube
		# which was imported in the beginning
		you_tube = YouTube(link)
	except:
		
		#to handle exception
		print("Error Connecting")
	
	# files with "mp4" extension are filtered out
	specify_mp4files = you_tube.filter('mp4')
	
	# use the extension to get the video and
	# pass in the get() function the  resolution
	downloaded_video = you_tube.get(specify_mp4files[-1].extension,specify_mp4files[-1].resolution)
	try:
		
		# video downloading
		downloaded_video.download(SAVE_PATH)
	except:
		print("Error Encountered!")
print('Video Download Completed!')

Points to Remember:

  • To download the videos, make sure you’re connected to the internet. Otherwise, an error will occur.
  • In no case should the set_filename() method be used in a loop. Only a single video is downloaded in this situation.
  • You can change the names at any moment by supplying a different array of names.
  • In the event of a connection interruption in the middle, an error will be generated, and you will not be able to download it.

Using pytube3 to Download YouTube Videos

The other alternative we recommend is using pytube3, a derivative of the original pytube package that fixes the problem (it only works with Python 3). All of the original library’s features have been kept. However, importing the library still needs the use of pyttube. That is irrespective of installing it using pip install pytube3.

First, we will elucidate the files needed by importing them as follows:

from pytube import YouTube

# imports - misc 
import os
import shutil
import math
import datetime

# imports - plots
import matplotlib.pyplot as plt
#%matplotlib inline

# imports - image operation
import cv2

We may use this object to download the video/audio and investigate some of the video’s attributes. The following are some of the most exciting strategies we can employ:

  • length — the video’s length in seconds
  • rating — the video’s rating
  • views — the number of views

The streams method is then used to inspect the available streams. To see all accessible streams, we can chain it with the all method.

video = YouTube('https://youtu.be/TShNiKYjxA4')
video.streams.all()

When you run that line of code, you’ll get a list of media formats.

We refer to pytube’s documentation for a more detailed overview of the possibilities for media types and working with streams. Let’s use the filter approach to reduce all of the available streams to mp4 files:

video.streams.filter(file_extension = "mp4").all()

In this situation, we’ll go with the first option, 360p (resolution). To download the video, we first use the itag to specify which one we want to download, and then we use the download method to get the file. The following is the complete code for downloading the video:

video.streams.get_by_itag(18).download()

We can also define the video’s destination path using the download method. Again, the current directory is the default value.

Video frames extraction

We designed a custom class named FrameExtractor to extract individual frames from the movie and store them as photos, as the name implies. The following is how the class is defined:

class VideoFrameExtraction():
    '''
    The class that will accept a video file and extract frames
    '''
    def __init__(self, video_path):
        self.video_path = video_path
        self.vid_cap = cv2.VideoCapture(video_path)
        self.n_frames = int(self.vid_cap.get(cv2.CAP_PROP_FRAME_COUNT))
        self.fps = int(self.vid_cap.get(cv2.CAP_PROP_FPS))
        
    def get_video_duration(self):
        duration = self.n_frames/self.fps
        print(f'Duration: {datetime.timedelta(seconds=duration)}')
        
    def get_n_images(self, every_x_frame):
        n_images = math.floor(self.n_frames / every_x_frame) + 1
        print(f'Extracting every code {every_x_frame} (nd/rd/th) frame would result in {n_images} images.')
        
    def extract_frames(self, every_x_frame, img_name, dest_path=None, img_ext = '.jpg'):
        if not self.vid_cap.isOpened():
            self.vid_cap = cv2.VideoCapture(self.video_path)
        
        if dest_path is None:
            dest_path = os.getcwd()
        else:
            if not os.path.isdir(dest_path):
                os.mkdir(dest_path)
                print(f'Created the following code directory: {dest_path}')
        
        frame_cnt = 0
        img_cnt = 0

        while self.vid_cap.isOpened():
            
            success,image = self.vid_cap.read()
            
            if not success:
                break
            
            if frame_cnt % every_x_frame == 0:
                img_path = os.path.join(dest_path, ''.join([img_name, '_', str(img_cnt), img_ext]))
                cv2.imwrite(img_path, image)  
                img_cnt += 1
                
            frame_cnt += 1
        
        self.vid_cap.release()
        cv2.destroyAllWindows()

We must supply the path to the video we wish to work with when instantiating the VideoFrameExtraction class object. The class generally allows you to extract every x-th frame from a video, as the change between any two surrounding frames is tiny. We also remove some video properties in the init method, such as the total number of frames per second frames (FPS). We also offer a few options for your convenience. The following are all of the methods:

  • get_video_duration — returns the video’s duration.
  • get_n_images — is responsible for printing the number of images extracted if every x-th frame (as indicated by every x frame) is extracted.
  • extract_frames — The class’s primary method for extracting images is extract frames. It provides every_x_frame’s value, and the image’s name is the bare minimum. In addition, the numbers indicating the sequence are automatically added at the end of the name. The photographs are saved in the current directory by default. We can optionally supply a path to the desired directory (dest_path), which will be created if it does not exist. We can also define the image file format, which is JPG by default.

It’s now time to put the class into practice. The starting point is creating an instance of the VideoFrameExtraction class:

fe = FrameExtractor('Lady in red [011] Chris de Burgh.mp4')

After that, we look into the video’s length:

fe.get_video_duration()

Let’s say we want to extract every 1000th frame, for example. We use the following command to determine the number of photos collected with this setting:

fe.get_n_images(every_x_frame=1000)

We extract the photos as the final step:

fe.extract_frames(every_x_frame=1000,
                  img_name='codeimg',
                  dest_path='codeimg_images')
# Created the following directory: codeimg_images

Because the specified directory did not exist before calling the extract frames method, it was created automatically, as evidenced by a displayed statement.

Finally, we build a short function for examining the photos that have been downloaded:

def show_image(path):
    image = cv2.imread(path)
    plt.imshow(image)
    plt.show()
show_image('codeimg_images/codeimg_38.jpg')

Conclusion

This article showed how to utilize pytube and pytube3 library to download videos from YouTube and create a custom class for extracting frames as photos from the downloaded files.

The Python computer language’s Pytube module makes downloading videos from YouTube incredibly simple, and it doesn’t require any other Python libraries, so there’s no need to install anything else. Pytube is included in almost all Python versions (2.7 and higher).

A potential change to the pytube3 class would be to skip the first n seconds of the video, as the beginning frequently contains title screens, business logos, and other information. The same might be said for the video’s conclusion. For the time being, however, we can adjust for this by manually deleting photographs that are no longer useful to us.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *