64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
import asyncio
|
||
from functools import partial
|
||
from pathlib import Path
|
||
from typing import Optional
|
||
import os
|
||
import yt_dlp
|
||
|
||
|
||
def build_opts(for_video: bool, outdir: Path, cookiefile: Optional[Path], browser: Optional[str], message=None, out_for_playlist: bool = True) -> dict:
|
||
postprocessors = []
|
||
if for_video:
|
||
postprocessors.append({'key': 'FFmpegVideoConvertor', 'preferedformat': 'mp4'})
|
||
|
||
outtmpl = '%(uploader)s_%(id)s.%(ext)s' if out_for_playlist else '%(title)s.%(ext)s'
|
||
|
||
opts: dict = {
|
||
'outtmpl': str(outdir / outtmpl),
|
||
'quiet': True,
|
||
'merge_output_format': 'mp4',
|
||
'postprocessors': postprocessors,
|
||
'retries': 5,
|
||
'fragment_retries': 5,
|
||
'concurrent_fragment_downloads': 5,
|
||
'noprogress': True, # ✅ Отключаем прогресс-бар
|
||
'source_address': '0.0.0.0',
|
||
}
|
||
|
||
proxy = os.getenv('HTTPS_PROXY') or os.getenv('HTTP_PROXY') or ''
|
||
if proxy:
|
||
opts['proxy'] = proxy
|
||
|
||
if cookiefile and cookiefile.exists():
|
||
opts['cookiefile'] = str(cookiefile)
|
||
elif browser:
|
||
opts['cookiesfrombrowser'] = (browser,)
|
||
|
||
# ✅ УБРАЛИ progress_hooks - они ломают event loop
|
||
|
||
return opts
|
||
|
||
|
||
async def run(url: str, opts: dict) -> tuple[Optional[Path], Optional[dict]]:
|
||
loop = asyncio.get_running_loop()
|
||
info, filepath = None, None
|
||
|
||
def _do():
|
||
nonlocal info, filepath
|
||
with yt_dlp.YoutubeDL(opts) as ydl:
|
||
info = ydl.extract_info(url, download=True)
|
||
|
||
out = None
|
||
if isinstance(info, dict):
|
||
out = info.get('_filename')
|
||
if not out:
|
||
rd = info.get('requested_downloads') or []
|
||
for it in rd[::-1]:
|
||
out = it.get('filepath') or it.get('filename')
|
||
if out:
|
||
break
|
||
filepath = Path(out) if out else None
|
||
|
||
await loop.run_in_executor(None, _do)
|
||
return filepath, info
|