Пример #1
0
def _ffmpeg_downloader(audio_stream: Stream, video_stream: Stream, target: str) -> None:
    """
    Given a YouTube Stream object, finds the correct audio stream, downloads them both
    giving them a unique name, them uses ffmpeg to create a new file with the audio
    and video from the previously downloaded files. Then deletes the original adaptive
    streams, leaving the combination.

    :param Stream audio_stream:
        A valid Stream object representing the audio to download
    :param Stream video_stream:
        A valid Stream object representing the video to download
    :param Path target:
        A valid Path object
    """
    video_unique_name = _unique_name(
        safe_filename(video_stream.title), video_stream.subtype, "video", target=target
    )
    audio_unique_name = _unique_name(
        safe_filename(video_stream.title), audio_stream.subtype, "audio", target=target
    )
    _download(stream=video_stream, target=target, filename=video_unique_name)
    print("Loading audio...")
    _download(stream=audio_stream, target=target, filename=audio_unique_name)

    video_path = os.path.join(target, f"{video_unique_name}.{video_stream.subtype}")
    audio_path = os.path.join(target, f"{audio_unique_name}.{audio_stream.subtype}")
    final_path = os.path.join(
        target, f"{safe_filename(video_stream.title)}.{video_stream.subtype}"
    )

    subprocess.run(  # nosec
        ["ffmpeg", "-i", video_path, "-i", audio_path, "-codec", "copy", final_path,]
    )
    os.unlink(video_path)
    os.unlink(audio_path)
Пример #2
0
    def download(self,
                 output_path=None,
                 filename=None,
                 filename_prefix=None,
                 only_url=None):
        """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 seperate from filename so you can use the default
			filename but still add a prefix.
		:type filename_prefix: str or None

		:rtype: str

		"""

        if only_url:
            return self.url

        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
        fp = os.path.join(output_path, filename)
        bytes_remaining = self.filesize
        PLog(
            'streams: downloading (%s total bytes) file to %s',
            self.filesize,
            fp,
        )

        with open(fp, 'wb') as fh:
            for chunk in request.get(self.url, streaming=True):
                # 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 fp
Пример #3
0
    def Downloaderffmpeg(
        self, audio_stream: Stream, video_stream: Stream, target: str 
    )-> str:
        video_unique_name = fileUnique(
            helpers.safe_filename(video_stream.title),
            video_stream.subtype,
            "video",
            target=target,
        )

        audio_unique_name = fileUnique(
            helpers.safe_filename(video_stream.title),
            audio_stream.subtype,
            "audio",
            target=target,
        )

        clidownload(stream=video_stream, target=target, filename=video_unique_name)
        clidownload(stream=audio_stream, target=target, filename=audio_unique_name)

        video_path = os.path.join(
            target, f"{video_unique_name}.{video_stream.subtype}"
        )
        audio_path = os.path.join(
            target, f"{audio_unique_name}.{audio_stream.subtype}"
        )
        final_path = os.path.join(
            # target, f"{helpers.safe_filename(video_stream.title)}.{video_stream.subtype}"
            target, f"{helpers.safe_filename(video_stream.title)}.mp4"
        )

        try:
            subprocess.run(  
                [
                    "ffmpeg",
                    "-i",
                    video_path,
                    "-i",
                    audio_path,
                    "-codec",
                    "copy",
                    final_path,
                    "-loglevel",
                    "quiet"
                ]
            )
        except:
            print("Ada kesalahan saat menggabungkan video")
            sleep(0.5)
            print("Tapi tenang, file video dan audio masih ada")            
        finally:
            print(s("%s" % prGreen("Success")))
            print(s("File disimpan di %s" % prGreen(final_path)))

            os.unlink(video_path)
            os.unlink(audio_path)
            return final_path

        return None
Пример #4
0
def write_audio(audio,
                video,
                position,
                channel_name="",
                channel_id="",
                group=None,
                include_title=False,
                include_channel=False):
    """Write audio Stream object to a file. If an output folder is not specified, audio will be placed in a folder corresponding to the name of the video's author (i.e. channel).

    :param audio: The audio Stream to download
    :param position: Channel-wise position of the video in the url list
    :param channel_name: The name of the channel as given on its main page (default "")
    :param channel_id: The name of the channel as it appears in the channel's URL (default "")
    :param group: The folder to output the audio stream to (default None)
    :param include_title: Include video title in audio filename (default True)
    :param include_channel: Save file to channel subfolder (default False)
    """

    safe_title = helpers.safe_filename(video.title)
    safe_author = helpers.safe_filename(video.author)

    out_path = path.join("corpus", "raw_audio")
    if group is not None:
        out_path = path.join(out_path, group)

    punc_and_whitespace = "[\s\_\-\.\?\!,;:'\"\\\/]+"
    if (include_channel):
        if channel_name and channel_id:
            safe_channel_name = sub(punc_and_whitespace, "", channel_name)
            out_path = path.join(
                out_path, "{0}_{1}".format(safe_channel_name, channel_id))
        else:
            safe_author = sub(punc_and_whitespace, "", video.author)
            out_path = path.join(out_path, safe_author)

    if not path.exists(out_path):
        makedirs(out_path)

    try:
        if include_title:
            audio.download(filename=safe_title,
                           output_path=out_path,
                           filename_prefix="{0}_{1}_".format(
                               safe_author, position),
                           skip_existing=True)
        else:
            audio.download(filename=str(position),
                           output_path=out_path,
                           filename_prefix="{0}_".format(safe_author),
                           skip_existing=True)

    except:
        logging.critical(
            "Video {0}: Could not save audio stream for video {0} from channel {1} ({2})"
            .format(position, video.author, video.title))

    # Be polite
    sleep(1)
Пример #5
0
    def download(
        self,
        title: str,
        srt=True,
        output_path=None,
        filename_prefix=None,
    ) -> str:
        """Write the media stream to disk.

        :param title:
            Output filename (stem only) for writing media file.
            If one is not specified, the default filename is used.
        :type title: str
        :param srt:
            Set to True to download srt, false to download xml. Defaults to True.
        :type srt bool
        :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_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
        """
        if title.endswith(".srt") or title.endswith(".xml"):
            filename = ".".join(title.split(".")[:-1])
        else:
            filename = title

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

        filename = safe_filename(filename)

        filename += " ({})".format(self.code)

        if srt:
            filename += ".srt"
        else:
            filename += ".xml"

        file_path = os.path.join(target_directory(output_path), filename)

        with open(file_path, "w", encoding="utf-8") as file_handle:
            if srt:
                file_handle.write(self.generate_srt_captions())
            else:
                file_handle.write(self.xml_captions)

        return file_path
Пример #6
0
 def get_file_path(
     self,
     filename: Optional[str],
     output_path: Optional[str],
     filename_prefix=None,
 ) -> str:
     if filename:
         filename = "{}.{}".format(safe_filename(filename), self.subtype)
     else:
         filename = self.default_filename
     if filename_prefix:
         filename = "{}{}".format(safe_filename(filename_prefix), filename)
     return os.path.join(target_directory(output_path), filename)
Пример #7
0
	def on_DL_pressed(self):
		if self.can_dl:
			if self.HighestQual.isChecked() and not self.AudioOnly.isChecked():
				self.vid_stream = self.vid.streams.filter(custom_filter_functions=[lambda s: s.includes_video_track]).order_by('resolution').desc().first()
				if self.vid_stream.is_progressive:
					fullpath, _ = QFileDialog.getSaveFileName(self, "Save file", helpers.safe_filename(self.vid.title), "{} (*.{});;All files (*.*)".format(self.suffix_description(self.vid_stream.subtype), self.vid_stream.subtype))
					if not fullpath:
						return
					self.fullpath = pathlib.Path(fullpath)

					worker = Worker_1()
					self.threadpool.start(worker)

				else:
					self.adapt = True

					self.aud_stream = self.vid.streams.filter(only_audio=True, subtype=self.vid_stream.subtype).first()
					
					fullpath, _ = QFileDialog.getSaveFileName(self, "Save file", helpers.safe_filename(self.vid.title), "{} (*.{});;All files (*.*)".format(self.suffix_description(self.aud_stream.subtype), self.aud_stream.subtype))
					if not fullpath:
						return
					self.fullpath = pathlib.Path(fullpath)

					worker = Worker_2()
					self.threadpool.start(worker)

			elif self.HighestQual.isChecked() and self.AudioOnly.isChecked():
				self.aud_stream = self.vid.streams.filter(only_audio=True).order_by('abr').desc().first()

				fullpath, _ = QFileDialog.getSaveFileName(self, "Save file", helpers.safe_filename(self.vid.title), "{} (*.{});;All files (*.*)".format(self.suffix_description(self.aud_stream.subtype), self.aud_stream.subtype))
				if not fullpath:
					return
				self.fullpath = pathlib.Path(fullpath)

				worker = Worker_3()
				self.threadpool.start(worker)

			else:
				print(self.SelectStream.currentIndex)
				
				self.vid_stream = self.vid.streams.all()[self.SelectStream.currentIndex()]

				fullpath, _ = QFileDialog.getSaveFileName(self, "Save file", helpers.safe_filename(self.vid.title), "{} (*.{});;All files (*.*)".format(self.suffix_description(self.vid_stream.subtype), self.vid_stream.subtype))
				if not fullpath:
					return
				self.fullpath = pathlib.Path(fullpath)

				worker = Worker_1()
				self.threadpool.start(worker)
Пример #8
0
    def parallel_streaming(self, output_path=None, filename=None):
        """Write the media stream to buffer

        :rtype: io.BytesIO buffer
        """
        buffer = io.BytesIO()
        logger.debug(
            'downloading (%s total bytes) file to BytesIO buffer',
            self.filesize,
        )
        chunks = request.get_parallel(self.url, self.on_progress_parallel)

        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

        # file path
        fp = os.path.join(output_path, filename)
        with open(fp, 'wb') as fh:
            for k in sorted(chunks.keys()):
                fh.write(chunks[k])
            self.on_complete(fh)
        return fp
Пример #9
0
def update_one_json(prep_json, video_dir, audio_dir):
    prep_json["title_clean"] = safe_filename(prep_json["title"])
    prep_json["description_clean"] = clean_description(
        prep_json["description"])

    video_path = osp.join(video_dir,
                          f"{safe_filename(prep_json['title'])}.mp4")
    audio_path = osp.join(audio_dir,
                          f"{safe_filename(prep_json['title'])}.mp3")
    try:
        prep_json["theme"] = CHANNEL_TITLE_2_THEME[prep_json["channelTitle"]]
    except KeyError:
        try:
            prep_json["theme"] = QUERY_2_THEME[prep_json["query"]]
        except KeyError:
            print(
                f"Theme cannot be extracted from channel title {prep_json['channelTitle']} "
                f"or query {prep_json.get('query')}")

    for fpath, fpath_name in zip([video_path, audio_path],
                                 ["video_path", "audio_path"]):
        prep_json[fpath_name] = "/".join(list(fpath.split("/"))[-3:])
        prep_json[f"{fpath_name}_exists"] = osp.exists(fpath)
        if not osp.exists(fpath):
            print(f"Path {fpath} doesn't exist")

    return prep_json
def download_youtube_by_itag(yt, itag, target):
    target = target or os.getcwd()
    filepath = None
    try:
        url = yt.watch_url
        stream = yt.streams.get_by_itag(itag)
        title = stream.title
        resolution = stream.resolution
        video_codec = stream.video_codec
        abr = stream.abr
        audio_codec = stream.audio_codec
        fps = stream.fps
        bitrate = stream.bitrate
        filesize = stream.filesize
        filename = '{title}_{video}_{video_codec}_{audio}_{audio_codec}_{fps}_{bitrate}_{filesize}'.format(
            title=title,
            video=resolution,
            video_codec=video_codec,
            audio=abr,
            audio_codec=audio_codec,
            fps=fps,
            bitrate=bitrate,
            filesize=filesize)
        filename = to_unicode(safe_filename(filename))
        logger.debug("Filename = {filename}".format(filename=filename))

        yt.register_on_progress_callback(on_progress)
        filepath = yt.streams.get_by_itag(itag).download(output_path=target,
                                                         filename=filename)
    except:
        logger.error(
            "Unable to download YT, url = [{url}], itag = [{itag}]".format(
                url=url, itag=itag))

    return filepath
Пример #11
0
def get_folder_file_from(url):
    """
    create folder for a single video to download

    Returns:
        tuple : folder_name, file_valid_name
    """
    with YoutubeDL({
            # Download single video instead of a playlist if in doubt.
            "noplaylist": True,
            # to make fetching info faster because we are not interested in DASH info
            "youtube_include_dash_manifest": False,
            # don't print log messages in stdout
            "quiet": True
    }) as ydl:
        info_dict = ydl.extract_info(url, download=False)
        title = info_dict.get('title', UNKNOWN_NAME)

        # name on youtube without file extension
        title = safe_filename(title)
        # valid name to pass to IDM
        valid_name = check_and_file_ext(title)
        # name on youtube with file extension
        original_name = title + valid_name[-4:] + "\n"

        mkdir_and_chdir(title)
        with open(NANES_FILE, 'w') as file:
            file.write(original_name)

        return title, "00-" + valid_name
Пример #12
0
def download_song(yt, name):

    global current_download

    stream = yt.streams.filter(
        only_audio=True,
        file_extension='mp4').order_by('resolution').desc().first()
    if not stream is None:
        print("Downloading " + yt.watch_url)

        filename = helpers.safe_filename(name)

        stream.subtype = "m4a"
        file_target = '{filename}.{file_type}'.format(filename=filename,
                                                      file_type=stream.subtype)

        if os.path.isfile(file_target):
            print("File already detected")
            return

        current_download = file_target

        stream.download(filename=filename)
        print("Download completed")
        return True
    else:
        print("Unable to download " + yt.watch_url)
        return False
Пример #13
0
def playVideo(title, fpath):
    print("Playing", safe_filename(title))
    player = vlc.MediaPlayer(fpath)
    player.play()
    print("Playing")
    while True:
        pass
Пример #14
0
    def download(self, output_path=None, filename=None):
        """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

        :rtype: None

        """
        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

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

        tmpRangefp = None
        isTimeOut = False
        with open(fp, 'wb') as fh:
            while True:
                for chunk in request.get(self.url,
                                         streaming=True,
                                         conRangefp=tmpRangefp):

                    if not chunk:
                        print 'streams time out sleep 10s'
                        fh.flush()
                        time.sleep(10)
                        nfize = os.path.getsize(fp)
                        print fp, nfize
                        if nfize < self.filesize:
                            tmpRangefp = fp
                            isTimeOut = True
                            break
                    else:
                        tmpRangefp = None
                    # 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)
                if isTimeOut:
                    isTimeOut = False
                    print tmpRangefp
                else:
                    self.on_complete(fh)
                    break
Пример #15
0
def main():
    """Command line application to download youtube videos."""
    # noinspection PyTypeChecker
    parser = argparse.ArgumentParser(description=main.__doc__)
    args = _parse_args(parser)
    if args.verbose:
        log_filename = None
        if args.logfile:
            log_filename = args.logfile
        setup_logger(logging.DEBUG, log_filename=log_filename)
        logger.debug(f'Pytube version: {__version__}')

    if not args.url or "youtu" not in args.url:
        parser.print_help()
        sys.exit(1)

    if "/playlist" in args.url:
        print("Loading playlist...")
        playlist = Playlist(args.url)
        if not args.target:
            args.target = safe_filename(playlist.title)
        for youtube_video in playlist.videos:
            try:
                _perform_args_on_youtube(youtube_video, args)
            except exceptions.PytubeError as e:
                print(f"There was an error with video: {youtube_video}")
                print(e)
    else:
        print("Loading video...")
        youtube = YouTube(args.url)
        _perform_args_on_youtube(youtube, args)
Пример #16
0
def download_playlist(url):
    """
    download the whole playlist of the given url
    NOTE: youtubedl was used instead of pytube because it gives stable result
    and that's because pytube sometimes didn't return the correct name of the given link
    """
    ydl = YoutubeDL({
        # this line is VERY IMPORTANT because if there's private viedeos
        # or anything unavilable to download youtube-dl won't crash
        # and will continue to the next videos in the playlist
        "ignoreerrors": True,
        # to make fetching info faster because we are not interested in DASH info
        "youtube_include_dash_manifest": False,
        # don't print log messages in stdout
        "quiet": True
    })

    with ydl:
        playlist = ydl.extract_info(
            url,
            download=False  # We just want to extract the info
        )

    name_playlist = safe_filename(playlist.get('title'))
    mkdir_and_chdir(name_playlist)
    download_multiple_videos(playlist, name_playlist)
Пример #17
0
def main():
    """Command line application to download youtube videos."""
    # noinspection PyTypeChecker
    parser = argparse.ArgumentParser(description=main.__doc__)
    args = _parse_args(parser)
    if args.verbosity:
        log_level = min(args.verbosity, 4) * 10
        setup_logger(logging.FATAL - log_level)

    if not args.url or "youtu" not in args.url:
        parser.print_help()
        sys.exit(1)

    if "/playlist" in args.url:
        print("Loading playlist...")
        playlist = Playlist(args.url)
        if not args.target:
            args.target = safe_filename(playlist.title())
        for youtube_video in playlist.videos:
            try:
                _perform_args_on_youtube(youtube_video, args)
            except PytubeError as e:
                print(f"There was an error with video: {youtube_video}")
                print(e)
    else:
        print("Loading video...")
        youtube = YouTube(args.url)
        _perform_args_on_youtube(youtube, args)
Пример #18
0
def download_channel(url):
    """
    download the whole channel of the given url (the url must ends with "/videos" 
    so you need to select the videos tab in the channel page and then copy the url 
    NOTE: youtubedl was used instead of pytube because it gives stable result
    and that's because pytube sometimes didn't return the correct name of the given link
    """
    ydl = YoutubeDL({
        # this line is VERY IMPORTANT because if there's private viedeos
        # or anything unavilable to download youtube-dl won't crash
        # and will continue to the next videos in the playlist
        "ignoreerrors": True,
        # Download single video instead of a playlist if in doubt.
        "noplaylist": True,
        # to make fetching info faster because we are not interested in DASH info
        "youtube_include_dash_manifest": False,
        # don't print log messages in stdout
        "quiet": True
    })

    with ydl:
        channel = ydl.extract_info(
            url,
            download=False  # We just want to extract the info
        )

    # original output without split is "Uploads from CHANNEL_NAME" (quotes not included)
    # so we need to split and pick the last item
    name_channel = safe_filename(channel.get("title").split(' from ')[-1])
    # print(name_channel)
    # print("="*50)
    mkdir_and_chdir(name_channel)
    download_multiple_videos(channel, name_channel)
Пример #19
0
 def merge_and_output(self):
     print(
         "\n[+++++] Download completed, now it's time to merge the video and audio!\n"
     )
     aud_path = ('"' + str(self.fetched_path) + '\\' +
                 helpers.safe_filename(self.title) + ' - aud' + '.mp4"')
     vid_path = ('"' + str(self.fetched_path) + '\\' +
                 helpers.safe_filename(self.title) + '.mp4"')
     mrg_path = ('"' + str(self.fetched_path) + '\\' +
                 helpers.safe_filename(self.title) + ' -- output.mp4"')
     subprocess.run('ffmpeg -i {} -i {} -c:v copy -c:a aac {} -y'.format(
         vid_path, aud_path, mrg_path))  # -y: overwrite without asking
     if self.fetched_option == 'C':
         os.system("DEL {} {}".format(aud_path, vid_path))
     elif self.fetched_option == "AC":
         os.system("DEL {}".format(vid_path))
     print("\n***** Sorry for this mess, we almost finished ^_^ *****\n")
Пример #20
0
def is_downloaded(fname):
	fname= safe_filename(fname)
	for file in glob.glob('Files/Musics/*.*'):
		li= file.rindex('.')
		name= file[13:li]
		if(name==fname):
			return file
	return "NO"
Пример #21
0
    def destination_filepath(self, output_path=None, filename=None,
                             filename_prefix=None):
        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
        fp = os.path.join(output_path, filename)
        return fp
Пример #22
0
    def default_filename(self) -> str:
        """Generate filename based on the video title.

        :rtype: str
        :returns:
            An os file system compatible filename.
        """
        filename = safe_filename(self.title)
        return f"{filename}.{self.subtype}"
Пример #23
0
 def default_filename(self):
     """Generate filename based on the video title.
     :rtype: str
     :returns:
         An os file system compatible filename.
     """
     title = self.player_config_args['player_response']['videoDetails']['title']
     filename = safe_filename(title)
     return '{filename}.{s.subtype}'.format(filename=filename, s=self)
Пример #24
0
    def default_filename(self):
        """Generate filename based on the video title.

        :rtype: str
        :returns:
            An os file system compatible filename.
        """
        title = self.player_config_args['title']
        filename = safe_filename(title)
        return '{filename}.{s.subtype}'.format(filename=filename, s=self)
Пример #25
0
    def pl_merge(self):
        # merge vid, aud and get the output
        print(
            "\n[+++++] Download completed, now it's time to merge the video and audio!\n"
        )

        aud_path = ('"' + str(self.pl_path) + '\\' +
                    helpers.safe_filename(self.single_yt_title) + ' - aud' +
                    '.mp4"')
        vid_path = ('"' + str(self.pl_path) + '\\' +
                    helpers.safe_filename(self.single_yt_title) + '.mp4"')
        mrg_path = ('"' + str(self.pl_path) + '\\' +
                    helpers.safe_filename(self.single_yt_title) +
                    ' -- output.mp4"')
        subprocess.run('ffmpeg -i {} -i {} -c:v copy -c:a aac {} -y'.format(
            vid_path, aud_path, mrg_path))  # -y: overwrite without asking
        os.system("DEL {} {}".format(aud_path, vid_path))
        #os.system("DEL {}".format(vid_path))
        print("\n***** Sorry for this mess, we almost finished ^_^ *****\n")
Пример #26
0
def sanitize_filename(s: str) -> str:
    """
    Processes given string, making it safe to be a correct filename.

    :param s: input string
    :return: string safe for filesystem
    """
    s = safe_filename(s)
    s = s.replace(' ', '_')
    return s.encode('ascii', 'ignore').decode('ascii')
Пример #27
0
    def default_filename(self):
        """Generate filename based on the video title.

        :rtype: str
        :returns:
            An os file system compatible filename.
        """

        filename = safe_filename(self.title)
        return '{filename}.{s.subtype}'.format(filename=filename, s=self)
Пример #28
0
def go_pytube():
    try:
        go_yt = yt(yt_url)
        name = safe_filename(go_yt.title)
        print(u'名稱:', name)
        return go_yt, name
    except reME:
        print(u'不正常的網址...')
        e = input(u'按下 Enter按鍵 離開')
        exit()
Пример #29
0
    def get_video(self, resolution, myfolder=None, fps=None):
        """
        download video in mp4 format

        :param myfolder: path to folder for downloaded video and audio
        :type myfolder: path-like or str or None
        :param resolution: resolution ends with 'p'
        :type resolution: str
        :param fps: frame per second
        :type fps: int
        :return: None
        """
        self.index += 1
        title = self.yt.title
        idx = self.index
        valid_filename = safe_filename(title) + '.mp4'
        file_path = os.path.join(
            myfolder, valid_filename) if myfolder else valid_filename
        progressive_video = self.yt.streams.filter(progressive=True,
                                                   resolution=resolution,
                                                   fps=fps)

        # download progressive video if possible
        if progressive_video:
            print("[Downloading progressive video...]")
            progressive_video.last().download(output_path=myfolder,
                                              filename=valid_filename)
            return
        if not FFMPEG_AVAILABLE:
            raise FfmpegNotAvailableError(
                'ffmpeg not found. Cannot perform downloading.'
                'Make sure ffmpeg is installed and added in PATH')

        # search for video with specific resolution and fps
        video_search_result = self.yt.streams.filter(only_video=True,
                                                     resolution=resolution,
                                                     fps=fps)
        if video_search_result:
            print("[Downloading...]")
            video_path = video_search_result.last().download(
                output_path=myfolder, filename=f'video{idx}')
            audio_path = self.yt.streams.filter(
                only_audio=True).order_by('abr').last().download(
                    output_path=myfolder, filename=f'audio{idx}')
            subprocess.run([
                'ffmpeg', '-i', video_path, '-i', audio_path, '-acodec', 'aac',
                '-vsync', 'vfr', '-preset', 'veryfast', file_path
            ])
            os.remove(video_path)
            os.remove(audio_path)
        else:
            quality = resolution + str(fps) if fps else resolution
            raise ValueError(
                "there is no video with quality {}".format(quality))
Пример #30
0
def vid_to_aud(var):
    startdl(var)
    var.streams.filter(
        only_audio=True,
        subtype='webm').order_by('bitrate').last().download(dlpath)
    filepath = os.path.join(dlpath, safe_filename(var.title))
    webmaudio = ffmpeg.input(filepath + '.webm')
    mp3audio = filepath + '.mp3'
    ffmpeg.output(webmaudio, mp3audio).run()
    os.remove(filepath + '.webm')
    finishdl(var)
Пример #31
0
def download_youtube_video(url=None,
                           itag=None,
                           audio_only=False,
                           output_path=None,
                           filename=None,
                           filename_prefix=None,
                           proxies=None,
                           progress_callback=None,
                           video_and_stream=None):
    """
    Download a YouTube Video.
    :param url: Full URL to YouTube Video or YouTube Video ID
    :type url: str
    :param itag: YouTube Stream ITAG to Download
    :type itag: int
    :param audio_only: Download only the audio for the video. Takes longer than video.
    :type audio_only: bool
    :param output_path: Path to folder to output file.
    :type output_path: str
    :param filename: Filename override. Does not override extension.
    :type filename: str
    :param filename_prefix: Currently Does Not Work on pytube
    :type filename_prefix: str
    :param proxies: Dictionary containing protocol (key) and address (value) for the proxies
    :type proxies: dict
    :return: Filename of downloaded video/audio
    :rtype: str
    """
    if url is None and video_and_stream is None:
        raise ValueError(
            'You must provide either a url or video/stream object tuple')
    if output_path:
        makedirs(output_path, exist_ok=True)
    if video_and_stream is None:
        if 'http' not in url:
            url = 'https://www.youtube.com/watch?v=%s' % url
        video = YouTube(url, proxies=proxies)
        if itag:
            itag = int(itag)
            stream = video.streams.get_by_itag(itag)
        else:
            stream = video.streams.filter(only_audio=audio_only).first()
    else:
        video, stream = video_and_stream
    if progress_callback:
        video.register_on_progress_callback(progress_callback)
    print('Download Started: %s' % video.title)
    if filename:
        filename = safe_filename(filename)
    stream.download(output_path=output_path, filename=filename)
    file_type = '.' + stream.mime_type.split('/')[1]
    filename = stream.default_filename if filename is None else filename + file_type
    print('Download Complete! Saved to file: %s' % filename)
    return filename
Пример #32
0
    def download(self, output_path=None, filename=None):
        """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

        :rtype: None

        """
        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

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

        with open(fp, 'wb') as fh:
            for chunk in request.get(self.url, streaming=True):
                # 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)
Пример #33
0
def test_safe_filename():
    """Unsafe characters get stripped from generated filename"""
    assert helpers.safe_filename('abc1245$$') == 'abc1245'
    assert helpers.safe_filename('abc##') == 'abc'