0

I'm making a GUI program capable of downloading a video or audio from YouTube with the user being able to choose the resolution or bitrate.

I want to add the functioning of the progress bar that was already defined in "Ui_MainWindow". I know I must use QThread and Signal from the PySide6 library, but all my attempts so far have been unsuccessful. Every help is welcome.

Follow the code below:

from PySide6 import QtWidgets
from PySide6.QtWidgets import(QApplication,QMainWindow,QWidget, QProgressBar)
from PySide6.QtCore import *
from PySide6.QtGui import *
import pytube
from pytube import YouTube
import sys
import os
import requests

from mainscreen_ui import Ui_MainWindow

class MainWindow(QMainWindow,Ui_MainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.setWindowTitle("YouTube Downloader")

        self.comboBox_resolucao.clear()
        self.comboBox_2.clear()

        self.comboBox_resolucao.setEnabled(False)
        self.comboBox_2.setEnabled(False)

        #Define o diretório inicial
        diretorio = str(sys.path[0])
        self.label_diretorio.setText(diretorio)

        #Se o botão "Button_pesquisa" for precionado executa a funçao "get_video_info"
        self.Button_pesquisa.clicked.connect(self.get_video_info)

        #Se o botão "Button_iniciar_video" for precionado executa a funçao ""
        self.Button_iniciar_video.clicked.connect(self.download_video)

        #Se o botão "Button_iniciar_audio" for precionado executa a funçao ""
        self.Button_iniciar_audio.clicked.connect(self.download_audio)

        #Se o botão "Button_diretorio" for precionado executa a funçao "select_diretorio"
        self.Button_diretorio.clicked.connect(self.select_diretorio)

        self.progressBar.setValue(0)

    def select_diretorio(self):

        #Atribui a variável diretorio o local que o usuário escolher
        diretorio = str(QtWidgets.QFileDialog.getExistingDirectory())

        #Exibe o diretório escolhido
        self.label_diretorio.setText(diretorio)

    def get_video_info(self):

        #Seta os locais de Informações como vazios
        self.label_tituloyt.setText("")
        self.label_tituloyt_2.setText("")
        self.label_thumb.clear()
        self.label_thumb_2.clear()

        self.comboBox_resolucao.clear()
        self.comboBox_2.clear()

        #Recebe o link digitado 
        url = self.lineEdit_link.text()

        try:
            video = YouTube(url)
        except pytube.exceptions.PytubeError:
            QtWidgets.QMessageBox.critical(
                self,
                "Erro",
                "Não foi possível obter informações sobre o vídeo. Verifique se o link é válido e se está conectado à internet.",
                QtWidgets.QMessageBox.Ok
            )
            return

        #Carrega a URL do link
        urlthumbnail = video.thumbnail_url

        #Exibe a imagem do Link
        imagem = QImage()
        imagem.loadFromData(requests.get(urlthumbnail).content)
        self.label_thumb.setPixmap(QPixmap(imagem))
        self.label_thumb_2.setPixmap(QPixmap(imagem))

        #Exibe o título do vídeo 
        self.label_tituloyt.setText(video.title)
        self.label_tituloyt_2.setText(video.title)

        # Adicionando resoluçoes para a comboBox_resolucao"
        stream_query = video.streams.filter(progressive=True, file_extension='mp4')
        self.comboBox_resolucao.clear()
        for stream in stream_query:
            self.comboBox_resolucao.addItem(str(stream.resolution))
        self.comboBox_resolucao.setEnabled(True)

        # Adicionando qualidades para a comboBox_2"
        stream_query = video.streams.filter(only_audio=True).order_by('abr').desc()
        self.comboBox_2.clear()
        for stream in stream_query:
            self.comboBox_2.addItem(str(stream.abr) + " (" + str(stream.mime_type) + ")")
        self.comboBox_2.setEnabled(True)

    def download_video(self):

        #Recebe o diretório e adiciona umm local específico de salvamento
        diretorionalabel = self.label_diretorio.text()+'/YouTubeDownloader/Vídeos'

        url = self.lineEdit_link.text()
        video = YouTube(url)

        stream_query = video.streams.filter(progressive=True, file_extension='mp4')
        selected_resoluçao = self.comboBox_resolucao.currentText()

        # Verifica se já existe um arquivo com o mesmo nome no diretório
        nome_arquivo = f"{video.title}_{selected_resoluçao}.mp4"
        numero_sequencial = 1
        while os.path.exists(os.path.join(diretorionalabel, nome_arquivo)):
            nome_arquivo = f"{video.title}_{selected_resoluçao}_{numero_sequencial}.mp4"
            numero_sequencial += 1
 
        # Faz o download do vídeo e salva com o nome verificado
        for stream in stream_query:
            if str(stream.resolution) == selected_resoluçao:
                self.progressBar.setValue(0)
                stream.download(output_path=diretorionalabel, filename=nome_arquivo)
                return
 
    def download_audio(self):
        # Recebe o diretório e adiciona um local específico de salvamento
        diretorionalabel = os.path.join(self.label_diretorio.text(), 'YouTubeDownloader', 'Áudios')

        url = self.lineEdit_link.text()
        video = YouTube(url)

        # Define a stream do áudio em formato mp4
        stream_query = video.streams.filter(only_audio=True, file_extension='mp4')
        selected_ab_bitrate = self.comboBox_2.currentText()

        # Verifica se já existe um arquivo com o mesmo nome no diretório
        nome_arquivo = f"{video.title}_{selected_ab_bitrate}.mp3"
        numero_sequencial = 1
        while os.path.exists(os.path.join(diretorionalabel, nome_arquivo)):
            nome_arquivo = f"{video.title}_{selected_ab_bitrate}_{numero_sequencial}.mp3"
            numero_sequencial += 1

        # Faz o download do áudio e salva com o nome verificado
        for stream in stream_query:
            if str(stream.abr) == selected_ab_bitrate:
                stream.download(output_path=diretorionalabel, filename=nome_arquivo)
                return


if __name__ == "__main__":
    app = QApplication(sys.argv)
    janela = MainWindow()
    janela.show()
    app.exec()

I already know that I must create a class with QThread for the progress of the progress bar to work, but I was not successful.

  • 1
    If you didn't succeeded in using QThread, then show us your attempts. There are dozens of similar posts even here on StackOverflow, and most of them are duplicates because their OPs didn't provide enough code or didn't study the documentation as they should have. So unless you provide us some valid [mre] of your attempts, your post will eventually be closed just like the others. Sorry, but SO is not a tutorial website, we don't just tell you how to do things, we answer to specific and detailed questions in order to provide help to both you and anybody else who may be facing the same problem. – musicamante Apr 23 '23 at 02:52
  • [Use PyQt's QThread to Prevent Freezing GUIs](https://realpython.com/python-pyqt-qthread/). – ekhumoro Apr 23 '23 at 11:21

0 Answers0