如何使用Python 3在线程中停止youtube-dl下载

5

我有一个从特定URL下载视频的函数,我通过线程启动此函数以避免GUI冻结,但我想要一个停止或暂停下载的功能。如何实现? 下面是代码:

def download_videos(self):
     ydl1 = youtube_dl.YoutubeDL(self.get_opts())
     if self.get_Urls().__len__() > 0:
         ydl1.download(self.get_Urls())

def downloadVideoThrd(self):
    self.t1 = threading.Thread(target=self.download_videos())
    self.t1.start()

以下内容可能会对您感兴趣:https://dev59.com/wXRC5IYBdhLWcg3wW_pk,https://dev59.com/EWw15IYBdhLWcg3wkcuq。 - SuperShoot
1个回答

1
您可以使用以下两个选项。使用multiprocessing库替代threading,或在子线程中引发SystemExit异常。
注意:当我测试youtube-dl时,它会从上次下载的位置继续下载。这就是为什么当我们开始下载相同的URL时,youtube-dl会恢复下载,但已下载的文件需要在文件系统中。
以下是第一个选项,在此解决方案中,我们不使用线程,而是使用子进程,因为我们可以向子进程发送任何信号,并根据需要处理此信号。
import multiprocessing
import time
import ctypes,signal,os
import youtube_dl

class Stop_Download(Exception): # This is our own special Exception class
    pass

def usr1_handler(signum,frame): # When signal comes, run this func
    raise Stop_Download

def download_videos(resume_event):
     signal.signal(signal.SIGUSR1,usr1_handler)

     def download(link):
         ydl1 = youtube_dl.YoutubeDL()
         ydl1.download([link])

     try:
         download(link)

     except Stop_Download: #catch this special exception and do what ever you want
         print("Stop_Download exception")
         resume_event.wait() # wait for event to resume or kill this process by sys.exit()
         print("resuming")
         download(link)

def downloadVideoThrd():
    resume_event=multiprocessing.Event()
    p1 = multiprocessing.Process(target=download_videos,args=(resume_event,))
    p1.start()
    print("mp start")
    time.sleep(5)
    os.kill(p1.pid,signal.SIGUSR1) # pause the download
    time.sleep(5)
    down_event.set() #resume downlaod
    time.sleep(5)
    os.kill(p1.pid,signal.SIGUSR2) # stop the download

downloadVideoThrd()

以下是第二种解决方案,您也可以查看此处以获取有关终止线程的更多详细信息。我们将在主线程中通过子线程引发SystemExit异常。我们可以停止或暂停线程。要暂停线程,您可以使用threading.Event()类。要停止线程(而不是进程),您可以使用sys.exit()

import ctypes,time, threading
import youtube_dl,

def download_videos(self):
    try:
        ydl1 = youtube_dl.YoutubeDL(self.get_opts())
        if self.get_Urls().__len__() > 0:
            ydl1.download(self.get_Urls())
    except SystemExit:
        print("stopped")
        #do whatever here

def downloadVideoThrd(self):
    self.t1 = threading.Thread(target=self.download_videos)
    self.t1.start()
    time.sleep(4)     
    """
    raise SystemExit exception in self.t1 thread
    """    
    ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(self.t1.ident),
                                            ctypes.py_object(SystemExit))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接