Files
youtube-microservice/app/utils/youtube.py
Viner Abubakirov cfc068e857 Временно переделал downloader и youtube
возможно потребуется перенести yt-dlp в консоль, и работать через stdout
2026-02-18 20:54:28 +05:00

88 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import Optional
from dataclasses import dataclass
@dataclass
class MediaContent:
url: str
headers: dict
chunk_size: int
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[MediaContent]:
"""
Возвращает ссылку на видеопоток с указанным разрешением
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 MediaContent(
f.get("url", ""),
f.get("http_headers", {}),
f.get("downloader_options", {}).get("http_chunk_size", 1024**2),
)
# если разрешение не указано или не найдено — берем лучший
if video_formats:
# сортируем по height
video_formats.sort(key=lambda x: x.get("height") or 0, reverse=True)
return MediaContent(
video_formats[0].get("url", ""),
video_formats[0].get("http_headers", {}),
video_formats[0]
.get("downloader_options", {})
.get("http_chunk_size", 1024**2),
)
return None
def get_audio_url(self) -> Optional[MediaContent]:
"""Возвращает ссылку на аудиопоток"""
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 MediaContent(
audio_formats[0].get("url", ""),
audio_formats[0].get("http_headers", {}),
audio_formats[0]
.get("downloader_options", {})
.get("http_chunk_size", 1024**2),
)
return None