Skip to content

Instantly share code, notes, and snippets.

@Adrian-2105
Last active June 11, 2024 20:32
Show Gist options
  • Save Adrian-2105/a1e407f3f4c780a60f829eac9d241881 to your computer and use it in GitHub Desktop.
Save Adrian-2105/a1e407f3f4c780a60f829eac9d241881 to your computer and use it in GitHub Desktop.
YouTube Downloader - Audio, Video and Playlists - Easy to use
import sys
import os
import subprocess
import argparse
from pytube import Playlist, YouTube, Stream
# Used to solve pytube.exceptions.AgeRestrictedError
from pytube import innertube
innertube._default_clients["ANDROID_MUSIC"] = innertube._default_clients["ANDROID_CREATOR"]
EXAMPLES_OF_USE = """
EXAMPLES
# Download a video in MP4 in the current directory
python YoutubeDownloader.py --video --url "https://www.youtube.com/watch?v=eYDI8b5Nn5s"
# Download an audio playlist in MP3 in a subfolder called 'MyPlaylist'
python YoutubeDownloader.py --audio --path "./MyPlaylist/" --url "https://youtube.com/playlist?list=PLZuZrScKjWOMAEEBEGTmAGtmmlg6QY7bC"
# Download the video by selecting the desired format
python YoutubeDownloader.py --select --url "https://www.youtube.com/watch?v=eYDI8b5Nn5s"
"""
# Downloads the video, pre-showing all download options
def download_option(url : str, path = './'):
video = YouTube(url)
video_options = video.streams.all()
for i in range(len(video_options)):
print(f'[{i}] {video_options[i]}')
while True:
num_option = int(input('Enter the number of the options you want to choose to download: '))
if num_option >= 0 and num_option < len(video_options):
break
print(f'Invalidad number. Please, insert one between 0 and {len(video_options) - 1}')
return download_stream(video_options[num_option], path)
# Downloads the video in MP4 at max resolution
def download_video(url : str, path = './'):
video = YouTube(url)
return download_stream(video.streams.get_highest_resolution(), path)
# Downloads the video in MP4 (only audio) at best quality
def download_audio(url: str, path = './'):
video = YouTube(url)
return download_stream(video.streams.get_audio_only(), path)
# Downloads a created Pytube Stream
def download_stream(stream: Stream, path = './'):
# gets the filename of the first audio stream
filename = stream.default_filename
print(f'Downloading {filename} ...')
# downloads first audio stream
stream.download(path)
print(f'{filename} downloaded!')
return os.path.join(path, filename)
# Converts a file video (MP4) to audio (MP3)
def convert_video_to_audio(filename: str, remove_later = False):
# Checks if file exists
if not os.path.exists(filename):
print(f'{filename} cannot be located in current directory ({os.getcwd()})', file=sys.stderr)
return
# creates mp3 filename for downloaded file
new_filename = filename[0:filename.rfind('.')] + ".mp3"
print(filename, new_filename)
# converts mp4 audio to mp3 audio
print("Converting to mp3....")
subprocess.run(['ffmpeg', '-i', filename, new_filename])
# remove original file if specified
if remove_later:
os.remove(filename)
if __name__ == "__main__":
# Arguments
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--video', action='store_true', help='download the video in MP4')
parser.add_argument('-a', '--audio', action='store_true', help='download the video as audio in MP3')
parser.add_argument('-s', '--select', action='store_true', help='select the download format among all the possible options')
parser.add_argument('-p', '--path', default='./', help='path where to download')
parser.add_argument('-u', '--url', required=True, help='URL to download')
# No arguments and print help
if len(sys.argv) == 1:
parser.print_help()
print(EXAMPLES_OF_USE)
print('NOTE: for audio downloads, this application requieres ffmpeg')
print(' - On Linux: you can download it through apt-get')
print(' - On Windows: download the executable ffmpeg.exe and add it to the working directory (or add it to the path instead)')
parser.exit()
# Parse arguments
args = parser.parse_args()
if not args.select and not args.video and not args.audio:
print('No option for download selected. Use --select, --video or --audio to download')
exit(1)
# Check if URL works and if it's a single video or a playlist
is_video = False
is_playlist = False
try:
is_video = YouTube(args.url)
is_video = True
except:
try:
is_playlist = Playlist(args.url)
is_playlist = True
except:
print('Invalid URL!', file=sys.stderr)
exit(1)
# Executes program
if not is_playlist:
if args.select:
filepath = download_option(args.url, args.path)
else:
if args.audio:
filepath = download_audio(args.url, args.path)
convert_video_to_audio(filepath, remove_later=True)
if args.video:
filepath = download_video(args.url, args.path)
else: # is playlist
playlist = Playlist(args.url)
for video_url in playlist:
if args.select:
filepath = download_option(video_url, args.path)
else:
if args.audio:
filepath = download_audio(video_url, args.path)
convert_video_to_audio(filepath, remove_later=True)
if args.video:
filepath = download_video(video_url, args.path)
@Adrian-2105
Copy link
Author

Adrian-2105 commented Feb 21, 2022

Help menu and examples

usage: YoutubeDownloader.py [-h] [-v] [-a] [-s] [-p PATH] -u URL

optional arguments:
  -h, --help            show this help message and exit
  -v, --video           download the video in MP4
  -a, --audio           download the video as audio in MP3
  -s, --select          select the download format among all the possible options
  -p PATH, --path PATH  path where to download
  -u URL, --url URL     URL to download

EXAMPLES

# Download a video in MP4 in the current directory
python YoutubeDownloader.py --video --url "https://www.youtube.com/watch?v=eYDI8b5Nn5s"

# Download an audio playlist in MP3 in a subfolder called 'MyPlaylist'
python YoutubeDownloader.py --audio --path "./MyPlaylist/" --url "https://youtube.com/playlist?list=PLZuZrScKjWOMAEEBEGTmAGtmmlg6QY7bC"

# Download the video by selecting the desired format
python YoutubeDownloader.py --select --url "https://www.youtube.com/watch?v=eYDI8b5Nn5s"

NOTE: for audio downloads, this application requieres ffmpeg
 - On Linux: you can download it through apt-get
 - On Windows: download the executable ffmpeg.exe and add it to the working directory (or add it to the path instead)
   -> Can be downloaded from: https://www.gyan.dev/ffmpeg/builds/ffmpeg-git-essentials.7z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment