DEV Community

Cover image for How to download Youtube Music and Videos with Python
Shittu Olumide
Shittu Olumide

Posted on • Updated on

 

How to download Youtube Music and Videos with Python

This article will discuss how to easily download music and videos from Youtube using the Python programming language. The reason why we will be using Python is that it is a lightweight, fast and easy tool to use for software development.

We will be using two libraries so as to achieve our aim argparse and pytube , it can be installed using the python package installer (pip).

Importing the libraries

import argparse
from pytube import YouTube
Enter fullscreen mode Exit fullscreen mode

To parse the arguments supplied to the script, we'll use argparse, and to download YouTube videos, we'll use pytube.

Next, we must provide the folders in which the video and audio should be stored. I do this by using the following constants:

VIDEO_DOWNLOAD_DIR = "../Downloads/videos"
AUDIO_DOWNLOAD_DIR = "..Downloads/audio"
Enter fullscreen mode Exit fullscreen mode

Download function

Let's write a function that takes care of downloading the videos and audio in their respective folders separately.

For audio, we will filter the streams for audio-only content, choose the first one that is available, and download the audio-only stream to the AUDIO_DOWNLOAD_DIR directory.

def YoutubeAudioDownload(video_url):
    video = YouTube(video_url)
    audio = video.streams.filter(only_audio = True).first()

    try:
        audio.download(AUDIO_DOWNLOAD_DIR)
    except:
        print("Failed to download audio")

    print("audio was downloaded successfully")
Enter fullscreen mode Exit fullscreen mode

For the video, the function takes the URL of the YouTube video and downloads the best/highest resolution available to the VIDEO_DOWNLOAD_DIR directory.

def YoutubeVideoDownload(video_url):
    video = YouTube(video_url)
    video = video.streams.get_highest_resolution()

    try:
        video.download(VIDEO_DOWNLOAD_DIR)
    except:
        print("Unable to download video at this time!")

    print("Video downloaded!")
Enter fullscreen mode Exit fullscreen mode

These two simple functions take the YouTube video and audio URL, download it in the greatest resolution possible, and then save it in their respective directory, but if there is an error, it prints out an error message.

Main function

The video URL is parsed using argparse in the main function, and an optional audio-only flag is also used. The video's audio will be downloaded if the flag is enabled; by default, both the video and audio are downloaded.

These two simple functions take the YouTube video and audio URL, download it in the greatest resolution possible, and then save it in their respective directory, but if there is an error, it prints out an error message.

Let's have a look at the code.

if __name__ == "__main__":
    ap = argparse.ArgumentParser()
    ap.add_argument("-v", "--video", required = True, help = "Youtube video URL")
    ap.add_argument("-a", "--audio", required = False, help = "Audio only", action = argparse.BooleanOptionalAction)
    args = vars(ap.parse_args())

    if args["audio"]:
        YoutubeAudioDownload(args["video"])
    else:
        YoutubeVideoDownload(args["video"])
Enter fullscreen mode Exit fullscreen mode

And we are done!

To test the code out if it actually works, type the following in the terminal.

# for audio
python main.py -a -v "[YouTube video URL]"

# for videos
python main.py -v "[YouTube video URL]"
Enter fullscreen mode Exit fullscreen mode

The audio/video directory should have the necessary media downloaded.

Wrap up

In this article, we discussed how to easily download audio and video from Youtube, using the pytube library. We also used the argparse library to add arguments to the terminal so that we can download the media with shorthand and links to either the audio or video. I personally use this to download songs that I like, and it works perfectly.

Let’s connect: Twitter & LinkedIn

You can also check out my Youtube channel.

Happy coding! 😊

Top comments (17)

Collapse
 
valentinopereira profile image
Valentino Pereira

Getting this error

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/urllib/request.py", line 1348, in do_open
    h.request(req.get_method(), req.selector, req.data, headers,
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 1276, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 1322, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 1271, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 1031, in _send_output
    self.send(msg)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 969, in send
    self.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 1448, in connect
    self.sock = self._context.wrap_socket(self.sock,
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/ssl.py", line 512, in wrap_socket
    return self.sslsocket_class._create(
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/ssl.py", line 1070, in _create
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/ssl.py", line 1341, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/valentinopereira/Documents/practice/youtube/index.py", line 17, in <module>
    download("https://www.youtube.com/watch?v=eFTLKWw542g")
  File "/Users/valentinopereira/Documents/practice/youtube/index.py", line 7, in download
    video = video.streams.get_highest_resolution()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pytube/__main__.py", line 295, in streams
    self.check_availability()
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pytube/__main__.py", line 210, in check_availability
    status, messages = extract.playability_status(self.watch_html)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pytube/__main__.py", line 102, in watch_html
    self._watch_html = request.get(url=self.watch_url)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pytube/request.py", line 53, in get
    response = _execute_request(url, headers=extra_headers, timeout=timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pytube/request.py", line 37, in _execute_request
    return urlopen(request, timeout=timeout)  # nosec
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/urllib/request.py", line 216, in urlopen
    return opener.open(url, data, timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/urllib/request.py", line 519, in open
    response = self._open(req, data)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/urllib/request.py", line 536, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/urllib/request.py", line 496, in _call_chain
    result = func(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/urllib/request.py", line 1391, in https_open
    return self.do_open(http.client.HTTPSConnection, req,
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/urllib/request.py", line 1351, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
Enter fullscreen mode Exit fullscreen mode

I tried running it inside venv and even on my system python.

Collapse
 
valentinopereira profile image
Valentino Pereira

Update: Fixed it by doing these timonweb.com/python/fixing-certifi... and restarting terminal

Collapse
 
shittu_olumide_ profile image
Shittu Olumide

Glad you fixed it!

Collapse
 
dshaw0004 profile image
DShaw0004

It's working but not on my local IDE (vs code). I have to use replit to run it so it is not downloading the file to my device.
Is there any way to run this on vscode ?

Collapse
 
shittu_olumide_ profile image
Shittu Olumide

Hello, thanks for reading!
It actually works on my IDE (VSCode)

Collapse
 
dshaw0004 profile image
DShaw0004

I don't know how but it is working.
Now I will make a tkinter gui to give this program an application like experience.
Do I have permission to use your code to make a gui ?

Thread Thread
 
shittu_olumide_ profile image
Shittu Olumide

Yeah sure, you can go ahead.
If you also need me to collaborate, we can work on it together.
It's good to know you want to use something of mine, which is yours now πŸ˜…

Thread Thread
 
dshaw0004 profile image
DShaw0004

Already done, you can check it now
YTdownloader

Thread Thread
 
shittu_olumide_ profile image
Shittu Olumide

This looks nice! πŸ‘
Checking it out now

Thread Thread
 
dshaw0004 profile image
DShaw0004

please rate this app 😊

Collapse
 
dshaw0004 profile image
DShaw0004

It is printing "Video downloaded!" but the folder where i want to install it is empty.
In case of Replit it actually create a folder of that name and add the file to it.

Collapse
 
chrisgreening profile image
Chris Greening

I've had a good bit of fun messing around with pytube for various projects but it's been a while, I'll have to check it out again - thanks for the tutorial!

Collapse
 
shittu_olumide_ profile image
Shittu Olumide

You are welcome!

Collapse
 
valentinopereira profile image
Valentino Pereira

The function calls in your main function are different than your definitions.

  1. download_audio is meant to be YoutubeAudioDownload
  2. download is meant to be YoutubeVideoDownload
Collapse
 
shittu_olumide_ profile image
Shittu Olumide

Opps, thanks for pointing this out!
I have edited the code πŸ˜ƒ

Collapse
 
erins5927 profile image
NerfWeb

Thanks for sharing! really helpful!

Collapse
 
shittu_olumide_ profile image
Shittu Olumide

You are welcome πŸ€—

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.