def zap(session, service, **kwargs): errormsg = None if service and "http" in service.toString(): url = service.toString() url = url.split(":") if len(url) > 9: url = url[10] if YoutubeDL is not None and url.startswith("YT-DLP%3a//"): url = url.replace("YT-DLP%3a//", "") url = url.replace("%3a", ":") try: ydl = YoutubeDL({"format": "b", "no_color": True}) result = ydl.extract_info(url, download=False) result = ydl.sanitize_info(result) if result and result.get("url"): url = result["url"] print("[ChannelSelection] zap / YoutubeDLP result url %s" % url) return (url, errormsg) else: errormsg = "No Link found!" print("[ChannelSelection] zap / YoutubeDLP no streams") except Exception as e: errormsg = str(e) print("[ChannelSelection] zap / YoutubeDLP failed %s" % str(e)) pass return (None, errormsg)
def download_metadata(self, url: str, process_ie_data: bool): self._cache.clean() cache_key = f"{url}{process_ie_data}" cached_data = self._cache.get(cache_key) self._logger.debug( "Downloading metadata", url=url, cached=cached_data is not None ) if cached_data: return cached_data options = { # Allow getting the _type value set to URL when passing a playlist entry "noplaylist": True, "extract_flat": False, # Causes ydl to return None on error "ignoreerrors": True, "quiet": True, "progress_hooks": [], } ydl = YoutubeDL(options) with ydl: try: metadata = ydl.extract_info( url, download=False, process=process_ie_data ) self._cache.register(cache_key, metadata) return metadata except Exception as e: self._logger.error("Downloading metadata error", url=url, error=e) return None
def test_nocheckcertificate(self): ydl = YoutubeDL({'logger': FakeLogger()}) self.assertRaises(Exception, ydl.extract_info, 'https://127.0.0.1:%d/video.html' % self.port) ydl = YoutubeDL({'logger': FakeLogger(), 'nocheckcertificate': True}) r = ydl.extract_info('https://127.0.0.1:%d/video.html' % self.port) self.assertEqual(r['entries'][0]['url'], 'https://127.0.0.1:%d/vid.mp4' % self.port)
def test_unicode_path_redirection(self): # XXX: Python 3 http server does not allow non-ASCII header values if sys.version_info[0] == 3: return ydl = YoutubeDL({'logger': FakeLogger()}) r = ydl.extract_info('http://127.0.0.1:%d/302' % self.port) self.assertEqual(r['entries'][0]['url'], 'http://127.0.0.1:%d/vid.mp4' % self.port)
class YtDlpResolver: def __init__(self): self.ytdl = YoutubeDL(ytdl_opts) def get_url(self, video_id: str): try: return self.ytdl.extract_info(f'https://www.youtube.com/watch?v={video_id}', download=False)['url'] except Exception as ex: raise PluginError(ex)
def _run_test(self, **params): ydl = YoutubeDL({ 'logger': FakeLogger(), # Disable client-side validation of unacceptable self-signed testcert.pem # The test is of a check on the server side, so unaffected 'nocheckcertificate': True, **params, }) r = ydl.extract_info('https://127.0.0.1:%d/video.html' % self.port) self.assertEqual(r['entries'][0]['url'], 'https://127.0.0.1:%d/vid.mp4' % self.port)
def test_template(self): ie = yt_dlp.extractor.get_info_extractor(test_case['name'])() other_ies = [ get_info_extractor(ie_key)() for ie_key in test_case.get('add_ie', []) ] is_playlist = any(k.startswith('playlist') for k in test_case) test_cases = test_case.get('playlist', [] if is_playlist else [test_case]) def print_skipping(reason): print('Skipping %s: %s' % (test_case['name'], reason)) if not ie.working(): print_skipping('IE marked as not _WORKING') return for tc in test_cases: info_dict = tc.get('info_dict', {}) if not (info_dict.get('id') and info_dict.get('ext')): raise Exception( 'Test definition incorrect. The output file cannot be known. Are both \'id\' and \'ext\' keys present?' ) if 'skip' in test_case: print_skipping(test_case['skip']) return for other_ie in other_ies: if not other_ie.working(): print_skipping('test depends on %sIE, marked as not WORKING' % other_ie.ie_key()) return params = get_params(test_case.get('params', {})) params['outtmpl'] = tname + '_' + params['outtmpl'] if is_playlist and 'playlist' not in test_case: params.setdefault('extract_flat', 'in_playlist') params.setdefault('playlistend', test_case.get('playlist_mincount')) params.setdefault('skip_download', True) ydl = YoutubeDL(params, auto_init=False) ydl.add_default_info_extractors() finished_hook_called = set() def _hook(status): if status['status'] == 'finished': finished_hook_called.add(status['filename']) ydl.add_progress_hook(_hook) expect_warnings(ydl, test_case.get('expected_warnings', [])) def get_tc_filename(tc): return ydl.prepare_filename(tc.get('info_dict', {})) res_dict = None def try_rm_tcs_files(tcs=None): if tcs is None: tcs = test_cases for tc in tcs: tc_filename = get_tc_filename(tc) try_rm(tc_filename) try_rm(tc_filename + '.part') try_rm(os.path.splitext(tc_filename)[0] + '.info.json') try_rm_tcs_files() try: try_num = 1 while True: try: # We're not using .download here since that is just a shim # for outside error handling, and returns the exit code # instead of the result dict. res_dict = ydl.extract_info( test_case['url'], force_generic_extractor=params.get( 'force_generic_extractor', False)) except (DownloadError, ExtractorError) as err: # Check if the exception is not a network related one if not err.exc_info[0] in ( compat_urllib_error.URLError, socket.timeout, UnavailableVideoError, compat_http_client.BadStatusLine) or ( err.exc_info[0] == compat_HTTPError and err.exc_info[1].code == 503): raise if try_num == RETRIES: report_warning( '%s failed due to network errors, skipping...' % tname) return print( 'Retrying: {0} failed tries\n\n##########\n\n'.format( try_num)) try_num += 1 else: break if is_playlist: self.assertTrue( res_dict['_type'] in ['playlist', 'multi_video']) self.assertTrue('entries' in res_dict) expect_info_dict(self, res_dict, test_case.get('info_dict', {})) if 'playlist_mincount' in test_case: assertGreaterEqual( self, len(res_dict['entries']), test_case['playlist_mincount'], 'Expected at least %d in playlist %s, but got only %d' % (test_case['playlist_mincount'], test_case['url'], len(res_dict['entries']))) if 'playlist_count' in test_case: self.assertEqual( len(res_dict['entries']), test_case['playlist_count'], 'Expected %d entries in playlist %s, but got %d.' % ( test_case['playlist_count'], test_case['url'], len(res_dict['entries']), )) if 'playlist_duration_sum' in test_case: got_duration = sum(e['duration'] for e in res_dict['entries']) self.assertEqual(test_case['playlist_duration_sum'], got_duration) # Generalize both playlists and single videos to unified format for # simplicity if 'entries' not in res_dict: res_dict['entries'] = [res_dict] for tc_num, tc in enumerate(test_cases): tc_res_dict = res_dict['entries'][tc_num] # First, check test cases' data against extracted data alone expect_info_dict(self, tc_res_dict, tc.get('info_dict', {})) # Now, check downloaded file consistency tc_filename = get_tc_filename(tc) if not test_case.get('params', {}).get('skip_download', False): self.assertTrue(os.path.exists(tc_filename), msg='Missing file ' + tc_filename) self.assertTrue(tc_filename in finished_hook_called) expected_minsize = tc.get('file_minsize', 10000) if expected_minsize is not None: if params.get('test'): expected_minsize = max(expected_minsize, 10000) got_fsize = os.path.getsize(tc_filename) assertGreaterEqual( self, got_fsize, expected_minsize, 'Expected %s to be at least %s, but it\'s only %s ' % (tc_filename, format_bytes(expected_minsize), format_bytes(got_fsize))) if 'md5' in tc: md5_for_file = _file_md5(tc_filename) self.assertEqual(tc['md5'], md5_for_file) # Finally, check test cases' data again but this time against # extracted data from info JSON file written during processing info_json_fn = os.path.splitext(tc_filename)[0] + '.info.json' self.assertTrue(os.path.exists(info_json_fn), 'Missing info file %s' % info_json_fn) with io.open(info_json_fn, encoding='utf-8') as infof: info_dict = json.load(infof) expect_info_dict(self, info_dict, tc.get('info_dict', {})) finally: try_rm_tcs_files() if is_playlist and res_dict is not None and res_dict.get( 'entries'): # Remove all other files that may have been extracted if the # extractor returns full results even with extract_flat res_tcs = [{'info_dict': e} for e in res_dict['entries']] try_rm_tcs_files(res_tcs)
async def add_to_playlist(_, message: Message): with suppress(MessageIdInvalid, MessageNotModified): admins = await get_admins(Config.CHAT) if Config.ADMIN_ONLY: if not (message.from_user is None and message.sender_chat or message.from_user.id in admins): k = await message.reply_sticker( "CAADBQADsQIAAtILIVYld1n74e3JuQI") await delete_messages([message, k]) return type = "" yturl = "" ysearch = "" url = "" if message.command[0] == "fplay": if not (message.from_user is None and message.sender_chat or message.from_user.id in admins): k = await message.reply("This command is only for admins.") await delete_messages([message, k]) return msg = await message.reply_text("⚡️ **Checking recived input..**") if message.reply_to_message and message.reply_to_message.video: await msg.edit("⚡️ **Checking Telegram Media...**") type = 'video' m_video = message.reply_to_message.video elif message.reply_to_message and message.reply_to_message.document: await msg.edit("⚡️ **Checking Telegram Media...**") m_video = message.reply_to_message.document type = 'video' if not "video" in m_video.mime_type: return await msg.edit("The given file is invalid") elif message.reply_to_message and message.reply_to_message.audio: #if not Config.IS_VIDEO: #return await message.reply("Play from audio file is available only if Video Mode if turned off.\nUse /settings to configure ypur player.") await msg.edit("⚡️ **Checking Telegram Media...**") type = 'audio' m_video = message.reply_to_message.audio else: if message.reply_to_message and message.reply_to_message.text: query = message.reply_to_message.text elif " " in message.text: text = message.text.split(" ", 1) query = text[1] else: await msg.edit( "You Didn't gave me anything to play.Reply to a video or a youtube link or a direct link." ) await delete_messages([message, msg]) return regex = r"^(?:https?:\/\/)?(?:www\.)?youtu\.?be(?:\.com)?\/?.*(?:watch|embed)?(?:.*v=|v\/|\/)([\w\-_]+)\&?" match = re.match(regex, query) if match: type = "youtube" yturl = query elif query.startswith("http"): try: has_audio_ = await is_audio(query) except: has_audio_ = False LOGGER.error("Unable to get Audio properties within time.") if has_audio_: try: dur = await get_duration(query) except: dur = 0 if dur == 0: await msg.edit( "This is a live stream, Use /stream command.") await delete_messages([message, msg]) return type = "direct" url = query else: if is_ytdl_supported(query): type = "ytdl_s" url = query else: await msg.edit( "This is an invalid link, provide me a direct link or a youtube link." ) await delete_messages([message, msg]) return else: type = "query" ysearch = query if not message.from_user is None: user = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" user_id = message.from_user.id else: user = "******" user_id = "anonymous_admin" now = datetime.now() nyav = now.strftime("%d-%m-%Y-%H:%M:%S") if type in ["video", "audio"]: if type == "audio": if m_video.title is None: if m_video.file_name is None: title_ = "Music" else: title_ = m_video.file_name else: title_ = m_video.title if m_video.performer is not None: title = f"{m_video.performer} - {title_}" else: title = title_ unique = f"{nyav}_{m_video.file_size}_audio" else: title = m_video.file_name unique = f"{nyav}_{m_video.file_size}_video" if Config.PTN: ny = parse(title) title_ = ny.get("title") if title_: title = title_ file_id = m_video.file_id if title is None: title = 'Music' data = {1: title, 2: file_id, 3: "telegram", 4: user, 5: unique} if message.command[0] == "fplay": pla = [data] + Config.playlist Config.playlist = pla else: Config.playlist.append(data) await add_to_db_playlist(data) await msg.edit("Media added to playlist") elif type in ["youtube", "query", "ytdl_s"]: if type == "youtube": await msg.edit("⚡️ **Fetching Video From YouTube...**") url = yturl elif type == "query": try: await msg.edit("⚡️ **Fetching Video From YouTube...**") ytquery = ysearch results = YoutubeSearch(ytquery, max_results=1).to_dict() url = f"https://youtube.com{results[0]['url_suffix']}" title = results[0]["title"][:40] except Exception as e: await msg.edit("Song not found.\nTry inline mode..") LOGGER.error(str(e), exc_info=True) await delete_messages([message, msg]) return elif type == "ytdl_s": url = url else: return ydl_opts = { "quite": True, "geo-bypass": True, "nocheckcertificate": True } ydl = YoutubeDL(ydl_opts) try: info = ydl.extract_info(url, False) except Exception as e: LOGGER.error(e, exc_info=True) await msg.edit(f"YouTube Download Error ❌\nError:- {e}") LOGGER.error(str(e)) await delete_messages([message, msg]) return if type == "ytdl_s": title = "Music" try: title = info['title'] except: pass else: title = info["title"] if info['duration'] is None: await msg.edit( "This is a live stream, Use /stream command.") await delete_messages([message, msg]) return data = { 1: title, 2: url, 3: "youtube", 4: user, 5: f"{nyav}_{user_id}" } if message.command[0] == "fplay": pla = [data] + Config.playlist Config.playlist = pla else: Config.playlist.append(data) await add_to_db_playlist(data) await msg.edit(f"[{title}]({url}) added to playist", disable_web_page_preview=True) elif type == "direct": data = { 1: "Music", 2: url, 3: "url", 4: user, 5: f"{nyav}_{user_id}" } if message.command[0] == "fplay": pla = [data] + Config.playlist Config.playlist = pla else: Config.playlist.append(data) await add_to_db_playlist(data) await msg.edit("Link added to playlist") if not Config.CALL_STATUS \ and len(Config.playlist) >= 1: await msg.edit("Downloading and Processing...") await download(Config.playlist[0], msg) await play() elif (len(Config.playlist) == 1 and Config.CALL_STATUS): await msg.edit("Downloading and Processing...") await download(Config.playlist[0], msg) await play() elif message.command[0] == "fplay": await msg.edit("Downloading and Processing...") await download(Config.playlist[0], msg) await play() else: await send_playlist() await msg.delete() pl = await get_playlist_str() if message.chat.type == "private": await message.reply(pl, reply_markup=await get_buttons(), disable_web_page_preview=True) elif not Config.LOG_GROUP and message.chat.type == "supergroup": if Config.msg.get('playlist') is not None: await Config.msg['playlist'].delete() Config.msg['playlist'] = await message.reply( pl, disable_web_page_preview=True, reply_markup=await get_buttons()) await delete_messages([message]) for track in Config.playlist[:2]: await download(track)
async def schedule_vc(bot, message): with suppress(MessageIdInvalid, MessageNotModified): type="" yturl="" ysearch="" msg = await message.reply_text("⚡️ **Checking recived input..**") if message.reply_to_message and message.reply_to_message.video: await msg.edit("⚡️ **Checking Telegram Media...**") type='video' m_video = message.reply_to_message.video elif message.reply_to_message and message.reply_to_message.document: await msg.edit("⚡️ **Checking Telegram Media...**") m_video = message.reply_to_message.document type='video' if not "video" in m_video.mime_type: return await msg.edit("The given file is invalid") elif message.reply_to_message and message.reply_to_message.audio: #if not Config.IS_VIDEO: #return await message.reply("Play from audio file is available only if Video Mode if turned off.\nUse /settings to configure ypur player.") await msg.edit("⚡️ **Checking Telegram Media...**") type='audio' m_video = message.reply_to_message.audio else: if message.reply_to_message and message.reply_to_message.text: query=message.reply_to_message.text elif " " in message.text: text = message.text.split(" ", 1) query = text[1] else: await msg.edit("You Didn't gave me anything to schedule. Reply to a video or a youtube link or a direct link.") await delete_messages([message, msg]) return regex = r"^(?:https?:\/\/)?(?:www\.)?youtu\.?be(?:\.com)?\/?.*(?:watch|embed)?(?:.*v=|v\/|\/)([\w\-_]+)\&?" match = re.match(regex,query) if match: type="youtube" yturl=query elif query.startswith("http"): has_audio_ = await is_audio(query) if not has_audio_: if is_ytdl_supported(query): type="ytdl_s" url=query else: await msg.edit("This is an invalid link, provide me a direct link or a youtube link.") await delete_messages([message, msg]) return type="direct" url=query else: type="query" ysearch=query if not message.from_user is None: user=f"[{message.from_user.first_name}](tg://user?id={message.from_user.id}) - (Scheduled)" user_id = message.from_user.id else: user="******" user_id = "anonymous_admin" now = datetime.now() nyav = now.strftime("%d-%m-%Y-%H:%M:%S") if type in ["video", "audio"]: if type == "audio": if m_video.title is None: if m_video.file_name is None: title_ = "Music" else: title_ = m_video.file_name else: title_ = m_video.title if m_video.performer is not None: title = f"{m_video.performer} - {title_}" else: title=title_ unique = f"{nyav}_{m_video.file_size}_audio" else: title=m_video.file_name unique = f"{nyav}_{m_video.file_size}_video" if Config.PTN: ny = parse(title) title_ = ny.get("title") if title_: title = title_ if title is None: title = 'Music' data={'1':title, '2':m_video.file_id, '3':"telegram", '4':user, '5':unique} sid=f"{message.chat.id}_{msg.message_id}" Config.SCHEDULED_STREAM[sid] = data await sync_to_db() elif type in ["youtube", "query", "ytdl_s"]: if type=="youtube": await msg.edit("⚡️ **Fetching Video From YouTube...**") url=yturl elif type=="query": try: await msg.edit("⚡️ **Fetching Video From YouTube...**") ytquery=ysearch results = YoutubeSearch(ytquery, max_results=1).to_dict() url = f"https://youtube.com{results[0]['url_suffix']}" title = results[0]["title"][:40] except Exception as e: await msg.edit( "Song not found.\nTry inline mode.." ) LOGGER.error(str(e), exc_info=True) await delete_messages([message, msg]) return elif type == "ytdl_s": url=url else: return ydl_opts = { "quite": True, "geo-bypass": True, "nocheckcertificate": True } ydl = YoutubeDL(ydl_opts) try: info = ydl.extract_info(url, False) except Exception as e: LOGGER.error(e, exc_info=True) await msg.edit( f"YouTube Download Error ❌\nError:- {e}" ) LOGGER.error(str(e)) await delete_messages([message, msg]) return if type == "ytdl_s": title = "Music" try: title=info['title'] except: pass else: title = info["title"] data={'1':title, '2':url, '3':"youtube", '4':user, '5':f"{nyav}_{user_id}"} sid=f"{message.chat.id}_{msg.message_id}" Config.SCHEDULED_STREAM[sid] = data await sync_to_db() elif type == "direct": data={"1":"Music", '2':url, '3':"url", '4':user, '5':f"{nyav}_{user_id}"} sid=f"{message.chat.id}_{msg.message_id}" Config.SCHEDULED_STREAM[sid] = data await sync_to_db() if message.chat.type!='private' and message.from_user is None: await msg.edit( text="You cant schedule from here since you are an anonymous admin. Click the schedule button to schedule through private chat.", reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton(f"Schedule", url=f"https://telegram.dog/{Config.BOT_USERNAME}?start=sch_{sid}"), ] ] ),) await delete_messages([message, msg]) return today = datetime.now(IST) smonth=today.strftime("%B") obj = calendar.Calendar() thisday = today.day year = today.year month = today.month m=obj.monthdayscalendar(year, month) button=[] button.append([InlineKeyboardButton(text=f"{str(smonth)} {str(year)}",callback_data=f"sch_month_choose_none_none")]) days=["Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun"] f=[] for day in days: f.append(InlineKeyboardButton(text=f"{day}",callback_data=f"day_info_none")) button.append(f) for one in m: f=[] for d in one: year_=year if d < int(today.day): year_ += 1 if d == 0: k="\u2063" d="none" else: k=d f.append(InlineKeyboardButton(text=f"{k}",callback_data=f"sch_month_{year_}_{month}_{d}")) button.append(f) button.append([InlineKeyboardButton("Close", callback_data="schclose")]) await msg.edit(f"Choose the day of the month you want to schedule the voicechat.\nToday is {thisday} {smonth} {year}. Chooosing a date preceeding today will be considered as next year {year+1}", reply_markup=InlineKeyboardMarkup(button))