This repository was archived by the owner on May 19, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathytPlaylistDL.py
More file actions
169 lines (144 loc) · 5.66 KB
/
Copy pathytPlaylistDL.py
File metadata and controls
169 lines (144 loc) · 5.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env python3
import urllib.request
import urllib.error
import re
import sys
import time
import os
from pytube import YouTube
class progressBar:
def __init__(self, barlength=25):
self.barlength = barlength
self.position = 0
self.longest = 0
def print_progress(self, cur, total, start):
currentper = cur / total
elapsed = int(time.clock() - start) + 1
curbar = int(currentper * self.barlength)
bar = '\r[' + '='.join(['' for _ in range(curbar)]) # Draws Progress
bar += '>'
bar += ' '.join(['' for _ in range(int(self.barlength - curbar))]) + '] ' # Pads remaining space
bar += bytestostr(cur / elapsed) + '/s ' # Calculates Rate
bar += getHumanTime((total - cur) * (elapsed / cur)) + ' left' # Calculates Remaining time
if len(bar) > self.longest: # Keeps track of space to over write
self.longest = len(bar)
bar += ' '.join(['' for _ in range(self.longest - len(bar))])
sys.stdout.write(bar)
def print_end(self, *args): # Clears Progress Bar
sys.stdout.write('\r{0}\r'.format((' ' for _ in range(self.longest))))
def getHumanTime(sec):
if sec >= 3600: # Converts to Hours
return '{0:d} hour(s)'.format(int(sec / 3600))
elif sec >= 60: # Converts to Minutes
return '{0:d} minute(s)'.format(int(sec / 60))
else: # No Conversion
return '{0:d} second(s)'.format(int(sec))
def bytestostr(bts):
bts = float(bts)
if bts >= 1024 ** 4: # Converts to Terabytes
terabytes = bts / 1024 ** 4
size = '%.2fTb' % terabytes
elif bts >= 1024 ** 3: # Converts to Gigabytes
gigabytes = bts / 1024 ** 3
size = '%.2fGb' % gigabytes
elif bts >= 1024 ** 2: # Converts to Megabytes
megabytes = bts / 1024 ** 2
size = '%.2fMb' % megabytes
elif bts >= 1024: # Converts to Kilobytes
kilobytes = bts / 1024
size = '%.2fKb' % kilobytes
else: # No Conversion
size = '%.2fb' % bts
return size
def getPageHtml(url):
try:
yTUBE = urllib.request.urlopen(url).read()
return str(yTUBE)
except urllib.error.URLError as e:
print(e.reason)
exit(1)
def getPlaylistUrlID(url):
if 'list=' in url:
eq_idx = url.index('=') + 1
pl_id = url[eq_idx:]
if '&' in url:
amp = url.index('&')
pl_id = url[eq_idx:amp]
return pl_id
else:
print(url, "is not a youtube playlist.")
exit(1)
def getFinalVideoUrl(vid_urls):
final_urls = []
for vid_url in vid_urls:
url_amp = len(vid_url)
if '&' in vid_url:
url_amp = vid_url.index('&')
final_urls.append('http://www.youtube.com/' + vid_url[:url_amp])
return final_urls
def getPlaylistVideoUrls(page_content, url):
playlist_id = getPlaylistUrlID(url)
vid_url_pat = re.compile(r'watch\?v=\S+?list=' + playlist_id)
vid_url_matches = list(set(re.findall(vid_url_pat, page_content)))
if vid_url_matches:
final_vid_urls = getFinalVideoUrl(vid_url_matches)
print("Found",len(final_vid_urls),"videos in playlist.")
printUrls(final_vid_urls)
return final_vid_urls
else:
print('No videos found.')
exit(1)
#function added to get audio files along with the video files from the playlist
def download_Video_Audio(path, vid_url, file_no):
try:
yt = YouTube(vid_url)
except Exception as e:
print("Error:", str(e), "- Skipping Video with url '"+vid_url+"'.")
return
try: # Tries to find the video in 720p
#video = yt.get('mp4', '720p')
video = yt.streams.filter(progressive = True, file_extension = "mp4").first()
except Exception: # Sorts videos by resolution and picks the highest quality video if a 720p video doesn't exist
video = sorted(yt.filter("mp4"), key=lambda video: int(video.resolution[:-1]), reverse=True)[0]
print("downloading", yt.title+" Video and Audio...")
try:
bar = progressBar()
video.download(path)
print("successfully downloaded", yt.title, "!")
except OSError:
print(yt.title, "already exists in this directory! Skipping video...")
try:
os.rename(yt.title+'.mp4',str(file_no)+'.mp4')
aud= 'ffmpeg -i '+str(file_no)+'.mp4'+' '+str(file_no)+'.wav'
final_audio='lame '+str(file_no)+'.wav'+' '+str(file_no)+'.mp3'
os.system(aud)
os.system(final_audio)
os.remove(str(file_no)+'.wav')
print("sucessfully converted",yt.title, "into audio!")
except OSError:
print(yt.title, "There is some problem with the file names...")
def printUrls(vid_urls):
for url in vid_urls:
print(url)
time.sleep(0.04)
if __name__ == '__main__':
if len(sys.argv) < 2 or len(sys.argv) > 3:
print('USAGE: python ytPlaylistDL.py playlistURL OR python ytPlaylistDL.py playlistURL destPath')
exit(1)
else:
url = sys.argv[1]
directory = os.getcwd() if len(sys.argv) != 3 else sys.argv[2]
# make directory if dir specified doesn't exist
try:
os.makedirs(directory, exist_ok=True)
except OSError as e:
print(e.reason)
exit(1)
if not url.startswith("http"):
url = 'https://' + url
playlist_page_content = getPageHtml(url)
vid_urls_in_playlist = getPlaylistVideoUrls(playlist_page_content, url)
# downloads videos and audios
for i,vid_url in enumerate(vid_urls_in_playlist):
download_Video_Audio(directory, vid_url, i)
time.sleep(1)