Example #1
0
def download_video(url, filename):
    global is_paused, is_cancelled
    download_button['state'] = 'disabled'
    pause_button['state'] = 'normal'
    cancel_button['state'] = 'normal'
    try:
        progress['text'] = 'Connecting ...'
        yt = YouTube(url)
        stream = yt.streams.first()
        filesize = stream.filesize
        with open(filename, 'wb') as f:
            is_paused = is_cancelled = False
            stream = request.stream(stream.url)
            downloaded = 0
            while True:
                if is_cancelled:
                    progress['text'] = 'Download cancelled'
                    break
                if is_paused:
                    continue
                chunk = next(stream, None)
                if chunk:
                    f.write(chunk)
                    downloaded += len(chunk)
                    progress['text'] = f'Downloaded {downloaded} / {filesize}'
                else:
                    # no more data
                    progress['text'] = 'Download completed'
                    break
        print('done')
    except Exception as e:
        print(e)
    download_button['state'] = 'normal'
    pause_button['state'] = 'disabled'
    cancel_button['state'] = 'disabled'
Example #2
0
    def download(
        self,
        output_path: Optional[str] = None,
        filename: Optional[str] = None,
        filename_prefix: Optional[str] = None,
        skip_existing: bool = True,
    ) -> 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
        :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("file %s already exists, skipping", file_path)
            self.on_complete(file_path)
            return file_path

        bytes_remaining = self.filesize
        logger.debug(
            "downloading (%s total bytes) file to %s",
            self.filesize,
            file_path,
        )

        with open(file_path, "wb") as fh:
            for chunk in request.stream(self.url):
                # 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
Example #3
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 #4
0
    def download(
        self,
        output_path: Optional[str] = None,
        filename: Optional[str] = None,
        filename_prefix: Optional[str] = None,
    ) -> 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

        :rtype: str

        """
        output_path = output_path or os.getcwd()
        if filename:
            safe = safe_filename(filename)
            filename = "{filename}.{s.subtype}".format(filename=safe, s=self)
        filename = filename or self.default_filename

        if filename_prefix:
            filename = "{prefix}{filename}".format(
                prefix=safe_filename(filename_prefix),
                filename=filename,
            )

        file_path = os.path.join(output_path, filename)
        bytes_remaining = self.filesize
        logger.debug(
            "downloading (%s total bytes) file to %s",
            self.filesize,
            file_path,
        )

        with open(file_path, "wb") as fh:
            for chunk in request.stream(self.url):
                # 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(fh)
        return file_path
Example #5
0
def test_streaming(mock_urlopen):
    fake_stream_binary = [
        iter(os.urandom(8 * 1024)),
        iter(os.urandom(8 * 1024)),
        iter(os.urandom(8 * 1024)),
        None,
    ]
    response = mock.Mock()
    response.read.side_effect = fake_stream_binary
    mock_urlopen.return_value = response
    response = request.stream("http://fakeassurl.gov")
    call_count = len(list(response))

    assert call_count == 3
Example #6
0
    def stream_to_buffer(self, buffer: BinaryIO) -> None:
        """Write the media stream to buffer

        :rtype: io.BytesIO buffer
        """
        bytes_remaining = self.filesize
        logger.info(
            "downloading (%s total bytes) file to buffer", self.filesize,
        )

        for chunk in request.stream(self.url):
            # reduce the (bytes) remainder by the length of the chunk.
            bytes_remaining -= len(chunk)
            # send to the on_progress callback.
            self.on_progress(chunk, buffer, bytes_remaining)
        self.on_complete(None)
Example #7
0
def test_streaming(mock_urlopen):
    # Given
    fake_stream_binary = [
        os.urandom(8 * 1024),
        os.urandom(8 * 1024),
        os.urandom(8 * 1024),
        None,
    ]
    mock_response = mock.Mock()
    mock_response.read.side_effect = fake_stream_binary
    mock_response.info.return_value = {"Content-Range": "bytes 200-1000/24576"}
    mock_urlopen.return_value = mock_response
    # When
    response = request.stream("http://fakeassurl.gov/streaming_test")
    # Then
    assert len(b''.join(response)) == 3 * 8 * 1024
    assert mock_response.read.call_count == 4
Example #8
0
def test_streaming(mock_urlopen):
    # Given
    fake_stream_binary = [
        os.urandom(8 * 1024),
        os.urandom(8 * 1024),
        os.urandom(8 * 1024),
        None,
    ]
    response = mock.Mock()
    response.read.side_effect = fake_stream_binary
    response.info.return_value = {"Content-Range": "bytes 200-1000/24576"}
    mock_urlopen.return_value = response
    # When
    response = request.stream("http://fakeassurl.gov")
    # Then
    call_count = len(list(response))
    assert call_count == 3
Example #9
0
def download_media(url, filename, audioOnly=False):
    if (url):
        global is_paused, is_cancelled
        download_button['state'] = 'disabled'
        download_audio_button['state'] = 'disabled'
        pause_button['state'] = 'normal'
        cancel_button['state'] = 'normal'
        var = optMval.get()
        try:
            progress['text'] = 'Connecting ...'
            yt = YouTube(url)
            if (audioOnly):
                stream = yt.streams.filter(subtype='mp4',
                                           only_audio=True).first()
                filename = filename + '/' + yt.title + '.mp3'
            else:
                stream = yt.streams[res_list_db[var]]
                filename = filename + '/' + yt.title + '.mp4'
            filesize = stream.filesize
            with open(filename, 'wb') as f:
                is_paused = is_cancelled = False
                stream = request.stream(stream.url)
                downloaded = 0
                while True:
                    if is_cancelled:
                        progress['text'] = 'Download cancelled'
                        break
                    if is_paused:
                        continue
                    chunk = next(stream, None)
                    if chunk:
                        f.write(chunk)
                        downloaded += len(chunk)
                        progress[
                            'text'] = f'Downloaded {downloaded} / {filesize}'
                    else:
                        # no more data
                        progress['text'] = 'Download completed'
                        break
            print('done')
        except Exception as e:
            print(e)
        download_button['state'] = 'normal'
        download_audio_button['state'] = 'normal'
        pause_button['state'] = 'disabled'
        cancel_button['state'] = 'disabled'
Example #10
0
def download_audio(url, filelocation):
    global is_paused, is_cancelled, filesize, downloaded
    download_audio_button['state'] = 'disabled'
    pause_button['state'] = 'normal'
    cancel_button['state'] = 'normal'
    try:
        progress['text'] = 'Connecting ...'
        yt = YouTube(url)
        stream = yt.streams.filter(only_audio=True).first()
        filesize = stream.filesize
        string = ''.join(
            [i for i in re.findall('[\w +/.]', yt.title) if i.isalpha()])
        filename = filelocation + '/' + string + '.mp3'
        with open(filename, 'wb') as f:
            is_paused = is_cancelled = False
            stream = request.stream(stream.url)
            downloaded = 0
            while True:
                pbar["maximum"] = filesize
                pbar["value"] = downloaded
                pbar.start()
                if is_cancelled:
                    progress['text'] = 'Download cancelled'
                    pbar.stop()
                    break
                if is_paused:
                    continue
                chunk = next(stream, None)
                if chunk:
                    f.write(chunk)
                    downloaded += len(chunk)
                    progress['text'] = f'Downloaded {downloaded} / {filesize}'
                else:
                    # no more data
                    progress['text'] = 'Audio Download completed!'
                    break
        print('done')
    except Exception as e:
        print(e)
    download_audio_button['state'] = 'normal'
    pause_button['state'] = 'disabled'
    cancel_button['state'] = 'disabled'
Example #11
0
 def download_as_temp(self, video):
     with tempfile.NamedTemporaryFile(delete=False) as f:
         for chunk in request.stream(video.url):
             f.write(chunk)
     return f.name
Example #12
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
Example #13
0
def test_timeout(mock_urlopen):
    exc = URLError(reason=socket.timeout('timed_out'))
    mock_urlopen.side_effect = exc
    generator = request.stream('http://fakeassurl.gov/timeout_test', timeout=1)
    with pytest.raises(MaxRetriesExceeded):
        next(generator)