Skip to content

Commit 27154a6

Browse files
committed
feat: Implement custom yt-dlp logger and add MessageNotModified error handling for message edits.
1 parent 292d661 commit 27154a6

2 files changed

Lines changed: 46 additions & 19 deletions

File tree

bot/core/calls.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,13 @@ async def play_media(
820820

821821
# 3. Retry Logic
822822
self._consecutive_failures[chat_id] += 1
823-
await message.edit_text("🔄 File corrupted, re-fetching...")
823+
from pyrogram.errors import MessageNotModified
824+
try:
825+
await message.edit_text("🔄 File corrupted, re-fetching...")
826+
except MessageNotModified:
827+
pass
828+
except Exception as e:
829+
logger.debug(f"Could not edit message for re-fetch: {e}")
824830

825831
try:
826832
# Re-fetch media (Stream OR Download)

bot/core/youtube.py

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,27 @@ class DownloadCancelledError(Exception):
3636
class YouTube:
3737
StorageLowError = StorageLowError # Expose exception class
3838

39+
class YtDlpLogger:
40+
def debug(self, msg):
41+
from bot import config, logger
42+
if config.YTDLP_VERBOSE and not msg.startswith('[debug] '):
43+
logger.info(f"yt-dlp: {msg}")
44+
def info(self, msg):
45+
from bot import config, logger
46+
if config.YTDLP_VERBOSE:
47+
logger.info(f"yt-dlp: {msg}")
48+
def warning(self, msg):
49+
from bot import logger
50+
logger.warning(f"yt-dlp: {msg}")
51+
def error(self, msg):
52+
from bot import logger
53+
logger.error(f"yt-dlp: {msg}")
54+
55+
def _YoutubeDL(self, params: dict):
56+
if "logger" not in params:
57+
params["logger"] = self.YtDlpLogger()
58+
return self._YoutubeDL(params)
59+
3960
def __init__(self):
4061
self.base = "https://www.youtube.com/watch?v="
4162
self.cookies = []
@@ -307,7 +328,7 @@ async def search(self, query: str, m_id: int, video: bool = False) -> Track | No
307328
if cookie: ydl_opts["cookiefile"] = cookie
308329
if config.PROXY_URL: ydl_opts["proxy"] = config.PROXY_URL
309330

310-
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
331+
with self._YoutubeDL(ydl_opts) as ydl:
311332
# ytsearch1: returns 1 result
312333
info = await asyncio.to_thread(ydl.extract_info, f"ytsearch1:{query}", download=False)
313334

@@ -343,7 +364,7 @@ async def _generic_search(self, url: str, m_id: int, video: bool = False) -> Tra
343364
ydl_opts["cookiefile"] = cookie
344365

345366
try:
346-
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
367+
with self._YoutubeDL(ydl_opts) as ydl:
347368
try:
348369
info = await asyncio.to_thread(ydl.extract_info, url, download=False)
349370
except Exception as ex:
@@ -355,7 +376,7 @@ async def _generic_search(self, url: str, m_id: int, video: bool = False) -> Tra
355376
logger.warning("_generic_search: Primary cookie failed. Retrying with fallback...")
356377
ydl_opts["cookiefile"] = fallback
357378
try:
358-
with yt_dlp.YoutubeDL(ydl_opts) as ydl_fallback:
379+
with self._YoutubeDL(ydl_opts) as ydl_fallback:
359380
info = await asyncio.to_thread(ydl_fallback.extract_info, url, download=False)
360381
logger.info("✅ Fallback cookie success (search)!")
361382
except Exception as ex2:
@@ -368,7 +389,7 @@ async def _generic_search(self, url: str, m_id: int, video: bool = False) -> Tra
368389
if config.PROXY_URL:
369390
ydl_opts["proxy"] = config.PROXY_URL
370391

371-
with yt_dlp.YoutubeDL(ydl_opts) as ydl_less:
392+
with self._YoutubeDL(ydl_opts) as ydl_less:
372393
info = await asyncio.to_thread(ydl_less.extract_info, url, download=False)
373394
logger.info("✅ Cookie-less fallback success (search)!")
374395
else:
@@ -381,7 +402,7 @@ async def _generic_search(self, url: str, m_id: int, video: bool = False) -> Tra
381402
if config.PROXY_URL:
382403
ydl_opts["proxy"] = config.PROXY_URL
383404

384-
with yt_dlp.YoutubeDL(ydl_opts) as ydl_less:
405+
with self._YoutubeDL(ydl_opts) as ydl_less:
385406
info = await asyncio.to_thread(ydl_less.extract_info, url, download=False)
386407
logger.info("✅ Cookie-less fallback success (search)!")
387408
else:
@@ -556,7 +577,7 @@ async def _generic_playlist(self, url: str, limit: int, user: str, video: bool)
556577
ydl_opts["cookiefile"] = cookie
557578

558579
try:
559-
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
580+
with self._YoutubeDL(ydl_opts) as ydl:
560581
try:
561582
info = await asyncio.to_thread(ydl.extract_info, url, download=False)
562583
except Exception as ex:
@@ -568,7 +589,7 @@ async def _generic_playlist(self, url: str, limit: int, user: str, video: bool)
568589
logger.warning("_generic_playlist: Primary cookie failed. Retrying with fallback...")
569590
ydl_opts["cookiefile"] = fallback
570591
try:
571-
with yt_dlp.YoutubeDL(ydl_opts) as ydl_fallback:
592+
with self._YoutubeDL(ydl_opts) as ydl_fallback:
572593
info = await asyncio.to_thread(ydl_fallback.extract_info, url, download=False)
573594
logger.info("✅ Fallback cookie success (playlist)!")
574595
except Exception as ex2:
@@ -580,7 +601,7 @@ async def _generic_playlist(self, url: str, limit: int, user: str, video: bool)
580601
if config.PROXY_URL:
581602
ydl_opts["proxy"] = config.PROXY_URL
582603

583-
with yt_dlp.YoutubeDL(ydl_opts) as ydl_less:
604+
with self._YoutubeDL(ydl_opts) as ydl_less:
584605
info = await asyncio.to_thread(ydl_less.extract_info, url, download=False)
585606
logger.info("✅ Cookie-less fallback success (playlist)!")
586607
else:
@@ -592,7 +613,7 @@ async def _generic_playlist(self, url: str, limit: int, user: str, video: bool)
592613
if config.PROXY_URL:
593614
ydl_opts["proxy"] = config.PROXY_URL
594615

595-
with yt_dlp.YoutubeDL(ydl_opts) as ydl_less:
616+
with self._YoutubeDL(ydl_opts) as ydl_less:
596617
info = await asyncio.to_thread(ydl_less.extract_info, url, download=False)
597618
logger.info("✅ Cookie-less fallback success (playlist)!")
598619
else:
@@ -706,7 +727,7 @@ def _download():
706727
free_space = disk_usage.free
707728

708729
# Get expected file size first and check if it fits
709-
with yt_dlp.YoutubeDL({"quiet": True, "geo_bypass": True, "nocheckcertificate": True}) as ydl_info:
730+
with self._YoutubeDL({"quiet": True, "geo_bypass": True, "nocheckcertificate": True}) as ydl_info:
710731
try:
711732
info = ydl_info.extract_info(url, download=False)
712733
filesize = info.get("filesize") or info.get("filesize_approx") or 0
@@ -727,7 +748,7 @@ def _download():
727748
# Try primary download
728749
downloaded_path = None
729750
try:
730-
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
751+
with self._YoutubeDL(ydl_opts) as ydl:
731752
ydl.download([url])
732753

733754
# Find the downloaded file
@@ -747,7 +768,7 @@ def _download():
747768
logger.warning("Primary cookie failed with Sign-in/SSL error. Retrying with fallback cookie...")
748769
ydl_opts["cookiefile"] = fallback
749770
try:
750-
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
771+
with self._YoutubeDL(ydl_opts) as ydl:
751772
ydl.download([url])
752773
logger.info("✅ Fallback cookie success!")
753774

@@ -769,7 +790,7 @@ def _download():
769790
ydl_opts["proxy"] = config.PROXY_URL
770791

771792
try:
772-
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
793+
with self._YoutubeDL(ydl_opts) as ydl:
773794
ydl.download([url])
774795
logger.info("✅ Cookie-less fallback success!")
775796
# Find file
@@ -899,7 +920,7 @@ async def get_stream_url(self, video_id: str, video: bool = False, quality: str
899920
try:
900921
logger.info(f"Extracting stream URL for {url}")
901922

902-
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
923+
with self._YoutubeDL(ydl_opts) as ydl:
903924
# Extract info without downloading
904925
try:
905926
info = await asyncio.to_thread(ydl.extract_info, url, download=False)
@@ -911,7 +932,7 @@ async def get_stream_url(self, video_id: str, video: bool = False, quality: str
911932
logger.warning("get_stream_url: Primary cookie failed. Retrying with fallback...")
912933
ydl_opts["cookiefile"] = fallback
913934
try:
914-
with yt_dlp.YoutubeDL(ydl_opts) as ydl_fallback:
935+
with self._YoutubeDL(ydl_opts) as ydl_fallback:
915936
info = await asyncio.to_thread(ydl_fallback.extract_info, url, download=False)
916937
logger.info("✅ Fallback cookie success (stream)!")
917938
except Exception as ex2:
@@ -922,7 +943,7 @@ async def get_stream_url(self, video_id: str, video: bool = False, quality: str
922943
if config.PROXY_URL:
923944
ydl_opts["proxy"] = config.PROXY_URL
924945

925-
with yt_dlp.YoutubeDL(ydl_opts) as ydl_less:
946+
with self._YoutubeDL(ydl_opts) as ydl_less:
926947
info = await asyncio.to_thread(ydl_less.extract_info, url, download=False)
927948
logger.info("✅ Cookie-less fallback success (stream)!")
928949
else:
@@ -934,7 +955,7 @@ async def get_stream_url(self, video_id: str, video: bool = False, quality: str
934955
if config.PROXY_URL:
935956
ydl_opts["proxy"] = config.PROXY_URL
936957

937-
with yt_dlp.YoutubeDL(ydl_opts) as ydl_less:
958+
with self._YoutubeDL(ydl_opts) as ydl_less:
938959
info = await asyncio.to_thread(ydl_less.extract_info, url, download=False)
939960
logger.info("✅ Cookie-less fallback success (stream)!")
940961
else:
@@ -1171,7 +1192,7 @@ async def smart_autoplay(self, mode: str | bool, previous_track: Track = None) -
11711192
try:
11721193
ydl_opts = {"quiet": True, "no_warnings": True}
11731194
video_url = f"https://www.youtube.com/watch?v={video_id}"
1174-
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
1195+
with self._YoutubeDL(ydl_opts) as ydl:
11751196
info = await asyncio.to_thread(ydl.extract_info, video_url, download=False)
11761197
if info and info.get("duration"):
11771198
duration_sec = info.get("duration")

0 commit comments

Comments
 (0)