# Импортируем необходимые модули from fastapi import APIRouter, HTTPException, Query from pydantic import BaseModel import yt_dlp import tempfile from fastapi.responses import FileResponse import os router = APIRouter(prefix="/yt-dlp", tags=["yt-dlp"]) class DownloadRequest(BaseModel): url: str format: str = "best" audio_only: bool = False @router.post("/download") async def download_video(data: DownloadRequest): """ Скачать видео по ссылке через yt-dlp и вернуть файл пользователю. """ save_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../data')) os.makedirs(save_dir, exist_ok=True) # choose output dir and format if data.audio_only: out_dir = os.path.join(save_dir, 'audio') os.makedirs(out_dir, exist_ok=True) outtmpl = os.path.join(out_dir, '%(title)s.%(ext)s') ydl_format = data.format if data.format != "best" else "bestaudio[ext=m4a]/bestaudio" else: outtmpl = os.path.join(save_dir, '%(title)s.%(ext)s') ydl_format = data.format ydl_opts = { 'outtmpl': outtmpl, 'format': ydl_format, # Use aria2c for parallel segmented downloading to speed up large files 'external_downloader': 'aria2c', 'external_downloader_args': ['-x', '16', '-s', '16', '-k', '1M'], } try: with yt_dlp.YoutubeDL(ydl_opts) as ydl: info = ydl.extract_info(data.url, download=True) filename = ydl.prepare_filename(info) except Exception as e: raise HTTPException(status_code=400, detail=f"Ошибка загрузки: {e}") if not os.path.exists(filename): raise HTTPException(status_code=404, detail="Файл не найден после загрузки") return FileResponse(filename, filename=os.path.basename(filename), media_type='application/octet-stream')