from typing import Optional class YtDlpInfo: def __init__(self, url: str): self.url = url self.info = None self._extract_info() def _extract_info(self): import yt_dlp ydl_opts = { "quiet": True, "skip_download": True, "noplaylist": True, "js-runtimes": "deno" } with yt_dlp.YoutubeDL(ydl_opts) as ydl: self.info = ydl.extract_info(self.url, download=False) @property def title(self) -> str: """Возвращает title видео""" return self.info.get("title", "unknown") def get_video_url(self, resolution: Optional[str] = None) -> Optional[tuple[dict, str]]: """ Возвращает ссылку на видеопоток с указанным разрешением resolution: например '1080p', '720p', '480p' """ formats = self.info.get("formats", []) video_formats = [ f for f in formats if f.get("vcodec") != "none" # есть видео and f.get("acodec") == "none" # без аудио ] if resolution: # ищем точное соответствие разрешению for f in video_formats: if f.get("format_note") == resolution: return f.get("http_headers", {}), f.get("url") # если разрешение не указано или не найдено — берем лучший if video_formats: # сортируем по height video_formats.sort(key=lambda x: x.get("height") or 0, reverse=True) return video_formats[0].get("http_headers"), video_formats[0].get("url") return None def get_audio_url(self) -> Optional[tuple[dict,str]]: """Возвращает ссылку на аудиопоток""" formats = self.info.get("formats", []) audio_formats = [ f for f in formats if f.get("vcodec") == "none" and f.get("acodec") != "none" ] if audio_formats: # берем наилучшее качество audio_formats.sort(key=lambda x: x.get("abr") or 0, reverse=True) return audio_formats[0].get("http_headers"), audio_formats[0].get("url") return None