o
    i                     @   s4  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
Z
d dlZddlmZ ddlmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z# G dd dej$Z%G d	d
 d
ej$Z&ej'G dd dZ(ej'G dd de(Z)ej'G dd de(Z*ej'G dd de(Z+e&j,e)ddddde&j-e)ddddde&j.e)dddie*dde+dddZ/ddddidddde/ddddd idddde/dd!d"did#dd$d%dd&d'did(e&j,e)ddddde&j-e)ddddde&j.e)dddiddd)dd*d+did,e&j,e)ddddde&j-e)ddddde&j.e)dddiddd-dd.d/d0d1d2d3d4idde&j,e)dddd5e&j-e)dddd5e&j.e)dddd5ie*dddd6dd7d8d9d:d;d<d2d=d>id?dd@ddAdBdCdDdEdFdGdHidIe&j,e)dddd5e&j.e)dddd5ie*dddddJddKdLdMd ide&j,e)ddddde&j-e)ddddde&j.e)dddidddNddOdPdQd idRdd$ddOdSdTd idRdddUddVdWdie&j,e)ddde&j-e)ddde&j.e)dddidXdYdZZ0d[d\ Z1d]d^ Z2d_d` Z3dadb Z4e4  G dcdd ddej$Z5deZ6G dfdg dgeZ7dS )h    N   )InfoExtractor   )	HTTPErrornetwork_exceptions)ExtractorErrorbug_reports_messagedatetime_from_strfilter_dict	get_firstint_or_noneis_htmljoin_nonemptyparse_count	qualities
str_to_inttraverse_objtry_calltry_getunified_timestampurl_or_nonevariadicc                   @      e Zd ZdZdZdZdS )_PoTokenContextplayergvssubsN)__name__
__module____qualname__PLAYERGVSSUBS r#   r#   R/home/ubuntu/.local/lib/python3.10/site-packages/yt_dlp/extractor/youtube/_base.pyr   $       r   c                   @   r   )StreamingProtocolhttpsdashhlsN)r   r   r   HTTPSDASHHLSr#   r#   r#   r$   r&   *   r%   r&   c                   @   s2   e Zd ZU dZeed< dZeed< dZeed< dS )BasePoTokenPolicyFrequiredrecommendednot_required_for_premiumN)r   r   r   r.   bool__annotations__r/   r0   r#   r#   r#   r$   r-   0   s   
 r-   c                   @   s   e Zd ZU dZeed< dS )GvsPoTokenPolicyFnot_required_with_player_tokenN)r   r   r   r4   r1   r2   r#   r#   r#   r$   r3   8   s   
 r3   c                   @      e Zd ZdS )PlayerPoTokenPolicyNr   r   r   r#   r#   r#   r$   r6   =       r6   c                   @   r5   )SubsPoTokenPolicyNr7   r#   r#   r#   r$   r9   B   r8   r9   TF)r.   r/   r0   r4   )r.   r/   )r.   )GVS_PO_TOKEN_POLICYPLAYER_PO_TOKEN_POLICYSUBS_PO_TOKEN_POLICYclientWEBz2.20260114.08.00)
clientNameclientVersion   )INNERTUBE_CONTEXTINNERTUBE_CONTEXT_CLIENT_NAMESUPPORTS_COOKIESSUPPORTS_AD_PLAYBACK_CONTEXTzMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15,gzip(gfe))r?   r@   	userAgentWEB_EMBEDDED_PLAYERz1.20260115.01.008   )rB   rC   rD   zmusic.youtube.com	WEB_REMIXz1.20260114.03.00C   )INNERTUBE_HOSTrB   rC   r:   rD   rE   WEB_CREATORz1.20260114.05.00>   )rB   rC   r:   REQUIRE_AUTHrD   ANDROIDz21.02.35   z?com.google.android.youtube/21.02.35 (Linux; U; Android 11) gzipAndroid11)r?   r@   androidSdkVersionrF   osName	osVersion)r.   r/   r4   )rB   rC   REQUIRE_JS_PLAYERr:   r;   
ANDROID_VRz1.71.26OculuszQuest 3    ztcom.google.android.apps.youtube.vr.oculus/1.71.26 (Linux; U; Android 12L; eureka-user Build/SQ3A.220605.009.A1) gzip12L)r?   r@   
deviceMakedeviceModelrS   rF   rT   rU      )rB   rC   rV   IOSz21.02.3Applez
iPhone16,2zMcom.google.ios.youtube/21.02.3 (iPhone16,2; U; CPU iOS 18_3_2 like Mac OS X;)iPhonez18.3.2.22D82)r?   r@   r[   r\   rF   rT   rU      )rB   rC   r:   r;   rV   MWEBz2.20260115.01.00zMozilla/5.0 (iPad; CPU OS 16_7_10 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1,gzip(gfe))rB   rC   r:   rD   rE   TVHTML5z7.20260114.12.00zMozilla/5.0 (ChromiumStylePlatform) Cobalt/25.lts.30.1034943-gold (unlike Gecko), Unknown_TV_Unknown_0/Unknown (Unknown, Unknown)   z
5.20260114z2Mozilla/5.0 (ChromiumStylePlatform) Cobalt/Version)rB   rC   rN   rD   TVHTML5_SIMPLYz1.0K   )rB   r:   rC   )web
web_safariweb_embedded	web_musicweb_creatorandroid
android_vriosmwebtvtv_downgraded	tv_simplyc                 C   sJ   |  dd^}}|r||d |fS | dd^}}| ||r"|d fS d fS )N.rA   r   _)rsplitsplit)client_namevariantbaser#   r#   r$   _split_innertube_cliente  s
   rz   c                 C   s<   t | d d^}}t|d d ddd |D  S )Nr   rt       c                 s   s    | ]}|d  V  qdS )r   Nr#   ).0xr#   r#   r$   	<genexpr>o  s    z$short_client_name.<locals>.<genexpr>)rz   rv   r   joinupper)rw   mainpartsr#   r#   r$   short_client_namem  s   &r   c                 C   s   | d  di ddi d S )NrB   
thirdPartyembedUrlzhttps://www.youtube.com/)
setdefaultupdate)ytcfgr#   r#   r$   _fix_embedded_ytcfgr  s   
r   c                  C   s   d} t | d d d }tt D ]k\}}|dd |dd |di  tD ]}|d |t  q)|dt  |d	t  |d
d |dd |dd |dd  |d d dd t	|\}}}d|| |d< |dkr|t
| qd S )N)rp   rg   ro   rl   rn   rK   zwww.youtube.comrV   Tr:   r;   r<   rN   FrD   rE   PLAYER_PARAMSrB   r=   hlen
   priorityembedded)r   tupleINNERTUBE_CLIENTSitemsr   r&   r3   r6   r9   rz   r   )BASE_CLIENTSr   r=   r   protocolrt   base_clientrx   r#   r#   r$   build_innertube_clientsx  s*   r   c                   @   sD   e Zd Ze Ze Ze Ze Ze Z	e Z
e ZdS )	BadgeTypeN)r   r   r   enumautoAVAILABILITY_UNLISTEDAVAILABILITY_PRIVATEAVAILABILITY_PUBLICAVAILABILITY_PREMIUMAVAILABILITY_SUBSCRIPTIONLIVE_NOWVERIFIEDr#   r#   r#   r$   r     s    r   youtubec                       s  e Zd ZdZdZdZdZdZg dZddhZ	d	Z
d
ZdZdZdd Zdd Zdd Zdd Zejdd Zdd Zdd Zdd Zdd Zdd  Zed!d" Zd#d$ Zd%Zd&Zdd(d)Zdd*d+Z dd-d.Z!dd/d0Z"dd1d2Z#dd3d4Z$dd5d6Z%e&d7d8 Z'ed9d: Z(d;d< Z)dd>d?Z*ed@dA Z+edBdC Z, fdDdEZ-	,	H	'ddIdJZ.ddKdLZ/e&dMdN Z0e&dOdP Z1dQdR Z2dSdT Z3dUdV Z4dWdX Z5dYdZ Z6d,d,d,d,d,d[d\d]Z7d,d,d,d,d,d,d'd^d_d`Z8dd,dadbdcZ9ddde Z:e&ddfdgZ;e<dhdi Z=e<dje>fdkdlZ?e<dmdn Z@e<dodp ZAddqdrZBdsdt ZCdueDfdvdwZEe&dxdy ZFe&d,dzd{d|ZGd}d~ ZHe&ddddZIe&dd ZJdddZK	,	,	'dddZLe&dd ZM  ZNS )YoutubeBaseInfoExtractorz-Provide base functions for Youtube extractorsa   channel|c|user|playlist|watch|w|v|embed|e|live|watch_popup|clip|shorts|movies|results|search|shared|hashtag|trending|explore|feed|feeds|browse|oembed|get_video_info|iframe_api|s/player|source|storefront|oops|index|account|t/terms|about|upload|signin|logoutzK(?:(?:PL|LL|EC|UU|FL|RD|UL|TL|PU|OLAK5uy_)[0-9A-Za-z-_]{10,}|RDMM|WL|LL|LM)F)}z!(?:www\.)?redirect\.invidious\.ioz(?:(?:www|dev)\.)?invidio\.usz$(?:www\.)?invidious\.pussthecat\.orgz(?:www\.)?invidious\.zee\.liz (?:www\.)?invidious\.ethibox\.frz(?:www\.)?iv\.ggtyler\.devz(?:www\.)?inv\.vern\.i2pzI(?:www\.)?am74vkcrjp2d5v36lcdqgsj2m6x36tbrkhsruoegwfcizzabnfgf5zyd\.onionz(?:www\.)?inv\.riverside\.rocksz(?:www\.)?invidious\.silur\.mez$(?:www\.)?inv\.bp\.projectsegfau\.ltzT(?:www\.)?invidious\.g4c3eya4clenolymqbpgwz3q3tawoxw56yhzk4vugqrl6dtu3ejvhjid\.onionz!(?:www\.)?invidious\.slipfox\.xyzzT(?:www\.)?invidious\.esmail5pdn24shtvieloeedh7ehz3nrwcdivnfhfcedl7gf4kwddhkqd\.onionzN(?:www\.)?inv\.vernccvbvyi5qhfzyqengccj7lkove6bjot2xhh5kajhwvidqafczrad\.onionz$(?:www\.)?invidious\.tiekoetter\.comzM(?:www\.)?iv\.odysfvr23q5wgt7i456o5t3trw2cw5dgn56vbjfbq2m7xsc5vqbqpcyd\.onionz (?:www\.)?invidious\.nerdvpn\.dez"(?:www\.)?invidious\.weblibre\.orgz(?:www\.)?inv\.odyssey346\.devz(?:www\.)?invidious\.dhusch\.dez(?:www\.)?iv\.melmac\.spacez(?:www\.)?watch\.thekitty\.zonez$(?:www\.)?invidious\.privacydev\.netzI(?:www\.)?ng27owmagn5amdm7l5s3rsqxwscl5ynppnis5dqcasogkyxcfqn7psid\.onionz (?:www\.)?invidious\.drivet\.xyzz(?:www\.)?vid\.priv\.auzI(?:www\.)?euxxcnhsynwmfidvhjf6uzptsmh4dipkmgdmcmxxuo7tunp3ad2jrwyd\.onionz(?:www\.)?inv\.vern\.ccz%(?:www\.)?invidious\.esmailelbob\.xyzz((?:www\.)?invidious\.sethforprivacy\.comz (?:www\.)?yt\.oelrichsgarcia\.dez(?:www\.)?yt\.artemislena\.euz!(?:www\.)?invidious\.flokinet\.toz(?:www\.)?invidious\.baczek\.mez(?:www\.)?y\.com\.sbz"(?:www\.)?invidious\.epicsite\.xyzz'(?:www\.)?invidious\.lidarshield\.cloudz(?:www\.)?yt\.funami\.techzT(?:www\.)?invidious\.3o7z6yfxhbw7n3za4rss6l434kmv55cgw2vuziwuigpwegswvwzqipyd\.onionzI(?:www\.)?osbivz6guyeahrwp2lnwyjk2xos342h4ocsxyqrlaopqjuhwn2djiiyd\.onionzI(?:www\.)?u2cvlit75owumwpy4dj2hsmvkq7nvrclkpht7xgyye2pyoxhpmclkrad\.onionz(?:(?:www|no)\.)?invidiou\.shz((?:(?:www|fi)\.)?invidious\.snopyta\.orgz(?:www\.)?invidious\.kabi\.tkz#(?:www\.)?invidious\.mastodon\.hostz$(?:www\.)?invidious\.zapashcanon\.frz3(?:www\.)?(?:invidious(?:-us)?|piped)\.kavin\.rocksz%(?:www\.)?invidious\.tinfoil-hat\.netz"(?:www\.)?invidious\.himiko\.cloudz((?:www\.)?invidious\.reallyancient\.techz(?:www\.)?invidious\.tubez(?:www\.)?invidiou\.sitez(?:www\.)?invidious\.sitez(?:www\.)?invidious\.xyzz (?:www\.)?invidious\.nixnet\.xyzz (?:www\.)?invidious\.048596\.xyzz(?:www\.)?invidious\.drycat\.frz(?:www\.)?inv\.skyn3t\.inz(?:www\.)?tube\.poal\.coz(?:www\.)?tube\.connect\.cafez(?:www\.)?vid\.wxzm\.sxz(?:www\.)?vid\.mint\.lgbtz(?:www\.)?vid\.puffyan\.usz(?:www\.)?yewtu\.bez(?:www\.)?yt\.elukerio\.orgz(?:www\.)?yt\.lelux\.fiz$(?:www\.)?invidious\.ggc-project\.dez(?:www\.)?yt\.maisputain\.ovhz(?:www\.)?ytprivate\.comz(?:www\.)?invidious\.13ad\.dez (?:www\.)?invidious\.toot\.koelnz(?:www\.)?invidious\.fdn\.frz!(?:www\.)?watch\.nettohikari\.comz (?:www\.)?invidious\.namazso\.euz"(?:www\.)?invidious\.silkky\.cloudz(?:www\.)?invidious\.exonip\.dez%(?:www\.)?invidious\.riverside\.rocksz#(?:www\.)?invidious\.blamefran\.netz(?:www\.)?invidious\.moomoo\.dez(?:www\.)?ytb\.trom\.tfz(?:www\.)?yt\.cyberhost\.ukz!(?:www\.)?kgg2m7yk5aybusll\.onionz!(?:www\.)?qklhadlycap4cnod\.onionzI(?:www\.)?axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4bzzsg2ii4fv2iid\.onionzI(?:www\.)?c7hqkpkpemu6e7emz5b4vyz7idjgdvgaaa3dyimmeojqbgpea3xqjoid\.onionzI(?:www\.)?fz253lmuao3strwbfbmx46yu7acac2jz27iwtorgmbqlkurlclmancad\.onionzT(?:www\.)?invidious\.l4qlywnpwqsluw65ts7md3khrivpirse744un3x7mlskqauz5pyuzgqd\.onionzH(?:www\.)?owxfohz4kjyv25fvlqilyxast7inivgiktls3th44jhk3ej3i7ya\.b32\.i2pzI(?:www\.)?4l2dgddgsrkf2ous66i6seeyi6etzfgrue332grh2n7madpwopotugyd\.onionzI(?:www\.)?w6ijuptxiku4xpnnaetxvnkc5vqcdu7mgns2u77qefoixi63vbvnpnqd\.onionzI(?:www\.)?kbjggqkzv65ivcqj6bumvp337z6264huv5kpkwuv6gu5yjiskvan7fad\.onionzI(?:www\.)?grwp24hodrefzvjjuccrkw3mjq4tzhaaq32amf33dzpmuxe7ilepcmad\.onionzI(?:www\.)?hpniueoejy4opn7bc4ftgazyqjoeqwlvh2uiku2xqku6zpoa4bf5ruid\.onionz(?:www\.)?piped\.kavin\.rocksz(?:www\.)?piped\.tokhmi\.xyzz(?:www\.)?piped\.syncpundit\.ioz(?:www\.)?piped\.mha\.fiz!(?:www\.)?watch\.whatever\.socialz!(?:www\.)?piped\.garudalinux\.orgz(?:www\.)?piped\.rivo\.lolz#(?:www\.)?piped-libre\.kavin\.rocksz(?:www\.)?yt\.jae\.fiz(?:www\.)?piped\.mint\.lgbtz(?:www\.)?il\.axz!(?:www\.)?piped\.esmailelbob\.xyzz"(?:www\.)?piped\.projectsegfau\.ltz (?:www\.)?piped\.privacydev\.netz%(?:www\.)?piped\.palveluntarjoaja\.euz(?:www\.)?piped\.smnz\.dez(?:www\.)?piped\.adminforge\.dez$(?:www\.)?watch\.whatevertinfoil\.dez(?:www\.)?piped\.qdi\.fiz(?:(?:www|cf)\.)?piped\.videoz(?:www\.)?piped\.aeong\.onez(?:www\.)?piped\.moomoo\.mez(?:www\.)?piped\.chauvet\.proz(?:www\.)?watch\.leptons\.xyzz(?:www\.)?pd\.vern\.ccz(?:www\.)?piped\.hostux\.netz(?:www\.)?piped\.lunar\.icuz(?:www\.)?hyperpipe\.surge\.shz%(?:www\.)?hyperpipe\.esmailelbob\.xyzz"(?:www\.)?listen\.whatever\.socialz(?:www\.)?music\.adminforge\.de)Safazidmsbscacsdadeetzen-INzen-GBr   eszes-419zes-USeufilfrzfr-CAglhrzuisitswlvlthunlnouzplzpt-PTptrosqskslzsr-Latnfisvvitrbebgkykkmkmnrusrukelhyiwurarfanemrhiasbnpaguortateknmlsithlomykaamkmzzh-CNzzh-TWzzh-HKjakoz1Unavailable videos will be hidden during playbackzUnavailable videos are hiddenz@[\w.-]{3,30}zUC[\w-]{22}r   zJhttps://github.com/yt-dlp/yt-dlp/wiki/Extractors#exporting-youtube-cookiesc                 C      | j d| j d|dd dS )N^()$zUC-iddefault_search_regex_YT_CHANNEL_UCID_RE)selfucidr#   r#   r$   ucid_or_noneO  s   z%YoutubeBaseInfoExtractor.ucid_or_nonec                 C   (   | j d| j dtj|pddd dS )Nr   r   r|   z@-handler   r   _YT_HANDLE_REurllibparseunquote)r   handler#   r#   r$   handle_or_noneR  s   z'YoutubeBaseInfoExtractor.handle_or_nonec                 C   r   )N'^(?:https?://(?:www\.)?youtube\.com)?/()r|   zchannel handler   r   r   urlr#   r#   r$   handle_from_urlV  s   z(YoutubeBaseInfoExtractor.handle_from_urlc                 C   r   )Nr   r  z
channel idr   r   r  r#   r#   r$   ucid_from_urlZ  s   z&YoutubeBaseInfoExtractor.ucid_from_urlc                 C   sn   | j ddddgdd }|sdS || jvr(td| d	t| jd
di ddd|dkr5| d| d |S )z
        Returns a language code supported by YouTube for the user preferred language.
        Returns None if no preferred language set.
        langYoutubeTr|   )ie_key	casesenser   r   NzUnsupported language code: z-. Supported language codes (case-sensitive): delimz, rs   expectedr   zPreferring "zQ" translated fields. Note that some metadata extraction may fail or be incorrect.)_configuration_arg_SUPPORTED_LANG_CODESr   r   report_warning)r   preferred_langr#   r#   r$   _preferred_lang^  s   

z(YoutubeBaseInfoExtractor._preferred_langc                 C   s@   | j rd S | jd}|r|jdsd S | jddddd d S )NSOCSCAA.youtube.comCAIT)secure)_has_auth_cookies_youtube_cookiesgetvalue
startswith_set_cookie)r   socsr#   r#   r$   _initialize_consentp  s   z,YoutubeBaseInfoExtractor._initialize_consentc                 C   s   | j d}i }|r'zttj|j}W n ty&   | dt	   Y nw |
| jp-ddd | jddtj|d d S )NPREFz Failed to parse user PREF cookier   UTC)r   tzr  )namer  )r  r  dictr   r   	parse_qslr  
ValueErrorr  r   r   r  r  	urlencode)r   pref_cookieprefr#   r#   r$   _initialize_prefx  s   z)YoutubeBaseInfoExtractor._initialize_prefc                 C   s$   d| _ | jrd| _ | d d S d S )NFTzFound YouTube account cookies)_passed_auth_cookiesr  write_debugr   r#   r#   r$   _initialize_cookie_auth  s
   z0YoutubeBaseInfoExtractor._initialize_cookie_authc                 C   s$   |    |   |   |   d S N)r)  r  r-  _check_login_requiredr,  r#   r#   r$   _real_initialize  s   z)YoutubeBaseInfoExtractor._real_initializec                 C   s4   | drtd| j dd| d| j  d S )Noauthz)Login with OAuth is no longer supported. Tr  z2Login with password is not supported for YouTube. )r  r   _youtube_login_hintr  )r   usernamepasswordr#   r#   r$   _perform_login  s   

z'YoutubeBaseInfoExtractor._perform_loginc                 C   s   | j dd d| j dS )Ncookiesmethodz. Also see  z3  for tips on effectively exporting YouTube cookies)_login_hint_COOKIE_HOWTO_WIKI_URLr,  r#   r#   r$   r2    s   z,YoutubeBaseInfoExtractor._youtube_login_hintc                 C   s.   | j r| js| jd| j d d d S d S d S )Nz3Login details are needed to download this content. r7  )_LOGIN_REQUIREDis_authenticatedraise_login_requiredr2  r,  r#   r#   r$   r/    s
   
z.YoutubeBaseInfoExtractor._check_login_requiredz@(?:window\s*\[\s*["\']ytInitialData["\']\s*\]|ytInitialData)\s*=zytInitialPlayerResponse\s*=rg   c                 C   s   t t| S r.  )copydeepcopyr   r   r=   r#   r#   r$   _get_default_ytcfg  s   z+YoutubeBaseInfoExtractor._get_default_ytcfgc                 C   s   t | d S )NrK   )r   r@  r#   r#   r$   _get_innertube_host  s   z,YoutubeBaseInfoExtractor._get_innertube_hostNc                    s$    fdd}||p||  |S )Nc                    s   t |  S r.  )r   )yexpected_typegetterr#   r$   <lambda>      z:YoutubeBaseInfoExtractor._ytcfg_get_safe.<locals>.<lambda>)rA  )r   r   rF  rE  default_client_funcr#   rD  r$   _ytcfg_get_safe  s   z(YoutubeBaseInfoExtractor._ytcfg_get_safec                 C      |  |dd dd ft|S )Nc                 S      | d S )NINNERTUBE_CLIENT_NAMEr#   r~   r#   r#   r$   rG        z?YoutubeBaseInfoExtractor._extract_client_name.<locals>.<lambda>c                 S      | d d d S )NrB   r=   r?   r#   rO  r#   r#   r$   rG        rK  strr   r   rI  r#   r#   r$   _extract_client_name     z-YoutubeBaseInfoExtractor._extract_client_namec                 C   rL  )Nc                 S   rM  )NINNERTUBE_CLIENT_VERSIONr#   rO  r#   r#   r$   rG    rP  zBYoutubeBaseInfoExtractor._extract_client_version.<locals>.<lambda>c                 S   rQ  )NrB   r=   r@   r#   rO  r#   r#   r$   rG    rR  rS  rU  r#   r#   r$   _extract_client_version  rW  z0YoutubeBaseInfoExtractor._extract_client_versionc                 C   s(   | j ddgtdd p|p| |pdS )Ninnertube_hostr|   r  r   rg   )r  CONFIGURATION_ARG_KEYrB  )r   req_api_hostnamerI  r#   r#   r$   _select_api_hostname  s
   z-YoutubeBaseInfoExtractor._select_api_hostnamec                 C   sD   t || |fdtd}t|dti d}|| jpdddd |S )	NrB   rE  r=   )rE  r   r   r   r   )r   timeZoneutcOffsetMinutes)r   rA  r#  r   r   r  )r   r   rI  contextclient_contextr#   r#   r$   _extract_context  s   z)YoutubeBaseInfoExtractor._extract_contextc                 C   s   t tt }g }|r|d|  ||||g td|	 
 }||g}|r8|d| |  dd| S )N: r|   rt   )rT  roundtimeappendr   valuesextendhashlibsha1encode	hexdigest)schemesidoriginadditional_parts	timestamp
hash_partssidhashr   r#   r#   r$   _make_sid_authorization  s   z0YoutubeBaseInfoExtractor._make_sid_authorizationc                 C   s
   |  dS )Nhttps://www.youtube.com)_get_cookiesr,  r#   r#   r$   r    s   
z)YoutubeBaseInfoExtractor._youtube_cookiesc                    sD   | j  t fdd}t fdd}t fdd}|p|||fS )zp
        Get SAPISID, 1PSAPISID, 3PSAPISID cookie values
        @returns sapisid, 1psapisid, 3psapisid
        c                      
    d j S )NSAPISIDr  r#   
yt_cookiesr#   r$   rG       
 z;YoutubeBaseInfoExtractor._get_sid_cookies.<locals>.<lambda>c                      rz  )Nz__Secure-3PAPISIDr|  r#   r}  r#   r$   rG    r  c                      rz  )Nz__Secure-1PAPISIDr|  r#   r}  r#   r$   rG    r  )r  r   )r   
yt_sapisidyt_3papisidyt_1papisidr#   r}  r$   _get_sid_cookies  s
   z)YoutubeBaseInfoExtractor._get_sid_cookiesrx  c           
   	   C   sn   g }i }|r
||d< |   \}}}d|fd|fd|ffD ]\}}	|	r-|| ||	|| q|s2dS d|S )z
        Generate API Session ID Authorization for Innertube requests. Assumes all requests are secure (https).
        @param origin: Origin URL
        @param user_session_id: Optional User Session ID
        @return: Authorization header value
        uSAPISIDHASHSAPISID1PHASHSAPISID3PHASHNrf  )r  ri  rw  r   )
r   rr  user_session_idauthorizationsrs  r  yt_1psapisidyt_3psapisidrp  rq  r#   r#   r$   _get_sid_authorization_header  s   
z6YoutubeBaseInfoExtractor._get_sid_authorization_headerc                 C   s   | j S r.  )r  r,  r#   r#   r$   r<    s   z)YoutubeBaseInfoExtractor.is_authenticatedc                 C   s,   |   \}}}d| jv }t|o|p|p|S )N
LOGIN_INFO)r  r  r1   )r   r  r  r  has_login_infor#   r#   r$   r    s   
z*YoutubeBaseInfoExtractor._has_auth_cookiesc                    s@   t  j|i |}t| dd r| js| jd| j ddd |S )Nr*  zThe provided YouTube account cookies are no longer valid. They have likely been rotated in the browser as a security measure. For tips on how to effectively export YouTube cookies, refer to  z .F	only_once)super_request_webpagegetattrr  r  r:  )r   argskwargsresponse	__class__r#   r$   r    s   z)YoutubeBaseInfoExtractor._request_webpageTDownloading API JSONUnable to download API pagec                 C   s   |rd|ind| j |di}|| | j|d}|ddi |r'|| | jd| |
| d| ||||t|d|t| j	d|	gt
d	d
d dddd ddS )Nrb  rI  zcontent-typezapplication/jsonhttps://z/youtubei/v1/utf8innertube_keyTr  r	  r   false)keyprettyPrintc                 S   s   |S r.  r#   rt   vr#   r#   r$   rG  .  s    z4YoutubeBaseInfoExtractor._call_api.<locals>.<lambda>)cndn)video_idfatalnoteerrnotedataheadersquery)rd  r   generate_api_headers_download_jsonr^  jsondumpsrn  r
   r  r\  )r   epr  r  r  r  r  r  rb  api_keyapi_hostnamerI  r  real_headersr#   r#   r$   	_call_api  s*   


z"YoutubeBaseInfoExtractor._call_apic                 C   s   | j | j|d||dS )Nzyt initial datar  )_search_json_YT_INITIAL_DATA_RE)r   item_idwebpager  r#   r#   r$   extract_yt_initial_data0  s   z0YoutubeBaseInfoExtractor.extract_yt_initial_datac                  G   s0   | D ]}t t|dd }|dur|  S qdS )zr
        Index of current account in account list.
        See: https://github.com/yt-dlp/yt-dlp/pull/519
        c                 S   rM  )NSESSION_INDEXr#   rO  r#   r#   r$   rG  :  rP  zAYoutubeBaseInfoExtractor._extract_session_index.<locals>.<lambda>N)r   r   )r  r   session_indexr#   r#   r$   _extract_session_index3  s   z/YoutubeBaseInfoExtractor._extract_session_indexc                 C   s,   | sdS |  d\}}}|r||fS d|fS )ad  
        Parse data_sync_id into delegated_session_id and user_session_id.

        data_sync_id is of the form "delegated_session_id||user_session_id" for secondary channel
        and just "user_session_id||" for primary channel.

        @param data_sync_id: data_sync_id string
        @return: Tuple of (delegated_session_id, user_session_id)
        )NNz||N)	partition)data_sync_idfirstrt   secondr#   r#   r$   _parse_data_sync_id>  s   z,YoutubeBaseInfoExtractor._parse_data_sync_idc                 G   4   t |ddthtf }r|S | j| }| |d S )z
        Extract current delegated session ID required to download private playlists of secondary channels
        @params response and/or ytcfg
        @return: delegated session ID
        .DELEGATED_SESSION_IDr   r   rT  any_extract_data_sync_idr  )r   r  delegated_sidr  r#   r#   r$   _extract_delegated_session_idP  s   
z6YoutubeBaseInfoExtractor._extract_delegated_session_idc                 G   r  )zx
        Extract current user session ID
        @params response and/or ytcfg
        @return: user session ID
        .USER_SESSION_IDrA   r  )r   r  user_sidr  r#   r#   r$   _extract_user_session_id]  s   
z1YoutubeBaseInfoExtractor._extract_user_session_idc                 G   s4   | j ddgtddd  }r|S t|ddthtfS )z
        Extract current account dataSyncId.
        In the format DELEGATED_SESSION_ID||USER_SESSION_ID or USER_SESSION_ID||
        @params response and/or ytcfg
        r  NTr  r   .)DATASYNC_ID)responseContextmainAppWebResponseContext
datasyncId)r  r\  r   rT  r  )r   r  r  r#   r#   r$   r  i  s
   z.YoutubeBaseInfoExtractor._extract_data_sync_idc                 G   s0   | j ddgtddd  }r|S t|dgtdS )zv
        Extracts visitorData from an API response or ytcfg
        Appears to be used to track session state
        visitor_dataNTr  r   )VISITOR_DATA)rB   r=   visitorData)r  r  r_  )r  r\  r   rT  )r   r  r  r#   r#   r$   _extract_visitor_datau  s   z.YoutubeBaseInfoExtractor._extract_visitor_datac                 C   s*   |si S | j | jd|ddd|ddpi S )Nz"ytcfg\.set\s*\(\s*({.+?})\s*\)\s*;r   {}r   Fr  )_parse_jsonr   )r   r  r  r#   r#   r$   extract_ytcfg  s   z&YoutubeBaseInfoExtractor.extract_ytcfgr   delegated_session_idr  r  rr  c          	      K   s   i }|p|  |}|r||d< |d u r| |}|s|d ur(|d ur$|nd|d< | j||p1| |d}|d ur@||d< ||d< t|dtdrKd	|d
< |S )NzX-Goog-PageIdr   zX-Goog-AuthUser)r  AuthorizationzX-Origin	LOGGED_INr_  truezX-Youtube-Bootstrap-Logged-In)r  r  r  r  r   r1   )	r   r   r  r  r  rr  r  r  authr#   r#   r$   _generate_cookie_auth_headers  s   
z6YoutubeBaseInfoExtractor._generate_cookie_auth_headers)r   r  r  r  r  r  rI  c             	   K   sr   d|  || }	t| j|dd |d| |||	|p| || j|dd |dd| j|||||	d}
t|
S )Nr  c                 S   rM  )NrC   r#   rO  r#   r#   r$   rG    rP  z?YoutubeBaseInfoExtractor.generate_api_headers.<locals>.<lambda>r  c                 S   rQ  )NrB   r=   rF   r#   rO  r#   r#   r$   rG    rR  )zX-YouTube-Client-NamezX-YouTube-Client-VersionOriginzX-Goog-Visitor-Id
User-Agentr  )r^  rT  rK  rY  r  r  r
   )r   r   r  r  r  r  r  rI  r  rr  r  r#   r#   r$   r    s$   
z-YoutubeBaseInfoExtractor.generate_api_headers)retry_fatalretry_on_statusc                O   s   | j |dD ]E}z| j|i |W   S  tyK } z,t|jtr8t|jtr/|jj|p-dvr8||_W Y d }~q| j	||d W Y d }~ d S d }~ww d S )Nr  i  i  )
RetryManager_download_webpager   
isinstancecauser   r   statuserror_error_or_warning)r   r  r  r  r  retryer#   r#   r$   _download_webpage_with_retries  s   z7YoutubeBaseInfoExtractor._download_webpage_with_retriesc                 C   s   dddd| ddd |}|si S | j||d|d	d
  dt| |ddddthfid}| ||p:i }t|d dkrGt	| |dkr`| j
s`t|dddthfpYi }|dd  |S )Nzhttps://m.youtube.comrx  zhttps://music.youtube.comzhttps://www.youtube.com/embed/z?html5=1zhttps://www.youtube.com/tv)ro   rg   rj   ri   rp   zDownloading rt   rf  z client configr  rB   r=   rF   )r  r  r   r   rp   
configInfoappInstallData)r  r  replacestripr   rA  rT  r  rz   r   r<  r#  pop)r   r=   r  r  r  r   config_infor#   r#   r$   _download_ytcfg  s6   


z(YoutubeBaseInfoExtractor._download_ytcfgc                 C   s   d| i}|rd|i|d< |S )NcontinuationclickTrackingParamsclickTrackingr#   )r  ctpr  r#   r#   r$   _build_api_continuation_query  s
   z6YoutubeBaseInfoExtractor._build_api_continuation_queryc                 C   sH   t |dd dd ft}|sd S |d}|sd S |d}| ||S )Nc                 S   rQ  )Ncontinuationsr   nextContinuationDatar#   rO  r#   r#   r$   rG    rR  zJYoutubeBaseInfoExtractor._extract_next_continuation_data.<locals>.<lambda>c                 S      | d d S )Nr  reloadContinuationDatar#   rO  r#   r#   r$   rG    rH  r  r  )r   r#  r  r  )clsrenderernext_continuationr  r  r#   r#   r$   _extract_next_continuation_data  s   

z8YoutubeBaseInfoExtractor._extract_next_continuation_datacontinuation_epc                 C   s\   t |dddthf}|| |D ]}t |ddthf}|sq|d}| ||  S d S )NcommandExecutorCommandcommands.continuationCommandtokenr  )r   r#  ri  rT  r  r  )r  r  continuation_commandscommandr  r  r#   r#   r$   _extract_continuation_ep_data  s   

z6YoutubeBaseInfoExtractor._extract_continuation_ep_datac                 C   s$   |  |}|r	|S t|dd| jdS )N))contentsr   rows
subThreads.continuationItemRenderer)continuationEndpoint)buttonbuttonRendererr	  F)get_allrE  )r  r   r
  )r  r   r  r#   r#   r$   _extract_continuation  s   
z.YoutubeBaseInfoExtractor._extract_continuationc                 c   sd    t |dd tp
g D ]$}t|tsq| D ]}|d}|s!q| |d}|r.||fV  qqd S )Nc                 S   rM  )Nalertsr#   rO  r#   r#   r$   rG    rP  z:YoutubeBaseInfoExtractor._extract_alerts.<locals>.<lambda>typetext)r   listr  r#  rj  r  	_get_text)r  r  
alert_dictalert
alert_typemessager#   r#   r$   _extract_alerts  s   


z(YoutubeBaseInfoExtractor._extract_alertsc           	      C   s   g g }}|D ] \}}|  dkr|r|||g q|| jvr'|||g q||d d  D ]\}}| jd| d| |d q0|rQtd|d d  |dd S )Nr  r   zYouTube said: z - r  rA   r  )lowerri  _IGNORED_WARNINGSr  r   )	r   r  r  r  r  errorswarningsr  alert_messager#   r#   r$   _report_alerts  s   

z'YoutubeBaseInfoExtractor._report_alertsc                 O   s   | j | |g|R i |S r.  )r#  r  )r   r  r  r  r#   r#   r$   _extract_and_report_alerts&  s   z3YoutubeBaseInfoExtractor._extract_and_report_alerts
badge_listc                 C   s   t jt jt jt jt jt jd}t jt jt jt jt jd}t jt jt jt jt jt jt jd}g }t|ddd fD ]B}|	t|dt
dpK|	t|d	}|rV|d
|i q8t|dddddt
dd}| D ]\}	}
|	| v ry|d
|
i  nqfq8|S )zr
        Extract known BadgeType's from a list of badge renderers.
        @returns [{'type': BadgeType}]
        )PRIVACY_UNLISTEDPRIVACY_PRIVATEPRIVACY_PUBLICCHECK_CIRCLE_THICKOFFICIAL_ARTIST_BADGECHECK)BADGE_STYLE_TYPE_MEMBERS_ONLYBADGE_STYLE_TYPE_PREMIUMBADGE_STYLE_TYPE_LIVE_NOWBADGE_STYLE_TYPE_VERIFIED BADGE_STYLE_TYPE_VERIFIED_ARTIST)unlistedprivatezmembers onlylivepremiumverifiedzofficial artist channel.c                 S   s   t d| S )Nz[bB]adgeRenderer$)research)r  rt   r#   r#   r$   rG  J  rH  z:YoutubeBaseInfoExtractor._extract_badges.<locals>.<lambda>)iconiconTyper_  styler  label)accessibilityDatar;  tooltipiconTooltipFr|   )r  rE  r   )r   r   r   r   r   r   r   r   r   r  rT  ri  r   r  )r   r%  icon_type_mapbadge_style_map	label_mapbadgesbadge
badge_typer;  matchlabel_badge_typer#   r#   r$   _extract_badges)  sN   
	
z(YoutubeBaseInfoExtractor._extract_badgesc                    s   t t|  fddS )Nc                    s   |d  kS )Nr  r#   r  rD  r#   r$   rG  _  rH  z5YoutubeBaseInfoExtractor._has_badge.<locals>.<lambda>)r1   r   )rB  rD  r#   rH  r$   
_has_badge]  s   z#YoutubeBaseInfoExtractor._has_badge)max_runsc             	   G   s   |pd gD ]h}|d u r| g}nt | |g d}tdd t|D s$|g}|D ]F}t|dd t}|r8|    S t|dd tpAg }|sKt|trK|}|d tt||pVt| }d	t |dtd	}|rl|    S q&qd S )
Nr   c                 s   s&    | ]}|d u pt |ttfV  qdS ).N)r  r  r   )r}   r  r#   r#   r$   r   h  s   $ z5YoutubeBaseInfoExtractor._get_text.<locals>.<genexpr>c                 S   rM  )N
simpleTextr#   rO  r#   r#   r$   rG  k  rP  z4YoutubeBaseInfoExtractor._get_text.<locals>.<lambda>c                 S   rM  )Nrunsr#   rO  r#   r#   r$   rG  n  rP  r|   ).r  r_  )
r   r  r   r   rT  r  r  minlenr   )r  rJ  	path_listpathobjitemr  rL  r#   r#   r$   r  a  s(   z"YoutubeBaseInfoExtractor._get_textc                 G   sJ   | j |g|R  p
d}t|}|d u r#t| jdtdd|dd d}|S )Nr|   z	^([\d,]+)z\scountr   )r  r   r   r   r6  sub)r   r  rO  
count_textrS  r#   r#   r$   
_get_countw  s   z#YoutubeBaseInfoExtractor._get_count
thumbnails)	final_keyc             
   G   s   g }|pdgD ];}t | g t||dR D ]*}t|d}|s#qd|v r.|dd }||t|dt|dd	 qq|S )
z
        Extract thumbnails from thumbnails dict
        @param path_list: path list to level that contains 'thumbnails' key
        r#   .r  maxresdefault?r   heightwidth)r  r[  r\  )r   r   r   r  rv   ri  r   )r  rX  rO  rW  rP  	thumbnailthumbnail_urlr#   r#   r$   _extract_thumbnails  s    
z,YoutubeBaseInfoExtractor._extract_thumbnailsc                 C   s^   t d| }|r-|d}|rt|S ztd|d|dW S  ty,   Y dS w dS )z
        Extracts a relative time from string and converts to dt object
        e.g. 'streamed 6 days ago', '5 seconds ago (edited)', 'updated today', '8 yr ago'
        z(?P<start>today|yesterday|now)|(?P<time>\d+)\s*(?P<unit>sec(?:ond)?|s|min(?:ute)?|h(?:our|r)?|d(?:ay)?|w(?:eek|k)?|mo(?:nth)?|y(?:ear|r)?)s?\s*agostartznow-{}{}rh  unitN)r6  r7  groupr	   formatr%  )relative_time_textmobjr`  r#   r#   r$   extract_relative_time  s   
z.YoutubeBaseInfoExtractor.extract_relative_timec                 C   s   |sd S |  |}d }t|tjrt| }|d u r-t|p,t| jd|	 dd d}|rE|rE|d u rE| j
dv rE| jd| ddd |S )	N)z([a-z]+\s*\d{1,2},?\s*20\d{2})z<(?:.+|^)(?:live|premieres|ed|ing)(?:\s*(?:on|for))?\s*(.+\d)z	time textr   )Nr   z"Cannot parse localized time text ""Tr  )rf  r  dtdatetimecalendartimegm	timetupler   r   r  r  r  )r   r  report_failuredt_rt  r#   r#   r$   _parse_time_text  s&   


z)YoutubeBaseInfoExtractor._parse_time_textbrowsec                 C   s  t | jdtd}t| j|d}t|}t|  }t|}	 z| j|d||||| ||
|	|
d	}W n ty } zvt	|j
tsO| j||dW  Y d }~S t	|j
tsb||_t| W Y d }~q|j
jd}t|st| j| j|j
jd ||dp|d|d	dd
d t}|r| jd|fgd	d |j
jdvr||_t| W Y d }~q| j||dW  Y d }~S d }~ww z	| j|dd W n- ty } z!d|j v r||_t| W Y d }~q| j||dW  Y d }~S d }~ww t|gt|R  stddd|_t|d }|s
d S q|S )Nraise_incomplete_datar[  r  T)	r  r  r  r  r  r  rb  r  rI  i   )prefixr  Fc                 S   r  )Nr  r  r#   rO  r#   r#   r$   rG    rH  z<YoutubeBaseInfoExtractor._extract_response.<locals>.<lambda>ERRORr  r  zunknown errorzIncomplete data receivedr  )r1   r  r\  iterr  nextr  rd  r   r  r  r   r  r   r  r  readr   r   r  _webpage_read_contentrT  r#  r  r$  msgr  r   r   )r   r  r  r  r  r   check_get_keysr  r  r  rI  raise_for_incompleteicd_retriesicd_rmmain_retriesmain_rmr  r  first_bytesyt_errorshould_retryr#   r#   r$   _extract_response  sl   



z*YoutubeBaseInfoExtractor._extract_responsec                 C   s   t d| d uS )Nz (https?://)?music\.youtube\.com/)r6  rE  )r  r#   r#   r$   is_music_url  s   z%YoutubeBaseInfoExtractor.is_music_url)rg   )Nrg   r.  )rx  N)TNr  r  NNNrg   )T)TTF)r  NNNrp  TNrg   )Or   r   r   __doc___RESERVED_NAMES_PLAYLIST_ID_REr;  _INVIDIOUS_SITESr  r  r   r   _NETRC_MACHINEr:  r   r   r  r  	functoolscached_propertyr  r  r)  r-  r0  r5  propertyr2  r/  r  _YT_INITIAL_PLAYER_RESPONSE_RErA  rB  rK  rV  rY  r^  rd  staticmethodrw  r  r  r  r<  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  classmethodr  r#  r
  r  r  r#  r$  r  rG  rI  r  rV  r_  rf  ro  r  r  __classcell__r#   r#   r  r$   r     s     	
























4



Br   )8rj  r>  dataclassesri  rh  r   r  rl  r  r6  rh  urllib.parser   commonr   networking.exceptionsr   r   utilsr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   Enumr   r&   	dataclassr-   r3   r6   r9   r*   r+   r,   WEB_PO_TOKEN_POLICIESr   rz   r   r   r   r   r\  r   r#   r#   r#   r$   <module>   s$   L
!

#
!!   
