Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import argparse
- import requests
- import random
- import time
- class VideoDownloader:
- MAX_DOWNLOAD_ATTEMPS = 3
- def __init__(self, playlist_url, output_file_path, memento=False, shuffle=False):
- self._base_url, self._playlist_path = self._split_url(playlist_url)
- self._output_file_path = output_file_path
- self._memento = memento
- self._shuffle = shuffle
- @staticmethod
- def _join_url(*parts):
- return "/".join(parts)
- @classmethod
- def _split_url(cls, url):
- parts = url.split("/")
- return cls._join_url(*parts[:-1]), parts[-1]
- @staticmethod
- def _parse_chunk_file(chunk_file):
- return [line for line in chunk_file.splitlines() if ".ts" in line]
- @staticmethod
- def _save_chunk(chunk_data, file_obj):
- file_obj.write(chunk_data)
- file_obj.flush()
- @classmethod
- def _download_file(cls, url):
- i = 1
- while i < cls.MAX_DOWNLOAD_ATTEMPS:
- try:
- return requests.get(url).content
- except Exception as ex:
- print(f"Error while getting the url: {url} in attempt #{(i + 1)}")
- if i == cls.MAX_DOWNLOAD_ATTEMPS:
- raise ex
- i += 1
- time.sleep(1)
- def _get_chunk_file(self):
- playlist_url = self._join_url(self._base_url, self._playlist_path)
- meta_data_file = self._download_file(playlist_url).decode("utf-8")
- chunk_file_path = meta_data_file.splitlines()[-1]
- chunk_file_url = self._join_url(self._base_url, chunk_file_path)
- chunk_file = requests.get(chunk_file_url).content.decode("utf-8")
- return chunk_file
- def _download_chunks(self, chunk_file_names, file_obj):
- chunks_number = len(chunk_file_names)
- print(f"Downloading {chunks_number} chunks...")
- for i, chunk_file in enumerate(chunk_file_names):
- print(f"Downloading chunk {i}/{chunks_number} ({(i/chunks_number)*100:.3f}%)\t({chunk_file}) chunks...")
- chunk_url = self._join_url(self._base_url, chunk_file)
- chunk_data = self._download_file(chunk_url)
- self._save_chunk(chunk_data, file_obj)
- print("Done.")
- def download(self):
- with open(self._output_file_path, "wb") as handle:
- chunk_file = self._get_chunk_file()
- chunk_file_names = self._parse_chunk_file(chunk_file)
- if self._memento:
- chunk_file_names = chunk_file_names[::-1]
- elif self._shuffle:
- random.shuffle(chunk_file_names)
- self._download_chunks(chunk_file_names, handle)
- def parse_args():
- parser = argparse.ArgumentParser(description="TAU video server downloader")
- parser.add_argument("--url", help="Playlist file URL", required=True)
- parser.add_argument("--output", help="Output file path", required=True)
- g = parser.add_mutually_exclusive_group()
- g.add_argument("--memento", help="Reverse the chunks order", action="store_true")
- g.add_argument("--shuffle", help="Just for fun", action="store_true")
- return parser.parse_args()
- def main():
- args = parse_args()
- video = VideoDownloader(args.url, args.output, args.memento, args.shuffle)
- video.download()
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement