2025-02-16 14:27:44 -06:00
|
|
|
import hashlib
|
|
|
|
import random
|
|
|
|
import threading
|
|
|
|
|
|
|
|
from .common import FileDownloader
|
|
|
|
from . import HlsFD
|
|
|
|
from ..networking import Request
|
2025-02-17 10:33:26 -06:00
|
|
|
from ..networking.exceptions import network_exceptions
|
2025-02-16 14:27:44 -06:00
|
|
|
|
|
|
|
|
|
|
|
class BunnyCdnFD(FileDownloader):
|
|
|
|
"""Downloads from BunnyCDN with required pings"""
|
|
|
|
|
|
|
|
def real_download(self, filename, info_dict):
|
|
|
|
self.to_screen(f'[{self.FD_NAME}] Downloading from BunnyCDN')
|
|
|
|
|
|
|
|
fd = HlsFD(self.ydl, self.params)
|
|
|
|
|
|
|
|
success = download_complete = False
|
|
|
|
ping_lock = threading.Lock()
|
2025-02-16 14:48:19 -06:00
|
|
|
|
|
|
|
timer = None
|
|
|
|
current_time = 0
|
2025-02-16 14:27:44 -06:00
|
|
|
|
|
|
|
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']
|
|
|
|
# Site sends ping every 4 seconds, but this throttles the download. Pinging every 2 seconds seems to work.
|
|
|
|
ping_interval = 2
|
|
|
|
|
|
|
|
def send_ping():
|
2025-02-16 14:48:19 -06:00
|
|
|
nonlocal timer, current_time
|
|
|
|
time = current_time + round(random.random(), 6)
|
2025-02-16 14:27:44 -06:00
|
|
|
# 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}',
|
2025-02-17 10:26:57 -06:00
|
|
|
headers=headers)
|
2025-02-16 14:27:44 -06:00
|
|
|
|
|
|
|
try:
|
|
|
|
self.ydl.urlopen(request).read()
|
2025-02-17 10:33:26 -06:00
|
|
|
except network_exceptions as e:
|
|
|
|
self.to_screen(f'[{self.FD_NAME}] Ping failed: {e}')
|
2025-02-16 14:27:44 -06:00
|
|
|
|
|
|
|
with ping_lock:
|
|
|
|
if not download_complete:
|
2025-02-16 14:48:19 -06:00
|
|
|
current_time += ping_interval
|
|
|
|
timer = threading.Timer(ping_interval, send_ping)
|
|
|
|
timer.start()
|
2025-02-16 14:27:44 -06:00
|
|
|
|
|
|
|
# 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:
|
2025-02-16 14:48:19 -06:00
|
|
|
if timer:
|
|
|
|
timer.cancel()
|
2025-02-16 14:27:44 -06:00
|
|
|
download_complete = True
|
|
|
|
|
|
|
|
return success
|