2017-10-28 123 views
0

我正在使用trollius(for async),htmlpy和pafy(和youtube-dl)为Youtube视频制作一个小型下载器。现在我遇到了一个问题,一旦我点击下载按钮,当backend正在下载视频时,UI冻结。如何停止htmlpy ui拦截

我试图让downloader类成为自己的线程,并运行在UI旁边,但这似乎不起作用。我还尝试使用coroutine异步执行视频下载,而UI继续。似乎都没有工作。

下面是一些代码

class Downloader(htmlPy.Object,threading.Thread): 
dd = os.path.join(os.getenv('USERPROFILE'), 'Downloads') # dd = download director 
dd = dd + "/vindownload/" 

def __init__(self, app): 
    threading.Thread.__init__(self) 
    super(Downloader, self).__init__() 
    # Initialize the class here, if required. 
    self.app = app 
    return 

@htmlPy.Slot(str) 
def download_single(self, json_data): 
    form_data = json.loads(json_data) 
    print json_data 
    url = form_data["name"] 
    dt = form_data["dt"] # Download type is audio or video 
    if url.__contains__("https://www.youtube.com/watch?v="): 
     if dt == 'audio': 
      print "hello1" 
      loop = trollius.get_event_loop() 
      loop.run_until_complete(self._downloadVid(url, vid=False)) 
      loop.stop() 
     else: 
      print "hello1" 
      loop = trollius.get_event_loop() 
      loop.run_until_complete(self._downloadVid(url, vid=True)) 
      loop.stop() 
     self.app.evaluate_javascript("document.getElementById('form').reset()") 
    else: 
     print "Incorrect url" 
    print form_data 

@trollius.coroutine 
def _downloadVid(self, url, vid=False, order_reverse=False, vinName=None): 
    print "hello123" 
    video = pafy.new(url) 
    print video 
    name = u''.join(video.title).encode('utf8') 
    name = re.sub("[<>:\"/\\|?*]", "", name) 
    if not vid: 
     file = video.getbestaudio() 
    else: 
     file = video.getbest() 
    if (order_reverse): 
     file.download(self.dd + vinName + name + ".mp4", quiet=False,callback=self.mycb) 
    else: 
     file.download(self.dd + name + ".mp4", quiet=False,callback=self.mycb) 

def mycb(self,total, recvd, ratio, rate, eta): 
    print(recvd, ratio, eta) 

和我initialize.py

BASE_DIR = os.path.abspath(os.path.dirname("initilize.py")) 

app = htmlPy.AppGUI(title=u"Vin download", width=700, height=400, resizable=False) 

app.static_path = os.path.join(BASE_DIR, "static/") 
app.template_path = os.path.join(BASE_DIR, "templates/") 

app.web_app.setMaximumWidth(830) 
app.web_app.setMaximumHeight(600) 

download = Downloader(app) 
download.start() 

# Register back-end functionalities 
app.bind(download) 
app.template = ("./index.html", {"template_variable_name": "value"}) 

# Instructions for running application 
if __name__ == "__main__": 
    # The driver file will have to be imported everywhere in back-end. 
    # So, always keep app.start() in if __name__ == "__main__" conditional 
    app.start() 

现在我的问题是。有没有一种方法可以在下载时释放我的UI,因此看起来不像应用程序崩溃。

我正在使用:Python 2.7,Trollius,Pafy,Youtube-dl,HTMLPY。

谢谢你的时间。

回答

0

好吧我找到了我的问题的答案,这里是我所做的。我改变了我的download_single方法如下:

@htmlPy.Slot(str) 
def download_single(self, json_data): 
    form_data = json.loads(json_data) 
    print json_data 
    url = form_data["name"] 
    dt = form_data["dt"] # Download type is audio or video 
    videoDown = videoDownload(url, dt, self.app, self.dd) 
    videoDown.start() 
    print form_data 

我和它先前的代码,现在被转移到一个名为videoDownload新类采取所有上述属性。

videoDownload.py

class videoDownload(threading.Thread): 
def __init__(self, url, dt, app, dd): 
    threading.Thread.__init__(self) 
    self.url = url 
    self.dt = dt 
    self.app = app 
    self.dd = dd 

def run(self): 
    threads.append(self) 
    if self.url.__contains__("https://www.youtube.com/watch?v="): 
     if self.dt == 'audio': 
      print "hello1" 
      self._downloadVid(self.url, vid=False) 
     else: 
      print "hello1" 
      self._downloadVid(self.url, vid=True) 
    else: 
     print "Incorrect url" 

def _downloadVid(self, url, vid=False, order_reverse=False, vinName=None): 
    print "hello123" 
    video = pafy.new(url) 
    print video 
    name = u''.join(video.title).encode('utf8') 
    name = re.sub("[<>:\"/\\|?*]", "", name) 
    if not vid: 
     file = video.getbestaudio() 
    else: 
     file = video.getbest() 
    if (order_reverse): 
     file.download(self.dd + vinName + name + ".mp4", quiet=False, callback=self.mycb) 
    else: 
     file.download(self.dd + name + ".mp4", quiet=False, callback=self.mycb) 
    threads.remove(self) 

def mycb(self, total, recvd, ratio, rate, eta): 
    pass 

这解决了问题,我曾与UI被封锁。一旦离开run方法,线程将自行结束,并且它将从类上方定义的线程数组中移除。

有一个伟大的一天的所有

〜Ellisan