Skip to content

Instantly share code, notes, and snippets.

@pranshuthegamer
Last active August 13, 2022 13:07
Show Gist options
  • Save pranshuthegamer/e3de3cab8bd34562043478f03bfdce48 to your computer and use it in GitHub Desktop.
Save pranshuthegamer/e3de3cab8bd34562043478f03bfdce48 to your computer and use it in GitHub Desktop.
yt-dlp playlist batch downloader
#!/bin/python3
import yt_dlp
import sys
import time
import multiprocessing
"""
This Script also works on normal playlists
usage: ./<script> <playlist url>
How it works:
First, it first extracts the urls from playlist into playlist_urls.
Then it spawns a number of threads defined by processes variable and maps the processes to playlist_urls
Notes:
To change the output, edit outtmpl in ydl-opts{}
The [None, ... , None] is the error array, if it isnt None, its an error
This script is barebones, you will have to add other things yourself
"""
args = sys.argv
playlist = args[1]
album_name:str = ''
# number of threads that will spawn
# change this value accordingly
max_processes=8
ydl_opts_playlist_extractor = {}
ydl_opts = {}
def main():
ydl_opts_playlist_extractor = {
'extract_flat': True,
'skip_download': True,
}
ydl_extractor = yt_dlp.YoutubeDL(ydl_opts_playlist_extractor)
#exits incase an error occurs
try:
info_dict = ydl_extractor.extract_info(playlist, download=False, process=False)
except:
exit()
# remove 'Album - ' from playlist name
global album_name
album_name = info_dict['title'].replace('Album - ', '')
playlist_entries = []
for videos in info_dict['entries']:
playlist_entries.append(videos)
playlist_digits = len(str(len(playlist_entries)))
# get the urls to perform download
playlist_urls = []
index = 1
for video in playlist_entries:
# create tuples in a list with can be mapped to a multiprocessing pool
index_zeroed = add_leading_zeros( str(index) , playlist_digits )
playlist_urls.append( ( index_zeroed , video['url'] ) )
index += 1
# creating and mapping thread pool to playlist_urls
processes = 4
if len(playlist_entries) > max_processes:
processes = max_processes
else:
processes = len(playlist_entries)
pool = multiprocessing.Pool(processes=processes)
outputs = pool.map(ydl_download, playlist_urls)
print(outputs)
def ydl_download(input: tuple()):
playlist_index: str = input[0]
url: str = input[1]
ydl_opts = {
'format': 'bestaudio/best',
# Edit this line to change filenames, extensions, etc.
'outtmpl': './%(channel)s/' + album_name + '/' + playlist_index + ' %(title)s - %(id)s.mp3'
}
# start the download for the process
with yt_dlp.YoutubeDL(ydl_opts) as ydl_downloader:
error = ydl_downloader.download(url)
return error
def add_leading_zeros(string, length):
return ("0" * ( length - len(string) ) ) + string
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment