Advertisement
Guest User

Untitled

a guest
Dec 10th, 2019
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.34 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.     def _get_chunk_file(self):
  48.         playlist_url = self._join_url(self._base_url, self._playlist_path)
  49.         meta_data_file = self._download_file(playlist_url).decode("utf-8")
  50.  
  51.         chunk_file_path = meta_data_file.splitlines()[-1]
  52.         chunk_file_url = self._join_url(self._base_url, chunk_file_path)
  53.         chunk_file = requests.get(chunk_file_url).content.decode("utf-8")
  54.         return chunk_file
  55.  
  56.     def _download_chunks(self, chunk_file_names, file_obj):
  57.         chunks_number = len(chunk_file_names)
  58.         print(f"Downloading {chunks_number} chunks...")
  59.  
  60.         for i, chunk_file in enumerate(chunk_file_names):
  61.             print(f"Downloading chunk {i}/{chunks_number} ({(i/chunks_number)*100:.3f}%)\t({chunk_file}) chunks...")
  62.             chunk_url = self._join_url(self._base_url, chunk_file)
  63.             chunk_data = self._download_file(chunk_url)
  64.             self._save_chunk(chunk_data, file_obj)
  65.         print("Done.")
  66.  
  67.     def download(self):
  68.         with open(self._output_file_path, "wb") as handle:
  69.             chunk_file = self._get_chunk_file()
  70.             chunk_file_names = self._parse_chunk_file(chunk_file)
  71.  
  72.             if self._memento:
  73.                 chunk_file_names = chunk_file_names[::-1]
  74.             elif self._shuffle:
  75.                 random.shuffle(chunk_file_names)
  76.             self._download_chunks(chunk_file_names, handle)
  77.  
  78.  
  79. def parse_args():
  80.     parser = argparse.ArgumentParser(description="TAU video server downloader")
  81.     parser.add_argument("--url", help="Playlist file URL", required=True)
  82.     parser.add_argument("--output", help="Output file path", required=True)
  83.  
  84.     g = parser.add_mutually_exclusive_group()
  85.     g.add_argument("--memento", help="Reverse the chunks order", action="store_true")
  86.     g.add_argument("--shuffle", help="Just for fun", action="store_true")
  87.     return parser.parse_args()
  88.  
  89.  
  90. def main():
  91.     args = parse_args()
  92.     video = VideoDownloader(args.url, args.output, args.memento, args.shuffle)
  93.     video.download()
  94.  
  95.  
  96. if __name__ == "__main__":
  97.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement