当下载视频时,Kivy会冻结

时间:2018-02-04 19:46:12

标签: python-3.x kivy pytube

我想创建一个使用pytube和kivy下载youtube视频的应用。问题是应用程序冻结,然后在下载开始时停止响应。我知道它开始下载,因为它创建了一个mp4文件。我研究了调度和多线程,但我不知道这些是如何工作的,我甚至不确定它们是否能解决我的问题。谁能告诉我在哪里看?

python文件:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout

from pytube import YouTube

class MyWidget(BoxLayout):
    def download_video(self, link):
         yt = YouTube(link)
         yt.streams.first().download()

class Youtube(App):
    pass

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

kivy文件:

 MyWidget:

 <MyWidget>:

 BoxLayout:
     orientation: 'horizontal'
     Button:
        text: 'press to download'
        on_press: root.download_video(url.text)
     TextInput:
        text: 'paste the youtube URL here'
        id: url

1 个答案:

答案 0 :(得分:0)

我最近因为线程化而被吓倒,谈论GIL。线程库本身并不太复杂,但这个问题对它来说是一个很好的用例。

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from pytube import YouTube

# import Thread from threading
from threading import Thread

class MyWidget(BoxLayout):

     # Create a start_download method
    def start_download(self):
        # Creates a new thread that calls the download_video method
        download = Thread(target=self.download_video)

        # Starts the new thread
        download.start()

    def download_video(self):
         # I implemented the text grabbing here because I came across a weird error if I passed it from the button (something about 44 errors?) 
         yt = YouTube(self.ids.url.text)
         yt.streams.first().download()

class Youtube(App):

    def build(self):
        return MyWidget()

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

youtube.kv

<MyWidget>:
    orientation: 'horizontal'
    Button:
        text: 'press to download'
        # Call the start download method to create a new thread rather than override the current.
        on_press: root.start_download()
    TextInput:
        text: 'paste the youtube URL here'
        id: url

1)您输入网址

2)您点击下载按钮

3)这会触发start_download方法。

4)start_download创建一个运行下载方法的线程,该方法将当前时间的url.text 作为参数。这意味着您可以输入其他网址,而下载时不会覆盖之前调用中的网址文本,因为它们位于不同的执行线程中。

Video Example