Retry oversized video downloads instead of giving up permanently

VK can briefly serve a not-yet-transcoded master stream on a capped-height
URL right after a video is published, tripping the size check on the very
first attempt. Treat that as transient (retry with a longer backoff) instead
of failing permanently, and merge the fallback note into a single "Смотреть
видео в VK" link instead of two separate lines.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 23:24:06 +05:00
parent 4ad047b5c3
commit d01a17146e
2 changed files with 18 additions and 13 deletions
+9 -4
View File
@@ -112,11 +112,16 @@ class MediaProcessor:
return path, err, is_permanent return path, err, is_permanent
last_result = (path, err, is_permanent) last_result = (path, err, is_permanent)
if attempt <= settings.yt_dlp_retry_attempts: if attempt <= settings.yt_dlp_retry_attempts:
# A fresh upload's lower-quality renditions can still be mid-transcode on
# VK's side - the "720p" URL then briefly serves the full-res master until
# the ladder catches up, which trips our size cap. That's not a permanent
# rejection, just needs more time than a stalled connection does.
delay = 60.0 if "exceeds size limit" in (err or "") else 3.0
logger.warning( logger.warning(
"yt-dlp attempt {}/{} failed transiently for {}: {} - retrying", "yt-dlp attempt {}/{} failed transiently for {}: {} - retrying in {}s",
attempt, settings.yt_dlp_retry_attempts + 1, url, err, attempt, settings.yt_dlp_retry_attempts + 1, url, err, delay,
) )
await asyncio.sleep(3.0) await asyncio.sleep(delay)
return last_result return last_result
async def _download_video_ytdlp_attempt( async def _download_video_ytdlp_attempt(
@@ -219,7 +224,7 @@ class MediaProcessor:
) )
output_path.unlink(missing_ok=True) output_path.unlink(missing_ok=True)
await unregister_active_path(output_path) await unregister_active_path(output_path)
return None, "video exceeds size limit", True return None, "video exceeds size limit", False
return output_path, None, False return output_path, None, False
+9 -9
View File
@@ -154,18 +154,18 @@ def build_media_unavailable_note(
media_type = str(getattr(item, "media_type", "медиа") or "медиа") media_type = str(getattr(item, "media_type", "медиа") or "медиа")
if not url: if not url:
continue continue
label = "Смотреть видео" if media_type == "video" else media_type if media_type == "video":
if parse_mode == "html": target = vk_url or url
lines.append(f'- <a href="{html.escape(url, quote=True)}">{html.escape(label)}</a>') label = "Смотреть видео в VK"
else: else:
lines.append(f"- {label}: {url}") target = url
label = media_type
if parse_mode == "html":
lines.append(f'- <a href="{html.escape(target, quote=True)}">{html.escape(label)}</a>')
else:
lines.append(f"- {label}: {target}")
if not lines: if not lines:
return "" return ""
if vk_url:
if parse_mode == "html":
lines.append(f'- <a href="{html.escape(vk_url, quote=True)}">Открыть пост в VK</a>')
else:
lines.append(f"- пост в VK: {vk_url}")
header = "Не поместилось в пост:" header = "Не поместилось в пост:"
if parse_mode == "html": if parse_mode == "html":
header = f"<i>{html.escape(header)}</i>" header = f"<i>{html.escape(header)}</i>"