示例#1
0
def choice_3():
    print("Executing choice 3...")
    logger.info("Executing choice 3...")
    url = input("Enter the url: ")
    logger.info(url)

    try:
        yt = YouTube(url)
        yt.check_availability()
        selected = yt.streams.filter(only_audio=True).first()
        logger.info(selected)
        file = pathlib.Path(path + selected.default_filename)

        if file.exists():
            print(f"{selected.default_filename} is already downloaded!")
            logger.info(f"{selected.default_filename} is already downloaded!")
        else:
            yt.streams.filter(only_audio=True).first().download(
                output_path=path)
            print(f"{selected.default_filename} downloaded!")
            logger.info(f"{selected.default_filename} downloaded!")

    except RegexMatchError as e:
        logger.error(e)
    except MembersOnly as e:
        logger.error(e)
    except RecordingUnavailable as e:
        logger.error(e)
    except VideoPrivate as e:
        logger.error(e)
    except VideoRegionBlocked as e:
        logger.error(e)
    except VideoUnavailable as e:
        logger.error(e)
示例#2
0
def youtube_downloader():
    if request.method == "GET":
        return render_template("index.html")
    else:

        if not request.form["URL"]:
            return redirect("/")
        else:
            URL = request.form["URL"]
            try:
                video = YouTube(URL)
                video.check_availability()
            except:
                return render_template("fail.html")
            if request.form.get("submit_audio"):
                return render_template("download_audio.html", URL=URL)
            else:
                resolutions = {}
                for stream in video.streams.filter(progressive=True):
                    resolutions[stream.resolution] = stream.resolution

                return render_template("download.html",
                                       resolutions=resolutions,
                                       URL=URL)
示例#3
0
class YouTubeHelper:
    def __init__(self, video_link):
        """
        initialize helper object and check video availability

        :param video_link: link to the YouTube video
        :type video_link: str
        """
        self.yt = YouTube(video_link)
        self.index = 0
        self.yt.check_availability()  # throw error if not available

    def auto_download(self, myfolder=None):
        """
        download highest quality video available in mp4 format

        :param myfolder: directory of downloaded video
        :type myfolder: str or path-like or None
        :return: None
        """
        resolutions = self.get_all_resolution()
        highest_resolution = None
        fps = None
        # find highest resolution and highest fps if possible
        for res in resolutions:
            i = res.find('p')
            number = res[:i]
            frame_per_second = res[i + 1:]
            if highest_resolution and number < highest_resolution:
                break
            if not highest_resolution:
                highest_resolution = number
            if not fps and frame_per_second:
                fps = int(frame_per_second)
            elif frame_per_second and int(frame_per_second) > fps:
                fps = int(frame_per_second)
        highest_resolution = str(highest_resolution) + 'p'
        conventional = highest_resolution + str(
            fps) if fps else highest_resolution
        print(
            'video with resolution {} will be downloaded'.format(conventional))
        self.get_video(highest_resolution, myfolder=myfolder, fps=fps)

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

    def get_audio(self, myfolder=None, quality=None, audio_format=None):
        """
        download audio in different format

        :param myfolder: directory for downloading audio
        :type myfolder: str or path-like or None
        :param quality: bit rate
        :type quality: int or None
        :param audio_format: audio format e.g.mp3,w4a
        :type: str
        :return: None
        """
        filename = safe_filename(self.yt.title)
        if quality is None:
            target = self.yt.streams.filter(
                only_audio=True).order_by('abr').last()
        elif not isinstance(quality, int):
            raise TypeError("quality should be int")
        else:
            abr = str(quality) + 'kbps'
            search_result = self.yt.streams.filter(only_audio=True, abr=abr)
            if search_result:
                target = search_result.last()
            else:
                raise ValueError(
                    "there is no audio with bit rate {}".format(abr))
        print("audio with {} is going to be downloaded".format(target.abr))
        print("[Downloading...]")
        audio_path = target.download(output_path=myfolder, filename=filename)
        print('[Download success]')
        if audio_format:
            audio_format = audio_format if audio_format[
                0] == '.' else '.' + audio_format
            path, ext = os.path.splitext(audio_path)
            if ext != audio_format:
                if not FFMPEG_AVAILABLE:
                    raise FfmpegNotAvailableError(
                        'ffmpeg not found. Cannot perform downloading.'
                        'Make sure ffmpeg is installed and added in PATH')
                output_path = os.path.join(
                    myfolder, filename +
                    audio_format) if myfolder else filename + audio_format
                subprocess.run(['ffmpeg', '-i', audio_path, output_path])
                os.remove(audio_path)

    def get_thumbnail(self, myfolder=None):
        """
        download video thumbnail and return the path to downloaded thumbnail

        :param myfolder: directory for downloading thumbnail
        :type myfolder: str or path-like or None
        :return: path to thumbnail
        :rtype: str
        """
        src_link = self.yt.thumbnail_url
        filename = os.path.basename(urllib.parse.urlparse(src_link).path)
        full_path = os.path.normpath(os.path.join(
            myfolder, filename)) if myfolder is not None else filename
        urllib.request.urlretrieve(src_link, full_path)
        return full_path

    def get_all_resolution(self):
        """
        print all available resolution

        :return: list of strings containing available resolution
        :rtype: list[str]
        """
        resolutions = []
        for stream in self.yt.streams.filter(
                only_video=True).order_by('resolution').desc():
            res = stream.resolution
            fps = stream.fps
            if fps > 30:
                res += str(fps)
            if res in resolutions:
                continue
            else:
                resolutions.append(res)
        return resolutions

    def get_all_audio_quality(self):
        """
        print all available bit rate

        :return: list of string containing available bit rate in terms of kbps
        :rtype: list[str]
        """
        audios = []
        for stream in self.yt.streams.filter(
                only_audio=True).order_by('abr').desc():
            bytes_per_second = stream.abr
            if bytes_per_second not in audios:
                audios.append(bytes_per_second)
        return audios

    def get_info(self):
        """
        print video info: title, publish date, description, duration,
        available resolution and audio bit rate for download

        :return: None
        """
        print("title: ", self.yt.title)
        print("publish date: ", self.yt.publish_date)
        print("description:")
        print(self.yt.description)
        print("length: ", readable_time(self.yt.length))
        print("available resolution for download: ", self.get_all_resolution())
        print("available audio quality for download: ",
              self.get_all_audio_quality())

    def get_video_length(self):
        """
        video duration in human readable form

        :return: video duration
        :rtype str
        """
        return readable_time(self.yt.length)

    def get_title(self):
        """
        get video title

        :return: title
        :rtype: str
        """
        return self.yt.title
示例#4
0
                    '--path',
                    metavar='{File path}',
                    type=str,
                    default='temp/',
                    help='The path of the target folder of downloads.')
parser.add_argument('URL',
                    metavar='{URL}',
                    type=str,
                    help='The target video URL.')

args = parser.parse_args()
print(f'get URL: {args.URL}')
print(f'get path: {args.path}')
try:
    yt = YouTube(url=args.URL)
    yt.check_availability()
except Exception as e:
    print(e)
    print("The input URL is wrong or unavailable :C. Program exits...")
    sys.exit()

if args.audio:
    streams = yt.streams.filter(only_audio=True)
elif args.video:
    streams = yt.streams.filter(only_video=True)
else:
    streams = yt.streams

str_streams = '\n'.join(list(map(str, streams)))
print(f"""
=======================================Download informations=======================================
示例#5
0
def test_video_unavailable(get):
    get.return_value = ""
    youtube = YouTube("https://www.youtube.com/watch?v=9bZkp7q19f0")
    with pytest.raises(RegexMatchError):
        youtube.check_availability()