-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b852b9a
commit 85712af
Showing
2 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import sys | ||
import os | ||
import subprocess | ||
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QPushButton, QRadioButton, QProgressBar, \ | ||
QLabel | ||
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer | ||
|
||
|
||
|
||
class Downloader(QThread): | ||
progress = pyqtSignal(str) | ||
|
||
def __init__(self, url, quality, download_dir): | ||
super().__init__() | ||
self.url = url | ||
self.quality = quality | ||
self.download_dir = download_dir | ||
|
||
def run(self): | ||
self.download_video() | ||
|
||
def download_video(self): | ||
command = [] | ||
|
||
if self.quality == "MP3 Only": | ||
command = ["yt-dlp", "-f", "bestaudio[ext=m4a]/bestaudio", "-x", "--audio-format", "mp3", "-o", | ||
os.path.join(self.download_dir, "%(title)s.%(ext)s"), self.url] | ||
elif self.quality == "720p": | ||
command = ["yt-dlp", "-f", "best[height<=720][ext=mp4]", "-o", | ||
os.path.join(self.download_dir, "%(title)s.%(ext)s"), self.url] | ||
elif self.quality == "1080p": | ||
command = ["yt-dlp", "-f", | ||
"bestvideo[height<=?1080][vbr<=?10000][fps<=?120][ext=mp4]+bestaudio[abr<=?192]/best[ext=mp4]/best", | ||
"-o", os.path.join(self.download_dir, "%(title)s.%(ext)s"), self.url] | ||
elif self.quality == "Highest Available": | ||
command = ["yt-dlp", "-f", "bestvideo+bestaudio[fps<=?120]", "-o", | ||
os.path.join(self.download_dir, "%(title)s.%(ext)s"), self.url] | ||
|
||
# For now, simply notify the GUI that we are downloading and then complete. | ||
# Ideally, you would capture yt-dlp's output and update the progress bar more granularly. | ||
self.progress.emit("Downloading...") | ||
subprocess.run(command, capture_output=True) | ||
self.progress.emit("Complete!") | ||
|
||
|
||
class App(QWidget): | ||
def __init__(self): | ||
super().__init__() | ||
self.init_ui() | ||
|
||
def init_ui(self): | ||
layout = QVBoxLayout() | ||
|
||
self.url_input = QLineEdit(self) | ||
self.url_input.setPlaceholderText("Enter YouTube URL") | ||
|
||
self.mp3_btn = QRadioButton("MP3 Only", self) | ||
self._720p_btn = QRadioButton("720p", self) | ||
self._1080p_btn = QRadioButton("1080p", self) | ||
self.highest_btn = QRadioButton("Highest Available", self) | ||
self.mp3_btn.setChecked(True) | ||
|
||
self.download_btn = QPushButton('Download', self) | ||
self.download_btn.clicked.connect(self.download_video) | ||
|
||
self.progress_bar = QProgressBar(self) | ||
self.progress_bar.setRange(0, 100) | ||
self.progress_label = QLabel("", self) | ||
self.progress_bar.hide() | ||
self.progress_label.hide() | ||
|
||
layout.addWidget(self.url_input) | ||
layout.addWidget(self.mp3_btn) | ||
layout.addWidget(self._720p_btn) | ||
layout.addWidget(self._1080p_btn) | ||
layout.addWidget(self.highest_btn) | ||
layout.addWidget(self.download_btn) | ||
layout.addWidget(self.progress_label) | ||
layout.addWidget(self.progress_bar) | ||
|
||
self.setLayout(layout) | ||
self.setWindowTitle('YouTube Video Downloader') | ||
self.resize(400, 200) | ||
self.show() | ||
|
||
def download_video(self): | ||
url = self.url_input.text() | ||
download_dir = os.path.join(os.path.expanduser("~"), "Downloads") | ||
|
||
if self.mp3_btn.isChecked(): | ||
quality = "MP3 Only" | ||
elif self._720p_btn.isChecked(): | ||
quality = "720p" | ||
elif self._1080p_btn.isChecked(): | ||
quality = "1080p" | ||
else: | ||
quality = "Highest Available" | ||
|
||
self.downloader = Downloader(url, quality, download_dir) | ||
self.downloader.progress.connect(self.update_progress) | ||
self.downloader.start() | ||
|
||
def update_progress(self, status): | ||
if status == "Downloading...": | ||
self.progress_label.setText("Downloading...") | ||
self.progress_label.show() | ||
self.progress_bar.setValue(50) | ||
self.progress_bar.show() | ||
elif status == "Complete!": | ||
self.progress_label.setText("Download Complete!") | ||
self.progress_bar.setValue(100) | ||
QTimer.singleShot(10000, self.progress_label.hide) # hide status bar after 10 seconds | ||
QTimer.singleShot(10000, self.progress_bar.hide) | ||
|
||
|
||
app = QApplication(sys.argv) | ||
app.setStyleSheet(""" | ||
QWidget { | ||
background-color: #333; | ||
} | ||
QLabel, QRadioButton { | ||
color: #fff; | ||
} | ||
QPushButton { | ||
background-color: #555; | ||
color: #fff; | ||
padding: 5px 15px; | ||
border: none; | ||
} | ||
QPushButton:hover { | ||
background-color: #666; | ||
} | ||
QLineEdit { | ||
background-color: #555; | ||
color: #fff; | ||
padding: 5px; | ||
border: none; | ||
} | ||
""") | ||
window = App() | ||
sys.exit(app.exec_()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import sys | ||
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLineEdit, QFileDialog, QComboBox, QLabel, \ | ||
QMessageBox | ||
from PyQt5.QtGui import QIcon | ||
from moviepy.editor import VideoFileClip | ||
import os | ||
|
||
class VideoConverterApp(QWidget): | ||
def __init__(self): | ||
super().__init__() | ||
self.initUI() | ||
|
||
def initUI(self): | ||
layout = QVBoxLayout() | ||
|
||
self.filePathLineEdit = QLineEdit(self) | ||
browseButton = QPushButton('Browse', self) | ||
browseButton.clicked.connect(self.browse_file) | ||
|
||
self.formatLabel = QLabel('Select output format:', self) | ||
self.formatComboBox = QComboBox(self) | ||
self.formatComboBox.addItems(['.mp4', '.avi', '.mkv', '.flv', '.mov']) | ||
|
||
convertButton = QPushButton('Convert', self) | ||
convertButton.clicked.connect(self.convert_video) | ||
|
||
self.conversionStatusLabel = QLabel('', self) | ||
|
||
layout.addWidget(self.filePathLineEdit) | ||
layout.addWidget(browseButton) | ||
layout.addWidget(self.formatLabel) | ||
layout.addWidget(self.formatComboBox) | ||
layout.addWidget(convertButton) | ||
layout.addWidget(self.conversionStatusLabel) | ||
|
||
self.setLayout(layout) | ||
|
||
self.setStyleSheet(""" | ||
QWidget { | ||
background-color: #333; | ||
} | ||
QLabel, QPushButton, QComboBox, QLineEdit { | ||
color: #fff; | ||
} | ||
QPushButton { | ||
background-color: #555; | ||
border: 2px solid #888; | ||
} | ||
QPushButton:hover { | ||
background-color: #666; | ||
} | ||
""") | ||
|
||
self.setWindowTitle('PyRate Converter') | ||
self.setGeometry(100, 100, 400, 200) | ||
|
||
def browse_file(self): | ||
options = QFileDialog.Options() | ||
filePath, _ = QFileDialog.getOpenFileName(self, "Select Video File", "", | ||
"Video Files (*.webm *.mp4 *.avi *.mkv *.flv *.mov);;All Files (*)", | ||
options=options) | ||
if filePath: | ||
self.filePathLineEdit.setText(filePath) | ||
|
||
def convert_video(self): | ||
input_path = self.filePathLineEdit.text() | ||
output_format = self.formatComboBox.currentText() | ||
|
||
if not input_path: | ||
QMessageBox.warning(self, 'Warning', 'Please select a video file.') | ||
return | ||
|
||
self.conversionStatusLabel.setText("Converting... this may take awhile...") | ||
|
||
QApplication.processEvents() | ||
|
||
clip = VideoFileClip(input_path) | ||
output_path = input_path.rsplit('.', 1)[0] + output_format | ||
|
||
try: | ||
clip.write_videofile(output_path, codec='libx264' if output_format == '.mp4' else 'mpeg4') | ||
os.remove(input_path) | ||
self.conversionStatusLabel.setText("") | ||
QMessageBox.information(self, 'Success', 'Conversion has completed!') | ||
except Exception as e: | ||
self.conversionStatusLabel.setText("") | ||
QMessageBox.critical(self, 'Error', f"Error occurred: {str(e)}") | ||
|
||
|
||
if __name__ == '__main__': | ||
app = QApplication(sys.argv) | ||
ex = VideoConverterApp() | ||
ex.show() | ||
sys.exit(app.exec_()) |