diff --git a/yt_dlp/downloader/bunnycdn.py b/yt_dlp/downloader/bunnycdn.py index e95fe34a3..150fdd6bc 100644 --- a/yt_dlp/downloader/bunnycdn.py +++ b/yt_dlp/downloader/bunnycdn.py @@ -20,51 +20,32 @@ def real_download(self, filename, info_dict): fd = HlsFD(self.ydl, self.params) - success = download_complete = False - ping_lock = threading.Lock() + stop_event = threading.Event() + ping_thread = threading.Thread(target=self.ping_thread, args=(stop_event,), kwargs=info_dict['_bunnycdn_ping_data']) + ping_thread.start() - timer = None - current_time = 0 + try: + return fd.real_download(filename, info_dict) + finally: + stop_event.set() - ping_url = info_dict['_bunnycdn_ping_data']['url'] - headers = info_dict['_bunnycdn_ping_data']['headers'] - secret = info_dict['_bunnycdn_ping_data']['secret'] - context_id = info_dict['_bunnycdn_ping_data']['context_id'] + + def ping_thread(self, stop_event, url, headers, secret, context_id): # Site sends ping every 4 seconds, but this throttles the download. Pinging every 2 seconds seems to work. ping_interval = 2 + # Hard coded resolution as it doesn't seem to matter + res = 1080 + paused = 'false' + current_time = 0 + + while not stop_event.wait(ping_interval): + current_time += ping_interval - def send_ping(): - nonlocal timer, current_time time = current_time + round(random.random(), 6) - # Hard coded resolution as it doesn't seem to matter - res = 1080 - paused = 'false' md5_hash = hashlib.md5(f'{secret}_{context_id}_{time}_{paused}_{res}'.encode()).hexdigest() - - request = Request( - f'{ping_url}?hash={md5_hash}&time={time}&paused={paused}&resolution={res}', - headers=headers) + ping_url = f'{url}?hash={md5_hash}&time={time}&paused={paused}&resolution={res}' try: - self.ydl.urlopen(request).read() + self.ydl.urlopen(Request(ping_url, headers=headers)).read() except network_exceptions as e: self.to_screen(f'[{self.FD_NAME}] Ping failed: {e}') - - with ping_lock: - if not download_complete: - current_time += ping_interval - timer = threading.Timer(ping_interval, send_ping) - timer.start() - - # Start ping loop - self.to_screen(f'[{self.FD_NAME}] Starting pings with {ping_interval} second interval...') - try: - send_ping() - success = fd.real_download(filename, info_dict) - finally: - with ping_lock: - if timer: - timer.cancel() - download_complete = True - - return success