Advertisement
Guest User

Untitled

a guest
Dec 5th, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.37 KB | None | 0 0
  1. import argparse
  2. import requests
  3. import random
  4. import time
  5.  
  6.  
  7. class VideoDownloader:
  8. MAX_DOWNLOAD_ATTEMPS = 3
  9.  
  10. def __init__(self, playlist_url, output_file_path, memento=False, shuffle=False):
  11. self._base_url, self._playlist_path = self._split_url(playlist_url)
  12. self._output_file_path = output_file_path
  13. self._memento = memento
  14. self._shuffle = shuffle
  15.  
  16. @staticmethod
  17. def _join_url(*parts):
  18. return "/".join(parts)
  19.  
  20. @classmethod
  21. def _split_url(cls, url):
  22. parts = url.split("/")
  23. return cls._join_url(*parts[:-1]), parts[-1]
  24.  
  25. @staticmethod
  26. def _parse_chunk_file(chunk_file):
  27. return [line for line in chunk_file.splitlines() if ".ts" in line]
  28.  
  29. @staticmethod
  30. def _save_chunk(chunk_data, file_obj):
  31. file_obj.write(chunk_data)
  32. file_obj.flush()
  33.  
  34. @classmethod
  35. def _download_file(cls, url):
  36. i = 1
  37. while i < cls.MAX_DOWNLOAD_ATTEMPS:
  38. try:
  39. return requests.get(url).content
  40. except Exception as ex:
  41. print(f"Error while getting the url: {url} in attempt #{(i + 1)}")
  42. if i == cls.MAX_DOWNLOAD_ATTEMPS:
  43. raise ex
  44. i += 1
  45. time.sleep(1)
  46.  
  47. raise ValueError("")
  48. def _get_chunk_file(self):
  49. playlist_url = self._join_url(self._base_url, self._playlist_path)
  50. meta_data_file = self._download_file(playlist_url).decode("utf-8")
  51.  
  52. chunk_file_path = meta_data_file.splitlines()[-1]
  53. chunk_file_url = self._join_url(self._base_url, chunk_file_path)
  54. chunk_file = requests.get(chunk_file_url).content.decode("utf-8")
  55. return chunk_file
  56.  
  57. def _download_chunks(self, chunk_file_names, file_obj):
  58. chunks_number = len(chunk_file_names)
  59. print(f"Downloading {chunks_number} chunks...")
  60.  
  61. for i, chunk_file in enumerate(chunk_file_names):
  62. print(f"Downloading chunk {i}/{chunks_number} ({(i/chunks_number)*100:.3f}%)\t({chunk_file}) chunks...")
  63. chunk_url = self._join_url(self._base_url, chunk_file)
  64. chunk_data = self._download_file(chunk_url)
  65. self._save_chunk(chunk_data, file_obj)
  66. print("Done.")
  67.  
  68. def download(self):
  69. with open(self._output_file_path, "wb") as handle:
  70. chunk_file = self._get_chunk_file()
  71. chunk_file_names = self._parse_chunk_file(chunk_file)
  72.  
  73. if self._memento:
  74. chunk_file_names = chunk_file_names[::-1]
  75. elif self._shuffle:
  76. random.shuffle(chunk_file_names)
  77. self._download_chunks(chunk_file_names, handle)
  78.  
  79.  
  80. def parse_args():
  81. parser = argparse.ArgumentParser(description="TAU video server downloader")
  82. parser.add_argument("--url", help="Playlist file URL", required=True)
  83. parser.add_argument("--output", help="Output file path", required=True)
  84.  
  85. g = parser.add_mutually_exclusive_group()
  86. g.add_argument("--memento", help="Reverse the chunks order", action="store_true")
  87. g.add_argument("--shuffle", help="Just for fun", action="store_true")
  88. return parser.parse_args()
  89.  
  90.  
  91. def main():
  92. args = parse_args()
  93. video = VideoDownloader(args.url, args.output, args.memento, args.shuffle)
  94. video.download()
  95.  
  96.  
  97. if __name__ == "__main__":
  98. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement