bunnycdn.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import hashlib
  2. import random
  3. import threading
  4. from .common import FileDownloader
  5. from . import HlsFD
  6. from ..networking import Request
  7. from ..networking.exceptions import network_exceptions
  8. class BunnyCdnFD(FileDownloader):
  9. """
  10. Downloads from BunnyCDN with required pings
  11. Note, this is not a part of public API, and will be removed without notice.
  12. DO NOT USE
  13. """
  14. def real_download(self, filename, info_dict):
  15. self.to_screen(f'[{self.FD_NAME}] Downloading from BunnyCDN')
  16. fd = HlsFD(self.ydl, self.params)
  17. stop_event = threading.Event()
  18. ping_thread = threading.Thread(target=self.ping_thread, args=(stop_event,), kwargs=info_dict['_bunnycdn_ping_data'])
  19. ping_thread.start()
  20. try:
  21. return fd.real_download(filename, info_dict)
  22. finally:
  23. stop_event.set()
  24. def ping_thread(self, stop_event, url, headers, secret, context_id):
  25. # Site sends ping every 4 seconds, but this throttles the download. Pinging every 2 seconds seems to work.
  26. ping_interval = 2
  27. # Hard coded resolution as it doesn't seem to matter
  28. res = 1080
  29. paused = 'false'
  30. current_time = 0
  31. while not stop_event.wait(ping_interval):
  32. current_time += ping_interval
  33. time = current_time + round(random.random(), 6)
  34. md5_hash = hashlib.md5(f'{secret}_{context_id}_{time}_{paused}_{res}'.encode()).hexdigest()
  35. ping_url = f'{url}?hash={md5_hash}&time={time}&paused={paused}&resolution={res}'
  36. try:
  37. self.ydl.urlopen(Request(ping_url, headers=headers)).read()
  38. except network_exceptions as e:
  39. self.to_screen(f'[{self.FD_NAME}] Ping failed: {e}')