首页 > 解决方案 > 在 youtube 下载器 kivy 应用程序中没有响应

问题描述

我用 Python 编写了这个程序:

import os
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from time import sleep
import pytube
import scrapetube
from pathlib import Path

save_addr = f"{os.environ['USERPROFILE']}\Downloads\Youtube DL"
print(save_addr)

layout = BoxLayout

def youtube_dl(video,addr):
        #yt = pytube.YouTube(f"{link.text}")
        #ys = yt.streams.get_highest_resolution()
        #ys.download()
        video = str(video.text)
        try:
            yt = pytube.YouTube(video)
            ys = yt.streams.get_highest_resolution()
            ys.download(output_path=addr)
        except pytube.exceptions.RegexMatchError:
            print('The Regex pattern did not return any matches for the video: {}'.format(video))          
        except pytube.exceptions.ExtractError:
            print('An extraction error occurred for the video: {}'.format(video))         
        except pytube.exceptions.VideoUnavailable:
            print('The following video is unavailable: {}'.format(video))

class cd:
    """Context manager for changing the current working directory"""
    def __init__(self, newPath):
        self.newPath = os.path.expanduser(newPath)

    def __enter__(self):
        self.savedPath = os.getcwd()
        os.chdir(self.newPath)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.savedPath)


class MyGrid(layout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.orientation = "vertical"
        self.spacing = 20
        self.padding = [10, 10]
        self.cols = 1
        self.label = Label(text="Enter link of Video You Want to Download!")
        self.add_widget(self.label)
        self.link = TextInput(hint_text="Example: youtube.com/watch?v=MXDHK_MqRsk", multiline=False)
        self.add_widget(self.link)
        self.btn = Button(text="OK!")
        self.btn.bind(on_press=lambda x:self.callback())
        self.add_widget(self.btn)
        sleep(3)

    def callback(self):
        def dl(video,addr,DL=True):
            try:
                yt = pytube.YouTube(video)
                if DL:
                    ys = yt.streams.get_highest_resolution()
                    cd(addr)
                    ys.download(output_path=addr)
            except pytube.exceptions.RegexMatchError:
                print('The Regex pattern did not return any matches for the video: {}'.format(video))          
            except pytube.exceptions.ExtractError:
                print('An extraction error occurred for the video: {}'.format(video))         
            except pytube.exceptions.VideoUnavailable:
                print('The following video is unavailable: {}'.format(video))
            return yt
        video = str(self.link.text)
        title = str(dl(video,self.link,DL=False).title)
        self.label.text = f"Download : \"{title}\" , Save in:"
        self.link.text = f"{save_addr}"
        self.btn.text = "Download video!"
        self.btn.bind(on_press=lambda x:dl(video,self.link.text))

class MyKivy(App):
        def build(self):
            return MyGrid()

if __name__ == "__main__":
    MyKivy().run()

我的问题是,当我把视频链接放到程序中,点击下载,从YouTube下载视频时,显示没有响应的消息,但下载完成后,程序恢复正常:

此错误的图像

我可以做些什么来防止显示没有响应的消息?

标签: pythonkivypytube

解决方案


为了防止这种情况,您必须使用多线程,这意味着您可以同时执行多个任务,这将防止 UI 冻结,因为它将在与下载器运行的线程不同的线程中运行。您将创建一个函数来在线程中运行下载器,如下所示:

import threading
def run_thread(self,*args):
    thread_dl = thrading.Thread(target = self.downloader,args = (arg1,arg2,arg3))
    thread_dl.start()

您将将此功能编辑为按钮 on_press 功能


推荐阅读