-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
165 lines (127 loc) · 5.78 KB
/
main.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
155
156
157
158
159
160
161
162
163
164
import tkinter
import customtkinter
from yt_dlp import YoutubeDL
from yt_dlp.utils import DownloadError
import re
def update_progress(percentage):
"""Update the progress bar and percentage label."""
progressBar.set(percentage / 100)
pPercentage.configure(text=f"{percentage}%")
def on_progress(d):
"""Callback function to display download progress."""
if d['status'] == 'downloading':
percentage_str = d.get('_percent_str', '')
if percentage_str:
match = re.search(r'(\d+(\.\d+)?)%', percentage_str)
if match:
percentage = match.group(1)
try:
percent_value = float(percentage)
app.after(0, update_progress, percent_value)
except ValueError:
print(f"Error converting percentage: {percentage_str}")
else:
print(f"Could not extract percentage from: {percentage_str}")
def is_valid_youtube_url(url):
"""Check if the URL is a valid YouTube URL."""
youtube_regex = re.compile(
r'(https?://)?(www\.)?(youtube\.com/watch\?v=|youtu\.be/)[\w-]{11}', re.IGNORECASE)
return re.match(youtube_regex, url) is not None
def normalize_youtube_url(url):
"""Normalize different YouTube URL formats to a standard format."""
if 'youtu.be/' in url:
video_id = url.split('youtu.be/')[1].split('?')[0]
return f'https://www.youtube.com/watch?v={video_id}'
elif 'youtube.com/watch?v=' in url:
return url.split('&')[0]
return url
def Download():
"""Handles the download process for the YouTube video."""
try:
yt_link = link.get().strip()
# Validate the URL
if not is_valid_youtube_url(yt_link):
finishLabel.configure(text="Invalid YouTube URL.", text_color="red")
return
yt_link = normalize_youtube_url(yt_link)
if yt_link.startswith('http://'):
yt_link = yt_link.replace('http://', 'https://')
# yt-dlp options
ydl_opts = { # Sets options for yt-dlp
'format': 'best', # Specifies to download the best quality available.
# Available format options:
# 'worst' - Downloads the lowest quality available.
# 'bestvideo' - Downloads the best video quality only.
# 'bestaudio' - Downloads the best audio quality only.
# 'bestvideo[height<=720]' - Best video under or equal to 720p.
# 'bestaudio[abr<=192]' - Best audio with an average bitrate of 192 kbps or lower.
# 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best' - Best video in MP4 and best audio in M4A.
# Combinations like 'bestvideo[height<=1080]+bestaudio/best' for quality under 1080p.
'outtmpl': '%(title)s.%(ext)s',
'progress_hooks': [on_progress],
}
finishLabel.configure(text="")
progressBar.set(0)
pPercentage.configure(text="0%")
with YoutubeDL(ydl_opts) as ydl:
info_dict = ydl.extract_info(yt_link, download=False)
ytObject = info_dict
title.configure(text=ytObject['title'], text_color="white")
ydl.download([yt_link])
finishLabel.configure(text="Download Complete!", text_color="green")
except DownloadError:
finishLabel.configure(text="Error: Could not retrieve video information.", text_color="red")
except Exception as e:
finishLabel.configure(text=f"Error occurred: {e}", text_color="red")
"""
GUI CONFIG IS BELOW THIS LINE, CUSTOMIZE THE FEEL OF THE APP BELOW
"""
customtkinter.set_appearance_mode("dark")
customtkinter.set_default_color_theme("blue")
app = customtkinter.CTk()
app.geometry("720x480")
app.title("YouTube Downloader")
# Disable maximize by making the window non-resizable
app.resizable(False, False)
# Title label
title = customtkinter.CTkLabel(app,
text="YouTube Downloader",
font=("Helvetica", 20, "bold"),
text_color="#00BFFF")
title.pack(pady=(20, 10))
# Instruction label
instructionLabel = customtkinter.CTkLabel(app,
text="Please insert the YouTube video link below:",
font=("Helvetica", 14),
text_color="#FFFFFF")
instructionLabel.pack(pady=(0, 10))
# Entry field for URL input
url_var = tkinter.StringVar()
link = customtkinter.CTkEntry(app,
width=350,
height=40,
textvariable=url_var,
placeholder_text="Enter YouTube URL",
fg_color="#333333",
text_color="white",
border_color="#00BFFF")
link.pack(pady=(0, 20))
# Label to display finish messages
finishLabel = customtkinter.CTkLabel(app, text="", font=("Helvetica", 12))
finishLabel.pack()
# Percentage label for download progress
pPercentage = customtkinter.CTkLabel(app, text="0%", font=("Helvetica", 12))
pPercentage.pack(pady=(10, 0))
# Progress bar for download status
progressBar = customtkinter.CTkProgressBar(app, width=400, progress_color="#00BFFF")
progressBar.set(0)
progressBar.pack(pady=(0, 20))
# Button to initiate the download
download_button = customtkinter.CTkButton(app,
text="Download",
command=Download,
fg_color="#00BFFF",
hover_color="#0080FF")
download_button.pack(pady=20)
# Run the app loop
app.mainloop()