-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathytpyrate.py
200 lines (167 loc) · 7.03 KB
/
ytpyrate.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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import os
import sys
from PyQt6.QtWidgets import (
QApplication, QMainWindow, QLabel, QLineEdit, QPushButton, QFileDialog,
QVBoxLayout, QWidget, QMessageBox, QComboBox, QProgressBar, QFrame
)
from PyQt6.QtGui import QFont
from PyQt6.QtCore import Qt, QThread, pyqtSignal
from pytube import YouTube
class DownloadThread(QThread):
progress = pyqtSignal(int)
finished = pyqtSignal()
def __init__(self, url, save_path, itag):
super().__init__()
self.url = url
self.save_path = save_path
self.itag = itag
def run(self):
yt = YouTube(self.url, on_progress_callback=self.report_progress)
stream = yt.streams.get_by_itag(self.itag)
stream.download(output_path=self.save_path)
self.finished.emit()
def report_progress(self, stream, chunk, bytes_remaining):
total_size = stream.filesize
progress_percent = int((1 - bytes_remaining / total_size) * 100)
self.progress.emit(progress_percent)
class YTPyrate(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("YTPyrate - YouTube Downloader")
self.setFixedSize(520, 480)
self.setStyleSheet("background-color: #09000f; color: white;")
self.font = QFont("Roboto", 12)
self.button_font = QFont("Roboto", 12, QFont.Weight.Bold)
self.input_url = ""
self.output_folder = ""
self.output_filename = ""
self.sizes = []
self.init_ui()
def init_ui(self):
"""Creates the modern UI layout"""
layout = QVBoxLayout()
# Title
title = QLabel("YouTube Video Downloader")
title.setFont(QFont("Roboto", 14, QFont.Weight.Bold))
title.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(title)
# Divider
layout.addWidget(self.create_divider())
# YouTube URL Input
self.url_input = QLineEdit()
self.url_input.setFont(self.font)
self.url_input.setPlaceholderText("Enter YouTube URL")
self.url_input.setStyleSheet("background-color: #6b4a5e; color: white; padding: 6px;")
layout.addWidget(self.url_input)
# Load Video Qualities
self.load_quality_button = QPushButton("Load Video Qualities")
self.load_quality_button.setFont(self.button_font)
self.load_quality_button.setStyleSheet(self.button_style())
self.load_quality_button.clicked.connect(self.load_video_qualities)
layout.addWidget(self.load_quality_button)
# Quality Selector
self.quality_selector = QComboBox()
self.quality_selector.setFont(self.font)
self.quality_selector.setStyleSheet("background-color: #6b4a5e; color: white; padding: 6px;")
layout.addWidget(self.quality_selector)
# Divider
layout.addWidget(self.create_divider())
# Output Folder Selection
self.output_label = QLabel("Save Location: Not selected")
self.output_label.setFont(self.font)
self.output_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(self.output_label)
self.browse_button = QPushButton("Choose Output Folder")
self.browse_button.setFont(self.button_font)
self.browse_button.setStyleSheet(self.button_style())
self.browse_button.clicked.connect(self.browse_location)
layout.addWidget(self.browse_button)
# Divider
layout.addWidget(self.create_divider())
# Download Button
self.download_button = QPushButton("Download Video")
self.download_button.setFont(self.button_font)
self.download_button.setStyleSheet(self.button_style())
self.download_button.clicked.connect(self.download_video)
layout.addWidget(self.download_button)
# Progress Bar
self.progress_bar = QProgressBar()
self.progress_bar.setStyleSheet("background-color: #6b4a5e; color: white;")
self.progress_bar.setValue(0)
layout.addWidget(self.progress_bar)
# Status Label
self.status_label = QLabel("")
self.status_label.setFont(self.font)
self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(self.status_label)
# Set layout
container = QWidget()
container.setLayout(layout)
self.setCentralWidget(container)
def create_divider(self):
"""Creates a modern divider"""
line = QFrame()
line.setFrameShape(QFrame.Shape.HLine)
line.setFrameShadow(QFrame.Shadow.Sunken)
line.setStyleSheet("color: #6b4a5e;")
return line
def button_style(self):
"""Returns a consistent button style"""
return """
QPushButton {
background-color: #6b4a5e;
color: white;
border-radius: 5px;
padding: 8px;
}
QPushButton:hover {
background-color: #8c6278;
}
QPushButton:pressed {
background-color: #5a3a4c;
}
"""
def browse_location(self):
"""Opens folder dialog to select output folder"""
folder = QFileDialog.getExistingDirectory(self, "Select Save Location")
if folder:
self.output_folder = folder
self.output_label.setText(f"Save Location: {folder}")
def load_video_qualities(self):
"""Loads available video and audio qualities"""
url = self.url_input.text().strip()
if not url:
QMessageBox.warning(self, "Error", "Please enter a YouTube URL.")
return
try:
yt = YouTube(url)
self.quality_selector.clear()
for stream in yt.streams.filter(progressive=True):
self.quality_selector.addItem(f"{stream.resolution} - {stream.mime_type}", stream.itag)
for stream in yt.streams.filter(only_audio=True):
self.quality_selector.addItem(f"Audio Only - {stream.mime_type}", stream.itag)
except Exception as e:
QMessageBox.critical(self, "Error", f"Failed to load video qualities: {str(e)}")
def download_video(self):
"""Starts the video download"""
url = self.url_input.text().strip()
save_path = self.output_folder
itag = self.quality_selector.currentData()
if not url or not save_path or itag is None:
QMessageBox.warning(self, "Error", "Please enter all details correctly.")
return
self.status_label.setText("Downloading...")
self.download_thread = DownloadThread(url, save_path, itag)
self.download_thread.progress.connect(self.progress_bar.setValue)
self.download_thread.finished.connect(self.download_complete)
self.download_thread.start()
def download_complete(self):
"""Handles completion of download"""
self.status_label.setText("Download Complete!")
QMessageBox.information(self, "Success", "Download complete!")
self.progress_bar.setValue(0)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = YTPyrate()
window.show()
sys.exit(app.exec())