Example #1
0
 def __call__(self, *args, **kwargs):
     try:
         for chunk in request.stream(self.url):
             yield chunk
     except HTTPError as e:
         if e.code != 404:
             raise
         # Some adaptive streams need to be requested with sequence numbers
         for chunk in request.seq_stream(self.url):
             yield chunk
Example #2
0
    def download(self,
                 output_path: Optional[str] = None,
                 filename: Optional[str] = None,
                 filename_prefix: Optional[str] = None,
                 skip_existing: bool = True,
                 timeout: Optional[int] = None,
                 max_retries: Optional[int] = 0) -> str:
        """Write the media stream to disk.

        :param output_path:
            (optional) Output path for writing media file. If one is not
            specified, defaults to the current working directory.
        :type output_path: str or None
        :param filename:
            (optional) Output filename (stem only) for writing media file.
            If one is not specified, the default filename is used.
        :type filename: str or None
        :param filename_prefix:
            (optional) A string that will be prepended to the filename.
            For example a number in a playlist or the name of a series.
            If one is not specified, nothing will be prepended
            This is separate from filename so you can use the default
            filename but still add a prefix.
        :type filename_prefix: str or None
        :param skip_existing:
            (optional) Skip existing files, defaults to True
        :type skip_existing: bool
        :param timeout:
            (optional) Request timeout length in seconds. Uses system default.
        :type timeout: int
        :param max_retries:
            (optional) Number of retries to attempt after socket timeout. Defaults to 0.
        :type max_retries: int
        :returns:
            Path to the saved video
        :rtype: str

        """
        file_path = self.get_file_path(
            filename=filename,
            output_path=output_path,
            filename_prefix=filename_prefix,
        )

        if skip_existing and self.exists_at_path(file_path):
            logger.debug(f'file {file_path} already exists, skipping')
            self.on_complete(file_path)
            return file_path

        bytes_remaining = self.filesize
        logger.debug(
            f'downloading ({self.filesize} total bytes) file to {file_path}')

        with open(file_path, "wb") as fh:
            try:
                for chunk in request.stream(self.url,
                                            timeout=timeout,
                                            max_retries=max_retries):
                    # reduce the (bytes) remainder by the length of the chunk.
                    bytes_remaining -= len(chunk)
                    # send to the on_progress callback.
                    self.on_progress(chunk, fh, bytes_remaining)
            except HTTPError as e:
                if e.code != 404:
                    raise
                # Some adaptive streams need to be requested with sequence numbers
                for chunk in request.seq_stream(self.url,
                                                timeout=timeout,
                                                max_retries=max_retries):
                    # reduce the (bytes) remainder by the length of the chunk.
                    bytes_remaining -= len(chunk)
                    # send to the on_progress callback.
                    self.on_progress(chunk, fh, bytes_remaining)
        self.on_complete(file_path)
        return file_path