# Importando os módulos necessários import os import subprocess from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, QMessageBox, QVBoxLayout, \ QHBoxLayout, QComboBox, QProgressBar from PyQt5.QtCore import QThread, pyqtSignal from pytube import YouTube # Criando uma classe para a thread que faz o download class DownloadThread(QThread): # Definindo os sinais personalizados progress_signal = pyqtSignal(int) complete_signal = pyqtSignal(str) error_signal = pyqtSignal(str) def __init__(self, url, format): super().__init__() # Recebendo os parâmetros da interface gráfica self.url = url self.format = format def run(self): # Tentando baixar o vídeo usando o pytube try: yt = YouTube(self.url) if self.format == "MP4": stream = yt.streams.first() elif self.format == "MP3": stream = yt.streams.filter(only_audio=True).first() # Registrando as funções de callback para o progresso e a conclusão do download yt.register_on_progress_callback(self.on_progress) yt.register_on_complete_callback(self.on_complete) # Fazendo o download do vídeo ou do áudio na pasta padrão ou na pasta "audio" if self.format == "MP4": stream.download() elif self.format == "MP3": stream.download(output_path="audio", filename_prefix="audio_") except Exception as e: # Emitindo um sinal de erro se ocorrer alguma exceção self.error_signal.emit(str(e)) def on_progress(self, stream, chunk, bytes_remaining): # Calculando o progresso do download em porcentagem size = stream.filesize progress = int((size - bytes_remaining) / size * 100) # Emitindo um sinal de progresso com o valor atual self.progress_signal.emit(progress) def on_complete(self, stream, file_path): # Se o formato for MP3, converte o arquivo baixado usando ffmpeg if self.format == "MP3": new_file_path = file_path.replace(".mp4", ".mp3") subprocess.run( [ "ffmpeg", "-i", os.path.join("audio", file_path), os.path.join("audio", new_file_path), ] ) # Apaga o arquivo original em formato webm os.remove(file_path) # Atualiza a variável file_path com o novo caminho do arquivo mp3 file_path = new_file_path # Emitindo um sinal de conclusão com o título do vídeo e o caminho do arquivo self.complete_signal.emit(stream.title + "|" + file_path) class App(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): # Definindo o título e o tamanho da janela self.setWindowTitle('Download de vídeos do YouTube') self.resize(400, 200) # Criando um rótulo para a URL self.label = QLabel('Digite a URL do vídeo:', self) # Criando uma caixa de texto para a URL self.url = QLineEdit(self) # Criando um botão para baixar o vídeo self.button = QPushButton('Baixar', self) self.button.clicked.connect(self.download) # Criando um ComboBox para escolher o formato do download self.format = QComboBox(self) self.format.addItem("MP4") self.format.addItem("MP3") # Criando uma barra de progresso para mostrar o andamento do download self.progress = QProgressBar(self) # Criando um layout vertical vbox = QVBoxLayout() # Criando um layout horizontal para a URL e o botão hbox1 = QHBoxLayout() hbox1.addWidget(self.label) hbox1.addWidget(self.url) vbox.addLayout(hbox1) # Adicionando o ComboBox ao layout vertical vbox.addWidget(self.format) # Adicionando a barra de progresso ao layout vertical vbox.addWidget(self.progress) # Criando um layout horizontal para o botão hbox2 = QHBoxLayout() hbox2.addStretch(1) hbox2.addWidget(self.button) hbox2.addStretch(1) vbox.addLayout(hbox2) # Definindo o layout da janela self.setLayout(vbox) # Mostrando a janela self.show() def download(self): # Obtendo a URL digitada pelo usuário url = self.url.text() # Verificando se a URL é válida if url.startswith('https://www.youtube.com/watch?v='): # Obtendo o formato escolhido pelo usuário format = self.format.currentText() # Criando uma instância da thread de download com os parâmetros da interface gráfica self.thread = DownloadThread(url, format) # Conectando os sinais da thread às funções da interface gráfica self.thread.progress_signal.connect(self.update_progress) self.thread.complete_signal.connect(self.show_complete_message) self.thread.error_signal.connect(self.show_error_message) # Iniciando a thread de download self.thread.start() # Desabilitando o botão enquanto o download estiver em andamento self.button.setEnabled(False) else: # Mostrando uma mensagem de aviso se a URL for inválida QMessageBox.warning(self, 'Aviso', 'URL inválida. Digite uma URL válida do YouTube.') def update_progress(self, value): # Atualizando o valor da barra de progresso com o sinal recebido da thread self.progress.setValue(value) def show_complete_message(self, message): # Recebendo o título do vídeo e o caminho do arquivo separados por "|" title, file_path = message.split("|") # Mostrando uma mensagem de sucesso quando o download for concluído QMessageBox.information(self, 'Sucesso', f'Vídeo {title} baixado com sucesso em {file_path}.') # Habilitando o botão novamente self.button.setEnabled(True) def show_error_message(self, error): # Mostrando uma mensagem de erro se ocorrer alguma exceção na thread de download QMessageBox.critical(self, 'Erro', f'Ocorreu um erro ao baixar o vídeo: {error}') # Habilitando o botão novamente self.button.setEnabled(True) # Criando uma instância da aplicação e executando-a app = QApplication([]) ex = App() app.exec_()