
    V|h                        S SK r S SKrS SKrS SKrS SKrS SKrSSKJr  SSK	J
r
  SSKJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJrJr  SSKJ r J!r!   " S S	\5      r" " S
 S\"5      r#S r$ " S S\"5      r% " S S\"5      r& " S S\&5      r' " S S\'5      r( " S S\&5      r) " S S\&5      r* " S S\'5      r+ " S S\"5      r,g)    N   )InfoExtractor   )	HTTPError)ExtractorErrorUserNotLivebase_url
clean_htmldict_getfloat_or_noneint_or_nonejoin_nonemptymake_archive_idparse_durationparse_iso8601parse_qs	qualitiesstr_or_nonetry_getunified_timestampupdate_url_queryurl_or_noneurljoin)traverse_objvaluec                       \ rS rSrSrSrSrSrSrSr	SS	S
SSSSSSSSS.r
\S 5       rS rS rSS jrSS jrS rS rSS jrSrg) TwitchBaseIE"   z&https?://(?:(?:www|go|m)\.)?twitch\.tvzhttps://api.twitch.tvzhttps://usher.ttvnw.netzhttps://www.twitch.tv/loginz https://passport.twitch.tv/logintwitch@27111f1b382effad0b6def325caef1909c733fe6a4fbabf54f8d491ef2cf2f14@a937f1d22e269e39a03b509f65a7490f9fc247d7f83d6ac1421523e3b68042cb@b73ad2bfaecfd30a9e6c28fada15bd97032c83ec77a0440766a56fe0bd632777@e0a46b287d760c6890a39d1ccd736af5ec9479a267d02c710e9ac33326b651d2@447aec6a0cc1e8d0a8d7732d47eb0762c336a2294fdb009e9c9d854e49d484b9@a647c2a13599e5991e175155f798ca7f1ecddde73f7f341f39009c14dbf59962@e1edae8122517d013405f237ffcc124515dc6ded82480a88daef69c83b53ac01@3006e77e51b128d838fa4e835723ca4dc9a05c5efd4466c1085215c6e437e65c@49b5b8f268cdeb259d75b58dcb0c1a748e3b575003448a2333dc5cdafd49adad@8d2793384aac3773beab5e59bd5d6f585aedb923d292800119e03d40cd0f9b41@07e99e4d56c5a7c67117a154777b0baf85a5ffefa393b213f4bc712ccaf85dd6)CollectionSideBarFilterableVideoTower_VideosClipsCards__UserShareClipRenderStatusChannelCollectionsContentStreamMetadataComscoreStreamingQueryVideoPreviewOverlayVideoMetadata$VideoPlayer_ChapterSelectButtonVideo"VideoPlayer_VODSeekbarPreviewVideoc                 .    U R                  SS/SSS9S   $ )N	client_idue6666qo983tsx6so1t0vnawi233waTwitchT)ie_key	casesenser   )_configuration_arg)selfs    Q/home/james-whalen/.local/lib/python3.13/site-packages/yt_dlp/extractor/twitch.py
_CLIENT_IDTwitchBaseIE._CLIENT_ID9   s3    &&:;HX\ ' ^^_a 	a    c           	      :  ^ ^ S mUU 4S jnT R                  T R                  S S5      u  pESU;   a  T" [        U5      5        U" XESUUT R                  S.5      u  peU(       d  g [        R
                  " SU5      b  T R                  S5      nU" XeS	US
S.5        g g )Nc                     [        SU  3SS9e)NzUnable to login. Twitch said: Texpected)r   )messages    r>   fail)TwitchBaseIE._perform_login.<locals>.fail?   s     0	:TK KrA   c           	        > TR                  U 5      nUR                  U5        UR                  nTR                  SU STR                  SS9n[        XV5      nUSSS.nTR                  US U[        R                  " U5      R                  5       USS	9n[        US
5      n	U	(       a  T" U	5        SUR                  SS5      ;   a  g[        UUR                  S5      =(       d    US   5      n
TR                  U
S SUS9$ )Nz&<form[^>]+action=(["\'])(?P<url>.+?)\1zpost urlurl)defaultgroupzhttps://www.twitch.tvtext/plain;charset=UTF-8)RefererOriginContent-Typei  )dataheadersexpected_status)errorerror_description
error_codezAuthenticated successfullyrF    )NNredirectredirect_pathzDownloading login redirect page)rR   )_hidden_inputsupdaterJ   _search_regex_LOGIN_POST_URLr   _download_jsonjsondumpsencoder   get_download_webpage_handle)pageurlhnoterQ   formpage_urlpost_urlrR   responserT   redirect_urlrG   r=   s              r>   
login_step/TwitchBaseIE._perform_login.<locals>.login_stepC   s   &&t,DKKxxH))94D$8$8 * GH x2H $1 :G **$4::d+;+B+B+D + 6H X'STEU+x||Ir/JJ!"Z(EH_,EGL 00d$E 1 ! !rA   zDownloading login pageblacklist_messagez
Logging in)usernamepasswordr7   z$(?i)<form[^>]+id="two-factor-submit"ztwo-factor authentication tokenzSubmitting TFA tokentrue)authy_tokenremember_2fa)rc   _LOGIN_FORM_URLr
   r?   research_get_tfa_info)	r=   ro   rp   rl   
login_pagehandleredirect_page	tfa_tokenrG   s	   `       @r>   _perform_loginTwitchBaseIE._perform_login>   s    	K	!B "::  $(@B
 *,J'( *$$!__/! 99<mLX**+LMI}.D( &G  YrA   c                      [        S U 5       5      nSUS'   g ! [         a+    U H"  nSUS   ;   d  M  UR                  SSS.5        M$      g f = f)Nc              3   :   #    U  H  oS    S:X  d  M  Uv   M     g7f)	format_idSourceN ).0fs     r>   	<genexpr>.TwitchBaseIE._prefer_source.<locals>.<genexpr>   s     KW+(0J!!Ws   	
   qualityz	/chunked/rJ   r   )r   format_note)nextStopIterationr[   )r=   formatssourcer   s       r>   _prefer_sourceTwitchBaseIE._prefer_source~   s]    		KWKKF "F9 	!E(*HH#%'/  	s    AAAc           	          SU R                   S.nU R                  S5      R                  S5      nU(       a  SUR                  -   US'   U R	                  SX[
        R                  " U5      R                  5       XTS9$ )	NrM   )rP   z	Client-IDhttps://gql.twitch.tv
auth-tokenzOAuth Authorizationzhttps://gql.twitch.tv/gql)rQ   rR   fatal)r?   _get_cookiesrb   r   r^   r_   r`   ra   )r=   video_idopsrf   r   rR   gql_auths          r>   _download_base_gqlTwitchBaseIE._download_base_gql   s{    6
 $$%<=AA,O'/(..'@GO$""'C'') # * 	*rA   c                 l    U H  nSSU R                   US      S.0US'   M     U R                  XU5      $ )NpersistedQueryr   operationName)version
sha256Hash
extensions)_OPERATION_HASHESr   )r=   r   r   rf   r   ops         r>   _download_gqlTwitchBaseIE._download_gql   sK    B  "&"8"8O9L"M# B|  &&xd;;rA   c                 f    U S3nSSU< SU< SU< S30nU R                  XSU S35      S	   U   $ )
NPlaybackAccessTokenqueryz{
              z(
                z: "a  ",
                params: {
                  platform: "web",
                  playerBackend: "mediaplayer",
                  playerType: "site"
                }
              )
              {
                value
                signature
              }
            }Downloading z access token GraphQLrQ   )r   )r=   r   
token_kind
param_namemethodr   s         r>   _download_access_token#TwitchBaseIE._download_access_token   s_    <23 J2
  &&:,&;<>>DFFLN 	NrA   c                 R    U(       a  [         R                  " SSU5      SS.SU0/$ S $ )Nz\d+x\d+(\.\w+)($|(?=[?#]))z0x0\g<1>r   rJ   
preferencerJ   )ru   sub)r=   	thumbnails     r>   _get_thumbnailsTwitchBaseIE._get_thumbnails   sB     	 667iP
 9
 	"
 "	"rA   c                 0    U R                  U R                   SU SU S3USSSS[        R                  " SS5      SSS	SUUS
.
S9nU H  nUR!                  S5      (       a>  US   R)                  S5      (       a%  UR+                  S0 5      R-                  SS S/05        U(       d  M`  UR+                  S0 5      R-                  S!S"S#/05        SUS$'   M     U$ ! [         Ga1  n[        UR                  [        5      (       aC  UR                  R                  S:w  d)  UR                  R                  R                  S5      S:w  a  e [        UR                  R                  R                  5       [        R                  1S[        145      =(       d    0 nUR!                  S5      S;   aH  Sn	U R#                  S5      R!                  S5      (       a  [	        SU	 3SS9eU R%                  SU	 35        ['        SSUSS9=n
(       a
  [	        U
SS9ee S nAff = f)%N/z.m3u8mp4rq   i@B i web	twitchwebzav1,h265,h264)
allow_sourceallow_audio_onlyallow_spectrepplatformplayersupported_codecsplaylist_include_frameratesigtokenr   i  zcontent-typezapplication/jsonr   rV   )vod_manifest_restrictedunauthorized_entitlementsz&access to this subscriber-only contentr   r   zYour account does not have TrD   z,You must be logged into an account that has rT   z: )	from_dictdelimvcodecav01downloader_optionsffmpeg_args_outz-fffmpeg_argsz-live_start_index0is_from_start)_extract_m3u8_formats_USHER_BASErandomrandintr   
isinstancecauser   statusrj   
get_headerr   readr_   loadsdictrb   r   raise_login_requiredr   
startswith
setdefaultr[   )r=   pathr   r   	signaturelive_from_startr   e
error_info
common_msg	error_msgfmts               r>   _extract_twitch_m3u8_formats)TwitchBaseIE._extract_twitch_m3u8_formats   s   	00##$AdV1XJe<h$*(.%+: %)(728$"V 1 G@ Cwwx  S]%=%=f%E%E3R8??ARUY[`Ta@bc3R8??QdfiPj@kl'+O$  7  	qww	2277>>S(77##..~>BTT%agg&6&6&;&;&=aRVQW?XY_]_J~~l+/ggE
$$%<=AA,OO(+Fzl)S^bcc)),XYcXd*ef),:]abbyb$Y>>#	s   AC H$D,HHr   N)T)F)__name__
__module____qualname____firstlineno___VALID_URL_BASE	_API_BASEr   rt   r]   _NETRC_MACHINEr   propertyr?   r|   r   r   r   r   r   r   __static_attributes__r   rA   r>   r   r   "   s    ?O'I+K3O8ON `'i^!c%g\"da[0r.p a a>@
*<N,"*rA   r   c                      \ rS rSrSrSrSSSSSS	S
SSS\SSS	SS./SS.SS0S.SSSSSSSSSS\S.
SS0S S!.S"SS#.S$SS#.S%SS#.S&SS#.S'SS#.S(S)SSS*SSS+S,SS-SS.S-S.S/S.S.S*S0S./SS\S1.SS0S.S2S(S)S3S4SS*SSS+S,SS-SS.S-S.S/S.S.S*S0S./SS\\\S5.S4SS6.S7.S8S9S:SS;S<SSS=S>SS<SS./SS\S1.SS0S?/S@.SASS#./rSB rSC r	SD r
SE rSF rSG rSHrgI)JTwitchVodIE   z
twitch:vodal  (?x)
                    https?://
                        (?:
                            (?:(?:www|go|m)\.)?twitch\.tv/(?:[^/]+/v(?:ideo)?|videos)/|
                            player\.twitch\.tv/\?.*?\bvideo=v?|
                            www\.twitch\.tv/[^/]+/schedule\?vodID=
                        )
                        (?P<id>\d+)
                    z0http://www.twitch.tv/riotgames/v/6528877?t=5m10sv6528877r   zLCK Summer Split - Week 6 Day 1zre:^https?://.*\.jpg$i8C  iV_U20150624z
Riot Games	riotgamesi6  r   zLeague of Legends
start_timeend_timetitlewas_live)idextr   r   duration	timestampupload_dateuploaderuploader_id
view_countr   chapterslive_statusskip_downloadTrJ   	info_dictparamsz(http://www.twitch.tv/belkao_o/v/11230755	v11230755Untitled Broadcastif  iU20150816BelkAO_obelkao_o)
r   r   r   r   r   r   r   r  r  r  zHTTP Error 404: Not FoundrJ   r  r	  skipz/http://player.twitch.tv/?t=5m10s&video=v6528877rJ   only_matchingz$https://www.twitch.tv/videos/6528877z+https://m.twitch.tv/beagsandjam/v/247478721z2https://www.twitch.tv/northernlion/video/291940395z)https://player.twitch.tv/?video=480452374z&https://www.twitch.tv/videos/635475444
v635475444i{-  i;^20200529i=  iR  zLegends of RuneterraArt)r   r   r   r   r  r  r   r   r  r  r   r  Storyboardssb0mhtml)r   r   r   r   r   r  r  r   r   r  r  r   r  columnsrows)formatr  )rf   rJ   r  r	  zVOD with single chapterz'https://www.twitch.tv/videos/1536751224v1536751224z8Porter Robinson Star Guardian Stream Tour with LilyPichui   iS(b20220719z;Unable to download JSON metadata: HTTP Error 403: Forbidden)rf   rJ   r  r	  expected_warningsz8https://www.twitch.tv/tangotek/schedule?vodID=1822395420c           	          U R                  USSUS.S.SSUS.S.SSUS.S./S	5      n[        US
SS9nUc  [        SU S3SS9e[        US5      US'   [        USSSS[        14SS9US'   U$ )Nr3   rW   )channelLoginvideoIDr   	variablesr4   F)includePrivater!  r5   z#Downloading stream metadata GraphQL).rQ   video)get_allzVideo  does not existTrD   ).rQ   r%  momentsedges.noder(  .rQ   r%  seekPreviewsURL
storyboard)r   r   r   r   )r=   item_idrQ   r%  s       r>   _download_infoTwitchVodIE._download_info  s    !!!0$&& "H&+& "F&+&& 2)3, T#95I= 6'/!BTRR'.efi*3):[MJTY[l rA   c                    UR                  S5      nUS:X  a  SnOUS:X  a  SnOS nSn[        U5      n/ nUR                  S5      n[        U[        5      (       aN  UR	                  5        H:  u  p[        U	5      n	U	(       d  M  X;  a  M   UR                  U	U" U5      S.5        M<     US	   UR                  S
5      =(       d    SUR                  S5      [        UR                  S5      5      UUR                  S0 5      R                  S5      UR                  S0 5      R                  S5      [        UR                  S5      5      [        UR                  S5      5      USS.$ )Nr   	recordingTrecordedF)smallmediumlargepreviewr   _idr   r  descriptionlengthchanneldisplay_namenamerecorded_atviews)r   r   r8  r   
thumbnailsr  r  r   r  is_liver   )	rb   r   r   r   itemsr   appendr   r   )
r=   infor   r@  
_QUALITIESquality_keyr?  r6  thumbnail_idthumbnail_urls
             r>   _extract_infoTwitchVodIE._extract_info  sG   (#[ Gz!GG1

+
((9%gt$$/6}}+ +M :$1!!("-l";#  0? u+XXg&>*>88M2#DHHX$67$B/33NC88Ir266v>&txx'>?%dhhw&78
 	
rA   c              #   r  #    UR                  S5      (       d  [        US5      nU(       a  SU0v   g US    Hz  n[        UR                  S5      S5      n[        UR                  S5      S5      n[        UR                  S5      5      nUb  Uc  U R	                  SU 3U5        Mp  UXV-   US	.v   M|     g 7f)
Nr(  )gamedisplayNamer   positionMillisecondsi  durationMillisecondsr8  z2Important chapter information missing for chapter r   )rb   r   r   r   report_warning)r=   rC  r-  rK  momentr   r   r<  s           r>   _extract_chaptersTwitchVodIE._extract_chapters  s     xx	""&=>Do%9oF$VZZ0F%GNJ"6::.D#EtLHvzz-89D!X%5##&XY]X^$_ahi(&1  &s   B5B7c                    UR                  S5      =(       d    UnUS   S:w  a  SU 3n[        UR                  S5      5      nS nU(       a5  [        R                  " SU5      (       a  UR                  S5      S:H  nS nOSnUUR                  S	5      =(       d    S
UR                  S5      [	        UR                  S5      5      U R                  U5      [        US [        5      [        US [        5      [        UR                  S5      5      [	        UR                  S5      5      [        U R                  X5      5      USS.$ )Nr   r   vpreviewThumbnailURLz/404_processing_[^.?#]+\.pngbroadcastTypeARCHIVEFr   r  r8  lengthSecondsc                     U S   S   $ )NownerrL  r   xs    r>   <lambda>/TwitchVodIE._extract_info_gql.<locals>.<lambda>  s    '
=0IrA   c                     U S   S   $ )NrZ  loginr   r[  s    r>   r]  r^    s    1W:g3FrA   publishedAt	viewCountT)r   r   r8  r   r?  r  r  r   r  r  r@  r   )rb   r   ru   findallr   r   r   strr   listrQ  )r=   rC  r-  vod_idr   r@  s         r>   _extract_info_gqlTwitchVodIE._extract_info_gql  s   $*7!9\F)> ?@	zz99EE ((?3y@ 	 XXg&>*>88M2#DHH_$=>..y9&I3O"4)FL*488M+BC%dhh{&;<T33DBC
 	
rA   c              #     #    U(       a  U(       d  g U R                  X!SSS9=(       d    / nUR                  S SS9  [        U5      n[        U5       H  u  pg[	        UR                  S5      5      nUR                  S5      n	U	(       a  U(       d  M@  U[        U	5      -  n
S	U 3S
SSSS[        XYS   5      [	        UR                  S5      5      [	        UR                  S5      5      X-  [	        UR                  S5      5      [	        UR                  S5      5      U	 Vs/ s H  n[        X[5      U
S.PM     snS.v   M     g s  snf 7f)Nz$Downloading storyboard metadata JSONFr   c                 H    [        U R                  S5      5      =(       d    S$ )Nwidthr   )r   rb   r[  s    r>   r]  1TwitchVodIE._extract_storyboard.<locals>.<lambda>!  s    AEE'N ; @q @rA   T)keyreversecountimagessbr,  r  noner   rl  heightr  cols)rJ   r   )r   r   r   protocolacodecr   rJ   rl  rt  fpsr  r  	fragments)r^   sortr	   	enumerater   rb   lenr   )r=   r-  storyboard_json_urlr   specbaseisrp  rq  fragment_durationr   s               r>   _extract_storyboardTwitchVodIE._extract_storyboard  s9    2""#6Agot"u{y{ 			@$	O+,dODAg/EUU8_Fu (3v; 6!!X+#  tAY/$QUU7^4%aeeHo6'#AEE&M2&quuV}5 %& %d #4. 1 %&  $&&s   D E"E:Ec           	         U R                  U5      nU R                  U5      nU R                  X25      nU R                  USS5      nU R	                  SX%S   US   U R                  S5      S9nUR                  U R                  X#R                  S5      UR                  S	5      5      5        U R                  U5        XdS
'   [        R                  R                  U5      n[        R                  R                  UR                  5      nSU;   a  [        US   S   5      US'   UR                  S5      b%  S[!        SU S3SU R"                  05      SS./0US'   U$ )Nr%  r   vodr   r   r   )r   r,  r   r   tr   r   r   rechatz https://api.twitch.tv/v5/videos/z	/commentsr7   r_   )rJ   r   	subtitles)	_match_idr.  rg  r   r   	get_paramextendr  rb   r   urllibparseurlparser   r   r   r   r?   )	r=   rJ   rf  r%  rC  access_tokenr   
parsed_urlr   s	            r>   _real_extractTwitchVodIE._real_extract<  s`   $##F+%%e42267DI3360,{2K NN+<= 4 ? 	t//		,8OQUQYQYZdQefgG$!Y\\**3/
%%j&6&67%<!/c
1!>D88K ,+:6()L'O " !D rA   r   N)r   r   r   r   IE_NAME
_VALID_URLint_TESTSr.  rH  rQ  rg  r  r  r   r   rA   r>   r   r      sv   GJ B61#%$& #$ %0 &'
. T
/: :)1#%"%
 T
 ,'* A 6 = D ; 8!$&#% #$ #0 #& $3 #' %"" &19
> T
A#H 7!$&#% #$ #0 #& $3 #' %"" &1? 
D !
I(R *8O$&#% #$ $0 &1%
* T
 \\58 JIgFRB#
J*
>BrA   r   c                 D   [        U [        5      (       d   eU R                  S5      nU(       d  g S[        R	                  5       SU-   SU 3U R                  S5      U R                  S5      [        U R                  S5      5      [        U R                  S5      5      S	.$ )
Nr   url_transparentrT  https://www.twitch.tv/videos/r   rU  rX  rb  )_typer:   r   rJ   r   r   r   r  )r   r   rb   r   r:   r   r   r*  r   s     r>   _make_video_resultr  ^  s    dD!!!!xx~H"$$&Hn.xj9'"XX34!$((?";<!$((;"78	 	rA   c                   6    \ rS rSrSrSSSS.SS./rS	rS
 rSrg)TwitchCollectionIEio  z@https?://(?:(?:www|go|m)\.)?twitch\.tv/collections/(?P<id>[^/]+)z0https://www.twitch.tv/collections/wlDCoH0zEBZZbQwlDCoH0zEBZZbQz'Overthrow Nook, capitalism for childrenr   r      rJ   r  playlist_mincountr+   c                    U R                  U5      nU R                  UU R                  SU0S./S5      S   S   S   nUR                  S5      n/ nUS   S	    Hg  n[	        U[
        5      (       d  M  UR                  S
5      n[	        U[
        5      (       d  MB  [        U5      nU(       d  MV  UR                  U5        Mi     U R                  XRUS9$ )NcollectionIDr"  zDownloading collection GraphQLr   rQ   
collectionr   rA  r)  r*  playlist_idplaylist_title)	r  r   _OPERATION_NAMErb   r   r   r  rB  playlist_result)	r=   rJ   collection_idr  r   entriesedger*  r%  s	            r>   r   TwitchCollectionIE._real_extract}  s    s+''!%!5!5,m<  -.
 /01
 289
 :FG
 w'w'0DdD))88F#DdD))&t,Euu% 1 ##u $ F 	FrA   r   N)	r   r   r   r   r  r  r  r  r   r   rA   r>   r  r  o  s6    TJ B">
   F *OFrA   r  c                       \ rS rSrSrS rSrg)TwitchPlaylistBaseIEi  d   c           	   '   D  ^#    SnU R                   " U/UQ76 nU R                   S3m[        R                  " S5       GH\  nUR	                  5       nU R
                  US'   U(       a  X6S'   U R                  UU R                  US./SU R                   SU 3S	S
9nU(       d    g[        UU4S j[        5      nU(       d    gU H  n	[        U	[        5      (       d  M  U	R                  S5      U R                  :w  a  M;  U	R                  S5      n
[        U
[        5      (       d  Mc  U
R                  S5      U R                  :w  a  M  U R                  U
5      nU(       d  M  U	R                  S5      nUv   M     U(       a  [        U[         5      (       a  GM]    g   g7f)z
Subclasses must define _make_variables() and _extract_entry(),
as well as set _OPERATION_NAME, _ENTRY_KIND, _EDGE_KIND, and _NODE_KIND
Nr  r   limitcursorr"  r   zs GraphQL page Frj  c                 &   > U S   S   S   T   S   $ )Nr   rQ   userr)  r   )r\  entries_keys    r>   r]  /TwitchPlaylistBaseIE._entries.<locals>.<lambda>  s    !VV 4[ A' JrA   
__typenamer*  )_make_variables_ENTRY_KIND	itertoolsrp  copy_PAGE_LIMITr   r  
_NODE_KINDr   re  r   r   rb   
_EDGE_KIND_extract_entryrd  )r=   channel_nameargsr  variables_commonpage_numr#  rd   r)  r  r*  entryr  s               @r>   _entriesTwitchPlaylistBaseIE._entries  s    
 //DtD))*!,!*H(--/I!%!1!1Ig&,(#%%%)%9%9!*   t/xjI & D JDRE!$--88L)T__<xx'!$--88L)T__<++D15!XXh/FK  FC!8!8C +s   EF #3F F r   N)r   r   r   r   r  r  r   r   rA   r>   r  r    s    K)rA   r  c                   4    \ rS rSrSrSrSrSr\S 5       r	Sr
g)	TwitchVideosBaseIEi  r,   r%  	VideoEdgeVideoc                 *    U UUR                  5       S.$ )N)channelOwnerLoginrV  	videoSort)upper)r  broadcast_typerz  s      r>   r  "TwitchVideosBaseIE._make_variables  s     ".+
 	
rA   r   N)r   r   r   r   r  r  r  r  staticmethodr  r   r   rA   r>   r  r    s(    3OKJJ
 
rA   r  c                   Z  ^  \ rS rSrSrSSSS.SS.S	SS
S.SS.SSSS.SS.SSSS.SS.SSSS.SS.SSSS.SS.SSS.SSS.SSS./	r\R                  " SSS /5      r\" S!S"5      r	\" S#S$5      \" S%S&5      \" S'S(5      \" S)S*5      \	S+.r
S,r\S-S..r\U 4S/ j5       r\S0 5       rS1 rS2rU =r$ )3TwitchVideosIEi  zGhttps?://(?:(?:www|go|m)\.)?twitch\.tv/(?P<id>[^/]+)/(?:videos|profile)z0https://www.twitch.tv/spamfish/videos?filter=allspamfishz$spamfish - All Videos sorted by Dater  i  r  z;https://www.twitch.tv/spamfish/videos?filter=all&sort=viewsz'spamfish - All Videos sorted by Populari  z5https://www.twitch.tv/spamfish/videos?filter=archivesz)spamfish - Past Broadcasts sorted by Date   z7https://www.twitch.tv/spamfish/videos?filter=highlightsz$spamfish - Highlights sorted by Datei  z>https://www.twitch.tv/esl_csgo/videos?filter=uploads&sort=timeesl_csgoz!esl_csgo - Uploads sorted by Date   z;https://www.twitch.tv/spamfish/videos?filter=past_premieresz(spamfish - Past Premieres sorted by Dater   z)https://www.twitch.tv/spamfish/videos/allTr  z'https://m.twitch.tv/spamfish/videos/allz%https://www.twitch.tv/spamfish/videos	BroadcasttypelabelNz
All VideosrW  zPast Broadcasts	HIGHLIGHT
HighlightsUPLOADUploadsPAST_PREMIEREzPast Premieres)archives
highlightsuploadspast_premieresallDatePopular)timer>  c                 p   >^ [        U4S j[        [        4 5       5      (       a  S$ [        TU ]  T5      $ )Nc              3   D   >#    U  H  oR                  T5      v   M     g 7fNsuitabler   ierJ   s     r>   r   *TwitchVideosIE.suitable.<locals>.<genexpr>$  s#      0 3/B{{3'' 3/    F)anyTwitchVideosClipsIETwitchVideosCollectionsIEsuperr  clsrJ   	__class__s    `r>   r  TwitchVideosIE.suitable!  sE      0'-3/ 0 0 0  	, W%c*		,rA   c                     [        U 5      $ r  )r  )r*  s    r>   r  TwitchVideosIE._extract_entry)  s    !$''rA   c                    U R                  U5      n[        U5      nUR                  SS/5      S   nUR                  SS/5      S   nU R                  R                  X@R                  5      nU R                  U R                  X&R                  U5      UU SUR                   SU R                  R                  XPR                  5       3S9$ )	Nfilterr  r   rz  r  z - z sorted by r  )r  r   rb   _BROADCASTS_DEFAULT_BROADCASTr  r  r  r  
_SORTED_BY_DEFAULT_SORTED_BY)r=   rJ   r  qsvideo_filterrz  	broadcasts          r>   r  TwitchVideosIE._real_extract-  s    ~~c*c]vvh03vvfvh'*$$((7N7NO	##MM,=$.IOO#4 5!__007N7NOPR	 $ T 	TrA   r   )r   r   r   r   r  r  collections
namedtupler  r  r  r  r  classmethodr  r  r  r  r   __classcell__r  s   @r>   r  r    s}   [J B;
 ! M>
 ! G@
   I;
 ! P8
  M?
  ; 9 7m9Fv &&{VW4EFI"46i):;\:Xy1#O5EF!K  "J
 , , ( (T TrA   r  c                       \ rS rSrSrSSSS.SS.S	S
S./r\R                  " SSS/5      r\" SS5      r	\" SS5      \	\" SS5      \" SS5      S.r
SrSrSrSrSr\S 5       r\S 5       rS rSrg )!r  i;  z[https?://(?:(?:www|go|m)\.)?twitch\.tv/(?P<id>[^/]+)/(?:clips|videos/*?\?.*?\bfilter=clips)z<https://www.twitch.tv/vanillatv/clips?filter=clips&range=all	vanillatvzvanillatv - Clips Top Allr  r   r  z=https://www.twitch.tv/dota2ruhub/videos?filter=clips&range=7dTr  Clipr   r  	LAST_WEEKzTop 7DLAST_DAYzTop 24H
LAST_MONTHzTop 30DALL_TIMEzTop All)24hr7d30dr     r-   clipClipEdgec                     U SU0S.$ )Nr   )r`  criteriar   )r  channel_filters     r>   r  #TwitchVideosClipsIE._make_variables]  s     ".
 	
rA   c                    [        U [        5      (       d   e[        U R                  S5      5      nU(       d  g S[        R                  5       U R                  S5      UU R                  S5      U R                  S5      [        U R                  S5      5      [        U R                  S5      5      [        U R                  S5      5      U R                  S	5      S
.
$ )NrJ   r  r   r   thumbnailURLdurationSeconds	createdAtrb  language)
r  r:   r   rJ   r   r   r   r   r  r#  )	r   r   r   rb   TwitchClipsIEr:   r   r   r   )r*  clip_urls     r>   r  "TwitchVideosClipsIE._extract_entryf  s    $%%%%txx/&#**,((4.XXg&.1%dhh/@&AB*488K+@A%dhh{&;<,
 	
rA   c                 "   U R                  U5      n[        U5      nUR                  SS/5      S   nU R                  R                  X@R                  5      nU R                  U R                  X%R                  5      UU SUR                   3S9$ )Nranger  r   z	 - Clips r  )	r  r   rb   _RANGE_DEFAULT_CLIPr  r  r   r  )r=   rJ   r  r  
date_ranger  s         r>   r  !TwitchVideosClipsIE._real_extracty  s    ~~c*c]VVGdV,Q/
{{z+=+=>##MM,4$*^9TZZLA $ C 	CrA   r   N)r   r   r   r   r  r  r	  r
  r  r*  r)  r  r  r  r  r  r  r  r  r  r   r   rA   r>   r  r  ;  s    oJ N0
  OF !!&8W*=>Dh/MZ+L),J	*	F K(OKJJ
 
 
 
$CrA   r  c                   r    \ rS rSrSrSSSS.SS.S	S
SS.SS./rSrSrSrSr	\
S 5       r\
S 5       rS rSrg)r  i  zWhttps?://(?:(?:www|go|m)\.)?twitch\.tv/(?P<id>[^/]+)/videos/*?\?.*?\bfilter=collectionsz8https://www.twitch.tv/spamfish/videos?filter=collectionsr  zspamfish - Collectionsr     r  z:https://www.twitch.tv/monstercat/videos?filter=collections
monstercatzmonstercat - Collectionsr  r/   r  CollectionsItemEdge
Collectionc                 
    SU 0$ )N
ownerLoginr   )r  s    r>   r  )TwitchVideosCollectionsIE._make_variables  s     ,
 	
rA   c                 p   [        U [        5      (       d   eU R                  S5      nU(       d  g S[        R	                  5       USU 3U R                  S5      U R                  S5      [        U R                  S5      5      [        U R                  S5      5      [        U R                  S5      5      S	.	$ )
Nr   r  z"https://www.twitch.tv/collections/r   r   rX  	updatedAtrb  )	r  r:   r   rJ   r   r   r   r   r  )r   r   rb   r  r:   r   r   r   )r*  r  s     r>   r  (TwitchVideosCollectionsIE._extract_entry  s    $%%%%&(//17GXXg&.1%dhh&?@*488K+@A%dhh{&;<

 
	
rA   c                 j    U R                  U5      nU R                  U R                  U5      UU S3S9$ )Nz - Collectionsr  )r  r  r  )r=   rJ   r  s      r>   r  'TwitchVideosCollectionsIE._real_extract  s@    ~~c*##MM,'\*^>: $ < 	<rA   r   N)r   r   r   r   r  r  r  r  r  r  r  r  r  r  r   r   rA   r>   r  r    s    kJ J-
  L/
  F" 2OK&JJ
 

 
 
"<rA   r  c                      ^  \ rS rSrSrSrSSSSSS	S
SSSS\S.SS
0SS.SS
S.SS
S.SS
S.SS
S.SSSSSS
SSSSSS SS!.SS"0S#./rS$r\	U 4S% j5       r
\S& 5       rS' rS(rU =r$ ))TwitchStreamIEi  ztwitch:streama  (?x)
                    https?://
                        (?:
                            (?:(?:www|go|m)\.)?twitch\.tv/|
                            player\.twitch\.tv/\?.*?\bchannel=
                        )
                        (?P<id>[^/#?]+)
                    zhttp://www.twitch.tv/shroomztv12772022048	shroomztvr   z;re:^ShroomzTV [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$zGH1Z1 - lonewolfing with ShroomzTV | A3 Battle Royale later - @ShroomzTVTieT20150122	ShroomzTV)r   
display_idr   r   r8  r@  r   r   r  r  r  r  zUser does not existr  z+http://www.twitch.tv/miracle_doto#profile-0r  z)https://player.twitch.tv/?channel=lotsofszhttps://go.twitch.tv/foodzhttps://m.twitch.tv/foodz https://www.twitch.tv/monstercat40500071752r/  zre:Monstercatz$md5:0945ad625e615bc8f0469396537d87d9ic20230222
Monstercatr@  zre:https://.*.jpg)r   r@  r   r8  r@  r   r   r  r  r  r   r   
Livestreamr  r   c           	         >^ [        U4S j[        [        [        [        [
        [        4 5       5      (       a  S$ [        TU ]!  T5      $ )Nc              3   D   >#    U  H  oR                  T5      v   M     g 7fr  r  r  s     r>   r   *TwitchStreamIE.suitable.<locals>.<genexpr>   s#      $ 3#B{{3'' 3#r  F)	r  r   r  r  r  r  r$  r  r  r  s    `r>   r  TwitchStreamIE.suitable  sQ      $&"'-!3# $ $ $  	, W%c*	,rA   c           
         [        U [        5      (       a  U R                  S5      (       d  g U S   nS[        R	                  5       SU-   SU 3U R                  S5      [        U R                  S5      5      =(       d    SS.$ )	Nr   rJ   rT  r  r   ra  r   )r  r:   r   rJ   r   r   )r   r   rb   r   r:   r   r  s     r>   r  TwitchStreamIE._extract_entry	  ss    $%%TXXd^^:!((*.28*=XXg&*488M+BCHq
 	
rA   c                 V   U R                  U5      R                  5       nU R                  USSU0S.SUSSSSSS.S.S	S
U0S./S5      nUS   S   S   nU(       d  [        U S3SS9eUS   nU(       d	  [	        US9e[        UR                  S5      5      nU R                  S5      (       aq  U R                  U S35        [        U R                  US S5      S 5      nU(       a)  UR                  S5      U=(       d    [        S5      :  a  U$ U R                  SUS9  U R                  USS5      nUR                  S5      =(       d    Un	U R                  SX(S   US   5      n
U R!                  U
5        UR                  S5      n[#        US  [$        5      =(       d    0 nUR                  S!5      n[#        US" [&        5      n[)        [#        US# [&        5      5      nU=(       d    UnUR                  S$5      nUS%;   a	  US&U S'3-  nU	UUUU R+                  U5      UUUUU
US(:H  S).$ )*Nr0   r   r"  r1   rW   FT)r:  clipSlugisClipisLiveisVodOrCollectionvodIDr2   r`  zDownloading stream GraphQLr   rQ   r  r'  rD   stream)r   r"  r   z,: Extracting VOD to download live from startr  r   infz9Unable to extract the VOD associated with this livestreamchannelNamer   zapi/channel/hlsr   r   viewersc                     U S   S   S   $ )Nr   rQ   r  r   r[  s    r>   r]  .TwitchStreamIE._real_extract.<locals>.<lambda>M  s    1ff)=rA   rL  c                     U S   S   $ )NbroadcastSettingsr   r   r[  s    r>   r]  rV  P  s    q!45g>rA   c                 $    U S   S   S   S   S   $ )Nr   rQ   r  rQ  previewImageURLr   r[  s    r>   r]  rV  S  s    1Q4</9:KLrA   r  )rerunlivez ()r\  )r   r@  r   r8  r?  r  r  r   r  r   r@  )r  lowerr   r   r   r   rb   r  	to_screenr   r  popfloatrO  r   r   r   r   r   rd  r   r   )r=   rJ   r  gqlr  rQ  r   r  r  	stream_idr   r  sq_userr  r8  r   r   stream_types                     r>   r  TwitchStreamIE._real_extract  s   ~~c*002  !1,l; ":+ "#").
 "7%|4" )%*( 1vf~f% .04A A h|44%fjj&=>	>>+,,NNl^+WXY|T6BDIE;/I4MuNKVb   d 22(M3 JJt$4	33|'-BLQ\D]_G$ZZ	*
#=tDJ;;}->E  L! 	 (Ljj(++r+a((E &&..y9 '"$"f,
 	
rA   r   )r   r   r   r   r  r  r  r  r  r  r  r  r  r  r   r  r  s   @r>   r;  r;    s   GJ 0%Rd#%#&
 T
 &'* = ; + * 2&$A#%$'$,
 \
!A3Fh K	, 	, 
 
P
 P
rA   r;  c            
       6   \ rS rSrSrSrSS0 SS_SS	_S
S_SS_SS_S\_SS_SS_SS_SS/_SS_SS_SS_S\_SS _S!S"_S#.S$S%0 SS&_SS'_S
S_SS(_SS)_S\_SS_SS*_SS+_SS,/_SS,_SS-_SS._S\_SS/_S!S0_S1S2/_S#.S3S.S4.S5S.S4.S6S.S4.S7S.S4.S8S.S4.S9S.S4./rS: rS;r	g<)=r$  ij  ztwitch:clipsa2  (?x)
                    https?://
                        (?:
                            clips\.twitch\.tv/(?:embed\?.*?\bclip=|(?:[^/]+/)*)|
                            (?:(?:www|go|m)\.)?twitch\.tv/(?:[^/]+/)?clip/
                        )
                        (?P<id>[^/?#&]+)
                    z0https://clips.twitch.tv/FaintLightGullWholeWheat 761769e1eafce0ffebfb4089cb3847cdr   	396245304r@  FaintLightGullWholeWheatr   r   r   z'EA Play 2016 Live from the Novo Theatrer       r  r   zre:^https?://.*\.jpgr   i]Wr   20160612creatorsEAr:  
channel_id25163635channel_is_verifiedFchannel_follower_countr  stereotype_r  43566419)rJ   md5r  zLhttps://www.twitch.tv/xqc/clip/CulturedAmazingKuduDatSheffy-TiZ_-ixAGYR3y2Uy e90fe616b36e722a8cfa562547c543f0
3207364882z-CulturedAmazingKuduDatSheffy-TiZ_-ixAGYR3y2UyzA day in the life of xQc<   iog20250325xQc71092938T
okSTFUdude	744085721
categorieszJust Chattingz;https://clips.twitch.tv/rflegendary/UninterestedBeeDAESuppyr  zDhttps://www.twitch.tv/sergeynixon/clip/StormyThankfulSproutFutureManzEhttps://clips.twitch.tv/embed?clip=InquisitiveBreakableYogurtJebaitedzChttps://m.twitch.tv/rossbroadcast/clip/ConfidentBraveHumanChefFrankzDhttps://go.twitch.tv/rossbroadcast/clip/ConfidentBraveHumanChefFrankz1https://m.twitch.tv/clip/FaintLightGullWholeWheatc                 6   U R                  U5      nU R                  USSU0S./S5      S   S   S   nU(       d
  [        SS	S
9eUS   S   US   S   S.n[        USS[        145      =(       d    0 n[        USS[        145      =(       d    0 n/ n[        UR                  S5      5      nUR                  [        USS S[        US914S[        14S[        14S[
        14[        U5      1S.45      5        [        UR                  S5      5      n	[        USS 45       Hq  n
UR                  [        U
S   U5      [        SU
R                  S5      5      [        U
R                  S5      5      [        U
R                  S5      5      U	SS.5        Ms     / n[        UR                  S5      5      nU(       a  UR                  SUSS.5        [        UR                  S5      5      =n(       a  UR                  SUS S.5        [        UR                  S5      5      nU(       a  X:w  a  UR                  S!USS.5        U R                  S"US    S#   S$S S%9nUR                  S&5      =(       d    UU(       a  [!        X5      /OS UUUS'.[        US([        14S)[        14S*[        14S+["        14S,S-[        1[$        [&        4S,S-[        14S,S&[        14S,S.S/[        14S,S0[(        14S1S-[        14S1S&[        14S2S-[        1[$        [&        [$        4S3.5      E$ )4Nr.   slugr"  zDownloading clip GraphQLr   rQ   r  z This clip is no longer availableTrD   playbackAccessTokenr   r   )r   r   assetsr   aspectRatiovideoQualitiesc                     [        US   5      $ N	sourceURLr   _rT  s     r>   r]  -TwitchClipsIE._real_extract.<locals>.<lambda>      S^_`al_mSnrA   r  r   r   	frameRate)rJ   r   rt  rx  aspect_ratioc                     [        US   5      $ r  r  r  s     r>   r]  r    r  rA   portrait)rJ   r   rt  rx  r  r   r   rK   )r   rJ   r   r3  z%7C(\d+)(?:-\d+)?.mp4rJ   zold id)rK   r   )r   _old_archive_idsr@  r   r?  r   r!  rb  r"  broadcasterrL  	followers
totalCount	isPartnercuratorrK  )r   r   r  r   rm  r:  ro  rr  rq  r  r  r~  )r  r   r   r   r   r   rb   r  r   rd  r   r   rB  r   r   r\   r   r   r   r  bool)r=   rJ   r  r  access_queryasset_defaultasset_portraitr   default_aspect_ratioportrait_aspect_ratior   r?  thumb_asset_default_urlthumb_asset_portrait_urlthumb_default_urlold_ids                   r>   r  TwitchClipsIE._real_extract  s   ~~c"!!!8$d^  '(
 )*+
 ,23
 4:;  2TC C -.{;/09
 %THa$+@AGR%dXq4&,ABHb,]->->}-MN|M4DFn"2"F!GH#cU+ ;-0-1"#789q
 4  	 !.n.@.@.O P">4DFn3opFNN'{(;\J*:vzz)7LM%fjj&;<$VZZ%<= 5  q 
"-m.?.?.O"P". 
 (3>3E3En3U'VV#V /  
 ((@A!2!M(   ##$<gbk%>PRZdh#i ((4.(DCI!> ?t$
 4!C5).>*[M:)M?;*MC5&#N)=3%@,dSE:+8+|VaUb*c(5{TF'K&u= )4#7%}seVS&Q" 
 	
rA   r   N)
r   r   r   r   r  r  r  r  r  r   r   rA   r>   r$  r$  j  s(   GJ B1
+
4
 5
 >	

 
 #
 0
 
 :
 
 t
 *
 "5
 %c
 
  :!
, ^1
,
I
 5
 /	

 
 #
 0
 
 :
 
 u
 *
 "4
 %c
 
  ;!
" ?+#
0 M
 V W U V Cw>F@U
rA   r$  )-r	  r  r_   r   ru   urllib.parser  commonr   networking.exceptionsr   utilsr   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   utils.traversalr   r   r   r   r  r  r  r  r  r  r  r;  r$  r   rA   r>   <module>r     s        	  ! -     * 2G= GTo, od""F "FJ,< ,^
- 
fT' fTRFC. FCR5< 4 5<pk
' k
\`
L `
rA   