-
Notifications
You must be signed in to change notification settings - Fork 1
/
youtube_video_donloader.py
154 lines (116 loc) · 4.91 KB
/
youtube_video_donloader.py
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
import os
import shutil
import youtube_dl
import pafy
import sys
import urllib
from urllib.parse import urlparse
# Exceptions
class Error(Exception):
pass
class PathNotFoundError(Error):
pass
class InvalidURLerror(Error):
pass
####################
# FUNCTIONS
def validate_url(in_url):
"""
Objective: To validate the input URL
Input : Input URL
Return : True- if valid
False - if invalid
"""
try:
result = urlparse(in_url)
return all([result.scheme, result.netloc])
except ValueError:
return False
def download(in_url, pref_type, save_path):
"""
Objective: To download video from the input URL
Input : in_url - Input URL,
pref_type - Preferred video type,
save_path - Path to save the downloaded file
Return : True- if Success
exits - if failure occurs
"""
available_qualities = []
try:
video_obj = pafy.new(in_url) # Create a new pafy object for the url
except OSError as ose:
print("Unable to visit the URL. There seems to be an internet connectivity issue.")
sys.exit(1)
streams = video_obj.streams # Creates a list of streaming qualities from pafy video object
for qual in streams:
available_qualities.append(str(qual).split(':')[1].split('@')[0].lower())
print("\nThe required video is available in the following qualities: ")
for item in set(available_qualities):
print(item, end=" ")
print_flag = 0
# Get the preferred type from the user input value
if pref_type == 'none':
print("\nPreferred type is mentioned 'NONE'. So, downloading the best available quality")
print_flag = 1
stream_obj = video_obj.getbest()
# If the preferred type is available in the streaming qualities, download it. Or download the best available version
if pref_type.lower() in available_qualities:
print("\nThe preferred video type '{0}' is available. So downloading video in the preferred type.".format(pref_type))
stream_obj = video_obj.getbest(preftype=pref_type) # preftype=pref_type
else:
if not print_flag:
print("\nThe video is not available in the desired quality i.e. {0}. Hence, downloading the best available quality".format(pref_type))
stream_obj = video_obj.getbest()
# Download the video using the stream object
try:
filename = stream_obj.download(quiet=False)
except:
print("Exception occurred while downloading.")
sys.exit(1)
# Checking if the video file exists already in the preferred path. If so, renaming the old file with '_old' extension
video_path = os.path.join(save_path, filename)
if os.path.isfile(video_path):
print("\nThe output file already exists in the specified path. So, renaming the old file with an extension '_old'")
os.rename(video_path, str(video_path).split('.')[0] + "_old." + str(video_path).split('.')[1])
# Moving the downloaded file to the desired path
file_path = os.path.abspath(filename)
base_file_name = os.path.basename(file_path)
destination = os.path.join(save_path, base_file_name)
if shutil.move(os.path.join(os.getcwd(), base_file_name), destination): # We use shutil because, we can't move fron 'C:\' using os module.
print("Successfully downloaded the video. It can be found at: \n {0}".format(destination))
return True
else:
print("Unable to move the donwloaded file to the desired location. It can be found at \n {0}".format(file_path))
return True
##############
"""This is the main function"""
def main():
"""
Objective : Gets the user inputs and validates them. Calls the necessary functions for operating on those inputs
Return : 0 - if Success
-1 - if download fails
1 - if exception occurs
"""
try:
in_url = input("Enter the desired url: ")
ret = validate_url(in_url) # Validates the URL right awaay and throws exception if validation failed
if not ret:
raise InvalidURLerror
pref_type = input("Enter the prefered video type (eg. mp4) | Enter 'none' if there's not preference: ")
save_path = input("Enter the desired path to save the video file: ")
if os.path.isdir(save_path): # Validates the preferred path
pass
else:
raise PathNotFoundError
if download(in_url, pref_type, save_path):
sys.exit(0)
else:
sys.exit(-1)
except PathNotFoundError as pnferr:
print("Given Path to save the video is not valid. Please try again later with a valid path.")
sys.exit(1)
except InvalidURLerror as inurlerr:
print("Please provide a valid video URL. There seems to be a problem with the URL")
sys.exit(1)
if __name__ == "__main__":
main()