Example #1
0
    def check_available(self) -> bool:
        # directly use the search extractors entry function so we can process each result
        # as soon as it's available instead of waiting for all of them
        extractor = yt_dlp.extractor.youtube.YoutubeSearchIE()
        extractor._downloader = yt_dlp.YoutubeDL(self.ydl_opts)
        extractor.initialize()
        for entry in extractor._search_results(self.query):
            if song_utils.is_forbidden(entry["title"]):
                continue
            try:
                with yt_dlp.YoutubeDL(self.ydl_opts) as ydl:
                    self.info_dict = ydl.extract_info(entry["id"],
                                                      download=False)
                break
            except (yt_dlp.utils.ExtractorError,
                    yt_dlp.utils.DownloadError) as error:
                logging.warning("error during availability check for %s:",
                                entry["id"])
                logging.warning(error)
        else:
            self.error = "No songs found"
            return False

        self.id = self.info_dict["id"]

        return self.check_not_too_large(self.info_dict["filesize"])
Example #2
0
    def download_video(self, queue: YoutubeQueue):
        # Download audio part
        default_audio_name = "audio"
        audio_file = queue.save_location + "\\" + default_audio_name
        output_file_path = audio_file + '.%(ext)s'
        ydl_opts = self.build_audio_fragment_download_options(output_file_path)
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            ydl.download([queue.link])
            result = ydl.extract_info("{}".format(queue.link))
            queue.audio_dl_stats = copy.deepcopy(self.download_stats)

        # Download video part (has no sound)
        default_video_name = "video"
        video_file = queue.save_location + "\\" + default_video_name
        output_file_path = video_file + '.%(ext)s'
        ydl_opts = self.build_video_fragment_download_options(output_file_path)
        with youtube_dl.YoutubeDL(ydl_opts) as ydl:
            ydl.download([queue.link])
            result = ydl.extract_info("{}".format(queue.link))
            queue.video_dl_stats = copy.deepcopy(self.download_stats)

        # Replace tags from file_name by its values from queue.video_dl_stats
        queue.replace_file_name_tags()

        # Merge audio and video parts to single file
        audio_file = default_audio_name + "." + constants.M4A
        video_file_extension = File.get_file_name_with_extension(queue.save_location, default_video_name).split(".")[-1]
        video_file = default_video_name + "." + video_file_extension

        merged_file = queue.file_name + "." + queue.save_format
        Ffmpeg.merge_audio_and_video(queue.save_location, audio_file, video_file, merged_file)
    async def process_playlist(self, playlist_type, url):

        if playlist_type == linkutils.Playlist_Types.YouTube_Playlist:

            if ("playlist?list=" in url):
                listid = url.split('=')[1]
            else:
                video = url.split('&')[0]
                await self.process_song(video)
                return

            options = {
                'format': 'bestaudio/best',
                'extract_flat': True,
                "cookiefile": config.COOKIE_PATH
            }

            with yt_dlp.YoutubeDL(options) as ydl:
                r = ydl.extract_info(url, download=False)

                for entry in r['entries']:

                    link = "https://www.youtube.com/watch?v={}".format(
                        entry['id'])

                    song = Song(linkutils.Origins.Playlist,
                                linkutils.Sites.YouTube,
                                webpage_url=link)

                    self.playlist.add(song)

        if playlist_type == linkutils.Playlist_Types.Spotify_Playlist:
            links = await linkutils.get_spotify_playlist(url)
            for link in links:
                song = Song(linkutils.Origins.Playlist,
                            linkutils.Sites.Spotify,
                            webpage_url=link)
                self.playlist.add(song)

        if playlist_type == linkutils.Playlist_Types.BandCamp_Playlist:
            options = {'format': 'bestaudio/best', 'extract_flat': True}
            with yt_dlp.YoutubeDL(options) as ydl:
                r = ydl.extract_info(url, download=False)

                for entry in r['entries']:

                    link = entry.get('url')

                    song = Song(linkutils.Origins.Playlist,
                                linkutils.Sites.Bandcamp,
                                webpage_url=link)

                    self.playlist.add(song)

        for song in list(self.playlist.playque)[:config.MAX_SONG_PRELOAD]:
            asyncio.ensure_future(self.preload(song))
Example #4
0
def single_songs(urls: List[str], artist, album, info_opts, download_opts,
                 track_numbers, strip_patterns, **kwargs) -> None:
    if len(urls) == 1:
        print(
            "\nthis video is not a playlist, and it has no chapters, are you sure you want to proceed?"
        )
        text = capture_input("(y)es, (n)o: ", "y", "n")
        if text == "n":
            try:
                os.rmdir(os.getcwd())
            except Exception:
                pass
            print("\nexiting...")
            sys.exit(0)

    status = []
    tracks = parse_track_numbers(track_numbers)
    if tracks and len(urls) != len(tracks):
        sys.exit("you passed {} track(s) and {} url(s)".format(
            len(tracks), len(urls)))

    for i, url in enumerate(urls):
        idx = tracks[i] if tracks else i + 1

        with youtube_dl.YoutubeDL(info_opts) as ydl:
            info = ydl.extract_info(url, download=False)
        if not info:
            status.append((idx, False, "", ""))
            continue

        if not glob.glob("*{}.*".format(info["id"])):  # don't redownload file
            with youtube_dl.YoutubeDL(download_opts) as ydl:
                ydl.download([url])
        else:
            print(
                "\nfound matching file for {}... if you wish to download and process file again, "
                "delete this file, or delete album directory\n".format(
                    info["title"]))

        title = strip(info["title"], strip_patterns) or info["title"]
        for file in glob.glob("*{}.*".format(info["id"])):
            _, extension = os.path.splitext(file)
            set_audio_id3(file,
                          title=title,
                          artist=artist,
                          album=album,
                          tracknumber="{}/{}".format(idx, len(urls)))
            try:
                os.rename(file, "{}-{}{}".format(title, info["id"], extension))
            except Exception:
                pass
        status.append((idx, True, info["id"], info["title"]))
    print("\n{}\n".format("\n".join(format_status_with_url(s)
                                    for s in status)))
Example #5
0
def download(item):
    mp3_postprocessor = {
        'key': 'FFmpegExtractAudio',
        'preferredcodec': 'mp3',
        'preferredquality': '0',
    }

    opus_postprocessor = {
        'key': 'FFmpegExtractAudio',
        'preferredcodec': item.ext,
    }

    metadata_postprocessor = {'key': 'FFmpegMetadata', 'add_metadata': True}

    ydl_opts = {
        'format': 'bestaudio/best',
        'paths': {
            'home': '/downloads/'
        },
        'outtmpl':
        '%(artist)s-%(album)s-%(track)s-[%(id)s]-(%(title)s).%(ext)s'
    }
    if item.ext == 'mp3':
        ydl_opts['postprocessors'] = [
            mp3_postprocessor, metadata_postprocessor
        ]
    if item.ext in ['opus', 'ogg', 'webm']:
        ydl_opts['postprocessors'] = [
            opus_postprocessor, metadata_postprocessor
        ]

    if item.url is not None:
        print("Starting download of " + item.url)

        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            ydl.add_post_processor(AddID3ArtworkPP())
            ydl.download([item.url])

        print("Finished downloading " + item.url)
    else:
        print(f'Starting download {item.artist}-{item.title}')

        if item.artist is not None and item.album is not None:
            ydl_opts['paths'][
                'home'] = f'/downloads/{item.artist}/{item.album}/'

        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            ydl.add_post_processor(AddID3ArtworkPP())
            ydl.extract_info(
                f'ytsearch:{item.artist} {item.title} Lyric Video',
                extra_info={'artwork': item.artwork})

        print(f'Finished downloading {item.artist}-{item.title}')
Example #6
0
    def __init__(self, download_folder=None):
        self.thread_pool = ThreadPoolExecutor(max_workers=2)
        self.download_folder = download_folder

        if download_folder:
            # print("setting template to " + os.path.join(download_folder, otmpl))
            otmpl = ytdl_format_options["outtmpl"]
            ytdl_format_options["outtmpl"] = os.path.join(download_folder, otmpl)

        self.unsafe_ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
        self.safe_ytdl = youtube_dl.YoutubeDL(
            {**ytdl_format_options, "ignoreerrors": True}
        )
    async def play_song(self, song):
        """Plays a song object"""

        if self.playlist.loop != True: #let timer run thouh if looping
            self.timer.cancel()
            self.timer = utils.Timer(self.timeout_handler)

        if song.info.title == None:
            if song.host == linkutils.Sites.Spotify:
                conversion = self.search_youtube(await linkutils.convert_spotify(song.info.webpage_url))
                song.info.webpage_url = conversion

            try:
                downloader = yt_dlp.YoutubeDL(
                    {'format': 'bestaudio', 'title': True, "cookiefile": config.COOKIE_PATH})
                r = downloader.extract_info(
                    song.info.webpage_url, download=False)
            except:
                asyncio.wait(1)
                downloader = yt_dlp.YoutubeDL(
                    {'title': True, "cookiefile": config.COOKIE_PATH})
                r = downloader.extract_info(
                    track, download=False)


            song.base_url = r.get('url')
            song.info.uploader = r.get('uploader')
            song.info.title = r.get('title')
            song.info.duration = r.get('duration')
            song.info.webpage_url = r.get('webpage_url')
            song.info.thumbnail = r.get('thumbnails')[0]['url']

        self.playlist.add_name(song.info.title)
        self.current_song = song

        self.playlist.playhistory.append(self.current_song)

        self.guild.voice_client.play(discord.FFmpegPCMAudio(
            song.base_url, before_options='-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5'), after=lambda e: self.next_song(e))

        self.guild.voice_client.source = discord.PCMVolumeTransformer(
            self.guild.voice_client.source)
        self.guild.voice_client.source.volume = float(self.volume) / 100.0

        self.playlist.playque.popleft()

        for song in list(self.playlist.playque)[:config.MAX_SONG_PRELOAD]:
            asyncio.ensure_future(self.preload(song))
Example #8
0
def get_mp3(url):
    global payload
    if not is_supported(url):
        return {"msg": "That video url didn't work.\n"
                                 "https://media.giphy.com/media/SFkjp1R8iRIWc/giphy.gif",
                          "file": ""
                          }
    payload = {}

    ydl_opts = {
        'format': 'bestaudio/best',
        'restrictfilenames': True,
        'outtmpl': f'{storage.absolute()}/%(title).50s.%(ext)s',
        'forcefilename': True,
        'ffmpeg_location': '/app/vendor/ffmpeg/ffmpeg',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '192',
        }],
        'logger': MyLogger(),
        'progress_hooks': [my_hook],
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        ydl.add_post_processor(MyCustomPP())
        info = ydl.extract_info(url)
        # print(json.dumps(ydl.sanitize_info(info)))
    return payload
Example #9
0
def get_mp4(url):
    global info
    global payload
    info = {}
    payload = {}

    if not is_supported(url):
        return {"msg": "That video url didn't work.\n"
                                 "https://media.giphy.com/media/SFkjp1R8iRIWc/giphy.gif",
                          "file": ""
                          }
    ydl_opts = {
        'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
        'restrictfilenames': True,
        # 'outtmpl': f'{storage.absolute()}/%(title)s.%(format_id)s.%(ext)s',
        'outtmpl': f'{storage.absolute()}/%(title).50s.%(ext)s',
        'windowsfilenames': True,
        'ffmpeg_location': '/app/vendor/ffmpeg/ffmpeg',
        'logger': MyLogger(),
        'progress_hooks': [my_hook],
    }

    with yt_dlp.YoutubeDL(ydl_opts) as ydl:
        ydl.add_post_processor(MyCustomPP())

        yt_info = ydl.extract_info(url)
        # pprint(yt_info)
        # pprint(ydl.sanitize_info(yt_info))
    return payload
Example #10
0
    def auto_poster(self,
                    url,
                    author,
                    group_id,
                    directory,
                    album_id=None,
                    wall_post=1):
        ydl_opts = {
            'outtmpl': f"../{directory}/%(title)s.%(ext)s",
            'quiet': True,
            'merge_output_format': 'mp4',
            'ignoreerrors': True,
            'format':
            "(((bv*[fps>30]/bv*)/(wv*[fps>30]/wv*)) + ba / (b[fps>30]/b)/(w[fps>30]/w))[format_id!=22]",
            'retries': 10
        }

        try:
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                ydl.download([url])
                video_info = ydl.extract_info(url, download=False)
                path = ydl.prepare_filename(video_info)
                title = video_info.get('title')
            id_vk, name_vk = self.upload("{" + author + "} " + title,
                                         path,
                                         group_id,
                                         album_id=album_id,
                                         wall_post=wall_post)
            return id_vk, name_vk
        except Exception as e:
            print("ОШИБКА " + str(e))
            print()
        finally:
            time.sleep(5)
            os.remove(path)
def download_video(url, captions, auto_captions, legacy):
    '''Try to download YouTube video in specific resolution.

    Fall back to bestvideo+bestaudio/best if not available in target resolution.
    '''
    ydl_opts = YDL_COMMON_OPTS.copy()
    ydl_opts.update(YDL_OPTS_SPECIFIC_RES)

    if args.skip_encoding:
        pass
    elif auto_captions:
        ydl_opts.update({'writeautomaticsub': True})
    elif captions:
        ydl_opts.update({'writesubtitles': True})


    while True:
        if legacy:
            with youtube_dl.YoutubeDL(ydl_opts) as ydl:
                try:
                    ydl.download([url])
                    break
                except youtube_dl.utils.DownloadError as e:
                    if 'not available' in str(e):
                        log.warning('Resolution {res} not available, downloading best possible resolution.'.format(res=args.res))
                        ydl_opts.update(YDL_OPTS_BEST_RES)
        else:
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                try:
                    ydl.download([url])
                    break
                except yt_dlp.utils.DownloadError as e:
                    if 'not available' in str(e):
                        log.warning('Resolution {res} not available, downloading best possible resolution.'.format(res=args.res))
                        ydl_opts.update(YDL_OPTS_BEST_RES)
Example #12
0
    def downloadYouTube(self, fileName, destinationDirectory, link):
        tempFilePath = os.path.join(DL_DIRECTORY, fileName)
        destinationPath = os.path.join(destinationDirectory, fileName)
        options = {
            'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]',
            'default_search': 'auto',
            'restrictfilenames': True,
            'prefer_ffmpeg': True,
            'quiet': True,
            'no_warnings': True,
            'ignoreerrors': True,
            'noplaylist': True,
            'noprogress': True,
            'logger': logger.get_null_log('YouTube-DL'),
            'outtmpl': tempFilePath
        }

        log.info('Attempting to download video: {} from "{}". Please Wait...'.
                 format(fileName, link))
        try:
            with yt_dlp.YoutubeDL(options) as youtube:
                youtube.extract_info(link, download=True)
        except Exception as e:
            log.warning(
                'Something went wrong while getting trailer from {}. ERROR: {}'
                .format(link, e))
            return False

        if os.path.isfile(tempFilePath):
            self._moveTo(tempFilePath, destinationPath)
            return True
        else:
            log.warning('Failed to download from {}'.format(link))
            return False
Example #13
0
    async def download(self, url: str, filePath: pathlib.Path):
        try:
            self._current = url

            settings = YOUTUBE_DL_OPTIONS
            settings["outtmpl"] = str(filePath)

            try:
                with youtube_dl.YoutubeDL(settings) as youtube:
                    self.log("Downloading {} to {}".format(url, filePath))

                    with ThreadPoolExecutor() as pool:
                        loop = asyncio.get_running_loop()
                        await loop.run_in_executor(
                            pool,
                            lambda: youtube.extract_info(url, download=True))

                    self.log("Finished downloading {} to {}".format(
                        url, filePath))

            except Exception as exception:
                self.error("Error downloading {}\n{}".format(url, exception))

        finally:
            self._current = ""
Example #14
0
def fetch_metadata(url):
    stdout = io.StringIO()
    stderr = io.StringIO()
    info = None
    with yt_dlp.YoutubeDL({'extract_flat': 'in_playlist'}) as ydl:
        ydl.params['extract_flat'] = 'in_playlist'
        return ydl.extract_info(url, download=False)
Example #15
0
def _tubeDl(url: str, starttime, uid: str):
    ydl_opts = {
        "addmetadata": True,
        "geo_bypass": True,
        "nocheckcertificate": True,
        "outtmpl": os.path.join(
            Config.TEMP_DIR, str(starttime), "%(title)s-%(format)s.%(ext)s"
        ),
        #         "logger": LOGS,
        "format": uid,
        "writethumbnail": True,
        "prefer_ffmpeg": True,
        "postprocessors": [
            {"key": "FFmpegMetadata"}
            # ERROR R15: Memory quota vastly exceeded
            # {"key": "FFmpegVideoConvertor", "preferedformat": "mp4"},
        ],
        "quiet": True,
    }
    try:
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            x = ydl.download([url])
    except DownloadError as e:
        LOGS.error(e)
    except GeoRestrictedError:
        LOGS.error(
            "ERROR: The uploader has not made this video available in your country"
        )
    else:
        return x
Example #16
0
    def run(self):
        """
        Defines options to extract_info with youtube_dl
        """
        mylogger = MyLogger()
        ydl_opts = {
            'ignoreerrors': True,
            'noplaylist': True,
            'no_color': True,
            'nocheckcertificate': self.nocheckcertificate,
            'logger': mylogger,
        }

        if self.appdata['downloader'] == 'youtube_dl':
            with youtube_dl.YoutubeDL(ydl_opts) as ydl:
                meta = ydl.extract_info(self.url, download=False)

        elif self.appdata['downloader'] == 'yt_dlp':
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                meta = ydl.extract_info(self.url, download=False)

        error = mylogger.get_message()

        if error:
            self.data = (None, error)
        elif meta:
            self.data = (meta, None)

        wx.CallAfter(pub.sendMessage, "RESULT_EVT", status='')
Example #17
0
 async def _add_playlist(self, ctx, *, url):
     """Adds all songs in a playlist to the queue"""
     if len(url) > 100:
         raise ValueError("url too long (length over 100)")
     if not url.isprintable():
         raise ValueError(f"url not printable: {url!r}")
     print(ctx.message.author.name, "queued playlist", repr(url))
     bracketed = False
     if url[0] == "<" and url[-1] == ">":
         bracketed = True
         url = url[1:-1]
     info = self.get_info(ctx)
     queue = info["queue"]
     ytdl = youtube_dl.YoutubeDL(self.ytdl_opts | {
         'noplaylist': None,
         'playlistend': None,
         "extract_flat": True,
     })
     data = await asyncio.to_thread(ytdl.extract_info, url, download=False)
     if 'entries' not in data:
         raise ValueError("cannot find entries of playlist")
     entries = data['entries']
     for entry in entries:
         url = f"https://www.youtube.com/watch?v={entry['url']}"
         if bracketed:
             url = f"<{url}>"
         queue.append({"ty": "stream", "query": url})
     if info["current"] is None:
         self.schedule(ctx)
     await ctx.send(f"Added playlist to queue: {url}")
Example #18
0
def youtube_session() -> Iterator[requests.Session]:
    """This context opens a requests session and loads the youtube cookies file."""

    cookies_path = os.path.join(settings.BASE_DIR,
                                "config/youtube_cookies.pickle")
    session = requests.session()
    # Have yt-dlp deal with consent cookies etc to setup a valid session
    extractor = yt_dlp.extractor.youtube.YoutubeIE()
    extractor._downloader = yt_dlp.YoutubeDL()
    extractor.initialize()
    session.cookies.update(extractor._downloader.cookiejar)

    try:
        if os.path.getsize(cookies_path) > 0:
            with open(cookies_path, "rb") as cookies_file:
                session.cookies.update(pickle.load(cookies_file))
    except FileNotFoundError:
        pass

    headers = {"User-Agent": yt_dlp.utils.random_user_agent()}
    session.headers.update(headers)
    yield session

    with open(cookies_path, "wb") as cookies_file:
        pickle.dump(session.cookies, cookies_file)
Example #19
0
def extract_tracks(user_playlist: UserPlaylist) -> UserPlaylist:
    playlist_url = UriParser(user_playlist.uri).url

    with yt_dlp.YoutubeDL(YTDL_OPTS) as ytdl:
        playlist_infos = ytdl.extract_info(playlist_url,
                                           download=False,
                                           process=False)

    if not playlist_infos:
        user_playlist.title = "⚠️ Invalid or private playlist"
        user_playlist.enabled = False
        user_playlist.save()
        return user_playlist

    all_track_uris = []

    for video in playlist_infos['entries']:
        track_uri = make_track_uri(video)
        user_track, user_track_created = UserTrack.objects.get_or_create(
            track_uri=track_uri,
            user_playlist=user_playlist,
            defaults={'date_added': timezone.now()},
        )
        all_track_uris.append(track_uri)

    # Delete records that are missing from the current version of the playlist
    UserTrack.objects.filter(user_playlist=user_playlist).exclude(
        track_uri__in=all_track_uris).delete()

    user_playlist.title = playlist_infos['title']

    return user_playlist
Example #20
0
def make_track_uri(video):
    track_uri, track_uri_created = TrackUri.objects.get_or_create(
        uri=f'youtube:video:{video["id"]}', )

    # Videos that are private or deleted appear without an uploader
    track_uri.deleted = not video["uploader"]

    # Retry to fetch unavailable track info to check if it's still unavailable
    if track_uri.unavailable:
        with yt_dlp.YoutubeDL(YTDL_OPTS) as ytdl:
            track_uri.unavailable = (
                not track_uri.deleted
                and not ytdl.extract_info(UriParser(track_uri.uri).url,
                                          download=False,
                                          process=False))

    if not track_uri.deleted and not track_uri.track:
        artist_without_topic = re.sub(' - [Tt]opic$', '', video['uploader'])

        track_uri.track = Track.objects.create(
            title=video['title'],
            artist=artist_without_topic,
            duration=timedelta(seconds=int(video['duration'])),
        )

    track_uri.save()

    return track_uri
async def play(ctx, url):

    voice = discord.utils.get(bot.voice_clients, guild=ctx.guild)

    if ctx.voice_client is None:

        channel = ctx.author.voice.channel

        await channel.connect()

    ydl_opts = {'format': 'bestaudio'}

    server = ctx.message.guild

    voice_channel = server.voice_client
    FFMPEG_OPTIONS = {
        'before_options':
        '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
        'options': 'vn'
    }
    if not voice_channel.is_playing():
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(url, download=False)
            url2 = info['formats'][0]['url']
            print(url2)
            voice_channel.play(FFmpegPCMAudio(source=url2, **FFMPEG_OPTIONS))

        voice_channel.is_playing()

    else:

        await ctx.send("Cekaj da se zavrsi play ili kucaj '!stop'.")

    return
Example #22
0
    def run(self):
        """
        This atipic method is called by start() method after the instance
        this class. see Streaming class below.
        """
        if self.stop_work_thread:
            return

        ydl_opts = {
            'format': self.quality,
            'outtmpl': f'{self.outputdir}/{self.outtmpl}',
            'restrictfilenames': True,
            'nopart': True,  # see --no-part by --help
            'ignoreerrors': True,
            'continue': True,
            'no_warnings': False,
            'noplaylist': True,
            'no_color': True,
            'nocheckcertificate': self.nocheckcertificate,
            'ffmpeg_location': f'{DownloadStream.FFMPEG_URL}',
            'logger': MyLogger(),
        }
        if DownloadStream.DOWNLOADER == 'yt_dlp':
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                ydl.download([f"{self.url}"])

        elif DownloadStream.DOWNLOADER == 'youtube_dl':
            with youtube_dl.YoutubeDL(ydl_opts) as ydl:
                ydl.download([f"{self.url}"])
Example #23
0
def download_clip(url):
    video_info = {}
    ydl_opts = {
        'format':
        'best',  #2 71 - 2560x1440 (1440p) #313 - 3840x2160 (2160p) #248 - 1920x1080 (1080p)
        'outtmpl': '%(id)s.%(ext)s',
        'writethumbnail': True,  # Download Thumbnail
        'proxy': os.getenv('PROXY')
    }
    try:
        with yt_dlp.YoutubeDL(ydl_opts) as ydl:
            info_dict = ydl.extract_info(url, download=False)
            video_info["title"] = info_dict.get("title")
            video_info["cover"] = info_dict.get("thumbnail")
            video_info["link"] = info_dict.get("webpage_url")
            video_info["video_path"] = "%s.%s" % (info_dict["display_id"],
                                                  info_dict["ext"])
            video_info["cover_path"] = "%s.%s" % (info_dict["display_id"],
                                                  "jpg")
            ydl.download([url])
            im = Image.open("%s.%s" %
                            (info_dict["display_id"], "webp")).convert("RGB")
            im.save("%s.%s" % (info_dict["display_id"], "jpg"), "jpeg")
            logger.info("Successfully Download", [url])
            return video_info
    except Exception as e:
        print(e)
        return False
Example #24
0
def get_media_info(url):
    '''
        Extracts information from a YouTube URL and returns it as a dict. For a channel
        or playlist this returns a dict of all the videos on the channel or playlist
        as well as associated metadata.
    '''
    opts = get_yt_opts()
    opts.update({
        'skip_download': True,
        'forcejson': True,
        'simulate': True,
        'logger': log,
        'extract_flat': True,
    })
    response = {}
    with yt_dlp.YoutubeDL(opts) as y:
        try:
            response = y.extract_info(url, download=False)
        except yt_dlp.utils.DownloadError as e:
            raise YouTubeError(f'Failed to extract_info for "{url}": {e}') from e
    if not response:
        raise YouTubeError(f'Failed to extract_info for "{url}": No metadata was '
                           f'returned by youtube-dl, check for error messages in the '
                           f'logs above. This task will be retried later with an '
                           f'exponential backoff.')
    return response
Example #25
0
def _mp3Dl(url: str, starttime, uid: str):
    _opts = {
        "outtmpl": os.path.join(Config.TEMP_DIR, str(starttime), "%(title)s.%(ext)s"),
        #         "logger": LOGS,
        "writethumbnail": True,
        "prefer_ffmpeg": True,
        "format": "bestaudio/best",
        "geo_bypass": True,
        "nocheckcertificate": True,
        "postprocessors": [
            {
                "key": "FFmpegExtractAudio",
                "preferredcodec": "mp3",
                "preferredquality": uid,
            },
            {"key": "EmbedThumbnail"},  # ERROR: Conversion failed!
            {"key": "FFmpegMetadata"},
        ],
        "quiet": True,
    }
    try:
        with yt_dlp.YoutubeDL(_opts) as ytdl:
            dloader = ytdl.download([url])
    except Exception as y_e:
        LOGS.exception(y_e)
        return y_e
    else:
        return dloader
Example #26
0
    async def youtube_dl_query(self, query, offset=None, limit=None):

        logger.debug(f"youtube_dl_query: {query} {offset}, {limit}")
        ytdl_opts = {
            # "ignoreerrors": False,
            'quiet': True,
            'no_color': True,
            'extract_flat': "in_playlist",
            "playlistend": limit,
            'proxy': self.proxies.get("https", None) if self.proxies else None,
            'logger': logger
        }

        if offset:
            ytdl_opts["playliststart"] = offset + 1
            ytdl_opts["playlistend"] = offset + limit

        #     ytdl_opts["daterange"] = youtube_dl.DateRange(end=)

        with youtube_dl.YoutubeDL(ytdl_opts) as ydl:
            playlist_dict = ydl.extract_info(query, download=False)
            if not playlist_dict:
                logger.warn("youtube_dl returned no data")
                return
            for item in playlist_dict['entries']:
                yield AttrDict(
                    guid=item["id"],
                    title=item["title"],
                    duration_seconds=item["duration"],
                )
Example #27
0
def getVideoInfo(id, audioonly):
    log("Retrieving Metadata for Video " + id)

    url = "https://youtube.com/watch?v=" + id
    if audioonly:
        options = {
            'format':
            'bestaudio/best',
            'postprocessors': [{
                'key': 'FFmpegExtractAudio',
                'preferredcodec': 'mp3'
            }]
        }
    else:
        options = {
            'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best',
        }
    ydl = yt_dlp.YoutubeDL(options)
    info = ydl.extract_info(url, download=False)
    title = info.get("title", "")
    log("Title: " + title)
    size = info.get('filesize', 0)
    for f in info.get("requested_formats", []):
        size += f["filesize"]
    log("Size: " + str(size) + " Bytes")

    task_handler.add_task(id, title, audioonly, size)
Example #28
0
def _worker(
    input_queue: Queue,
    output_queue: Queue,
    output_folder,
    info_folder,
    *,
    cookiefile=None,
    verbose=False,
    timeout=5,
):
    ydl_opts = {
        'format': 'bestaudio/best',
        'outtmpl': str(output_folder / '%(id)s_temp.%(ext)s'),
        'quiet': True,
        'no_warnings': True,
        'socket_timeout': timeout,
    }
    if cookiefile is not None:
        ydl_opts['cookiefile'] = cookiefile
    with suppress_stderr(), yt_dlp.YoutubeDL(ydl_opts) as ydl:
        while not input_queue.empty():
            clips = input_queue.get()
            for clip_id, start, end in clips:
                try:
                    _download_clip(clip_id, start, end, ydl, output_folder,
                                   info_folder)
                    output_queue.put((clip_id, True))
                except Exception as ex:
                    if verbose:
                        print(
                            str(clip_id) + " --> " + str(type(ex)) + ": " +
                            str(ex))
                    output_queue.put((clip_id, False))
Example #29
0
def get_and_send_videos(msg: tg.Message, urls: list[str], gif: bool = False):
    logger.info(f"[{msg.message_id}] {', '.join(urls)}")
    opts: dict = YDL_OPTS if not gif else YDL_OPTS_GIF
    try:
        if trim := parse_timestamp(msg):
            opts["postprocessors"].append(trim)
    except InternalError as e:
        logger.error(f"[{msg.message_id}] {e.msg}")
        msg.reply_text(f"{e.msg}\nid: {msg.message_id}", quote=True, disable_web_page_preview=True)
        return
    with yt_dlp.YoutubeDL(opts) as ydl:
        for url in urls:
            ydl.cache.remove()
            fn = ""
            try:
                info = ydl.extract_info(url, download=True)
                v_id = info["id"]
                fn = ydl.prepare_filename(info)
                if trim:
                    fn += ".trim.mp4"
            except Exception as e:
                logger.error(f"[{msg.message_id}] {type(e)}: {e}")
                msg.reply_text(f"Unable to find video at {url}\nid: {msg.message_id}",
                               quote=True, disable_web_page_preview=True)
            else:
                send_videos(msg, url, fn, v_id, gif)
                f = Path(fn)
                if f.is_file():
                    f.unlink()
Example #30
0
    def fetch_metadata(self) -> bool:
        # in case of a radio playlist, restrict the number of songs that are downloaded
        assert self.id
        if self.is_radio():
            self.ydl_opts["playlistend"] = storage.get("max_playlist_items")
            # radios are not viewable with the /playlist?list= url,
            # create a video watch url with the radio list
            query_url = ("https://www.youtube.com/watch?v=" + self.id[2:] +
                         "&list=" + self.id)
        else:
            # if only given the id, yt-dlp returns an info dict resolving this id to a url.
            # we want to receive the playlist entries directly, so we query the playlist url
            query_url = "https://www.youtube.com/playlist?list=" + self.id

        try:
            with yt_dlp.YoutubeDL(self.ydl_opts) as ydl:
                info_dict = ydl.extract_info(query_url, download=False)
        except (yt_dlp.utils.ExtractorError,
                yt_dlp.utils.DownloadError) as error:
            self.error = error
            return False

        if info_dict["_type"] != "playlist" or "entries" not in info_dict:
            # query was not a playlist url -> search for the query
            assert False

        assert self.id == info_dict["id"]
        if "title" in info_dict:
            self.title = info_dict["title"]
        for entry in info_dict["entries"]:
            self.urls.append("https://www.youtube.com/watch?v=" + entry["id"])
        assert self.key is None

        return True