a
    h                     @   sX  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
 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mZmZ ddlm Z m!Z! G dd	 d	eZ"G d
d de"Z#dd Z$G dd de"Z%G dd de"Z&G dd de&Z'G dd de'Z(G dd de&Z)G dd de&Z*G dd de'Z+G dd de"Z,dS )    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                   @   s   e Zd ZdZdZdZdZdZdZddd	d
ddddddddZ	e
dd Zdd Zdd Zd&ddZd'ddZdd Zd d! Zd(d#d$Zd%S ))TwitchBaseIEz&https?://(?:(?:www|go|m)\.)?twitch\.tvzhttps://api.twitch.tvzhttps://usher.ttvnw.netzhttps://www.twitch.tv/loginz https://passport.twitch.tv/loginZtwitchZ@27111f1b382effad0b6def325caef1909c733fe6a4fbabf54f8d491ef2cf2f14Z@a937f1d22e269e39a03b509f65a7490f9fc247d7f83d6ac1421523e3b68042cbZ@b73ad2bfaecfd30a9e6c28fada15bd97032c83ec77a0440766a56fe0bd632777Z@e0a46b287d760c6890a39d1ccd736af5ec9479a267d02c710e9ac33326b651d2Z@447aec6a0cc1e8d0a8d7732d47eb0762c336a2294fdb009e9c9d854e49d484b9Z@a647c2a13599e5991e175155f798ca7f1ecddde73f7f341f39009c14dbf59962Z@e1edae8122517d013405f237ffcc124515dc6ded82480a88daef69c83b53ac01Z@3006e77e51b128d838fa4e835723ca4dc9a05c5efd4466c1085215c6e437e65cZ@49b5b8f268cdeb259d75b58dcb0c1a748e3b575003448a2333dc5cdafd49adadZ@8d2793384aac3773beab5e59bd5d6f585aedb923d292800119e03d40cd0f9b41Z@07e99e4d56c5a7c67117a154777b0baf85a5ffefa393b213f4bc712ccaf85dd6)CollectionSideBarFilterableVideoTower_VideosClipsCards__UserShareClipRenderStatusChannelCollectionsContentStreamMetadataComscoreStreamingQueryVideoPreviewOverlayVideoMetadata$VideoPlayer_ChapterSelectButtonVideo"VideoPlayer_VODSeekbarPreviewVideoc                 C   s   | j ddgdddd S )N	client_idZue6666qo983tsx6so1t0vnawi233waZTwitchT)ie_keyZ	casesenser   )Z_configuration_arg)self r*   L/mnt/pikpak/tmp/myenv/lib/python3.9/site-packages/yt_dlp/extractor/twitch.py
_CLIENT_ID9   s
    
zTwitchBaseIE._CLIENT_IDc                    s   dd   fdd} jd d\}}d|v r> t| |||d||jd\}}|sbd S td	|d urd
}|||d|dd d S )Nc                 S   s   t d|  ddd S )NzUnable to login. Twitch said: Texpected)r   )messager*   r*   r+   fail?   s    
z)TwitchBaseIE._perform_login.<locals>.failc                    s    | }|| |j}jd| djdd}t||}|ddd}j|d |t|	 |dd	}t
|d
}	|	r| |	 d|ddv rdS t||dp|d }
j|
d d|dS )Nz&<form[^>]+action=(["\'])(?P<url>.+?)\1zpost urlurl)defaultgroupzhttps://www.twitch.tvtext/plain;charset=UTF-8)ZRefererZOriginContent-Typei  )dataheadersZexpected_status)errorZerror_description
error_codezAuthenticated successfullyr/    )NNredirectZredirect_pathzDownloading login redirect page)r7   )Z_hidden_inputsupdater1   _search_regex_LOGIN_POST_URLr   _download_jsonjsondumpsencoder
   get_download_webpage_handle)pageZurlhnoter6   formpage_urlZpost_urlr7   responser8   Zredirect_urlr0   r)   r*   r+   
login_stepC   s:    



z/TwitchBaseIE._perform_login.<locals>.login_stepzDownloading login pageZblacklist_messagez
Logging in)usernamepasswordr'   z$(?i)<form[^>]+id="two-factor-submit"ztwo-factor authentication tokenzSubmitting TFA tokentrue)Zauthy_tokenZremember_2fa)rD   _LOGIN_FORM_URLr	   r,   researchZ_get_tfa_info)r)   rL   rM   rK   Z
login_pagehandleZredirect_pageZ	tfa_tokenr*   rJ   r+   _perform_login>   s,    !
zTwitchBaseIE._perform_loginc              	   C   s\   zt dd |D }d|d< W n8 tyV   |D ] }d|d v r0|ddd q0Y n0 d S )	Nc                 s   s   | ]}|d  dkr|V  qdS )	format_idSourceNr*   ).0fr*   r*   r+   	<genexpr>       z.TwitchBaseIE._prefer_source.<locals>.<genexpr>
   qualityz	/chunked/r1   rU   )r[   format_note)nextStopIterationr<   )r)   formatssourcerW   r*   r*   r+   _prefer_source~   s    zTwitchBaseIE._prefer_sourceTc                 C   sN   d| j d}| dd}|r.d|j |d< | jd||t| ||dS )	Nr4   )r5   z	Client-IDhttps://gql.twitch.tv
auth-tokenzOAuth Authorizationzhttps://gql.twitch.tv/gql)r6   r7   fatal)r,   _get_cookiesrC   r   r?   r@   rA   rB   )r)   video_idopsrF   re   r7   Zgql_authr*   r*   r+   _download_base_gql   s    zTwitchBaseIE._download_base_gqlc                 C   s4   |D ] }dd| j |d  di|d< q| |||S )NZpersistedQueryr   operationName)versionZ
sha256Hash
extensions)_OPERATION_HASHESri   )r)   rg   rh   rF   re   opr*   r*   r+   _download_gql   s    
zTwitchBaseIE._download_gqlc                 C   s:   | d}dd|||f i}|  ||d| dd | S )NZPlaybackAccessTokenquerya?  {
              %s(
                %s: "%s",
                params: {
                  platform: "web",
                  playerBackend: "mediaplayer",
                  playerType: "site"
                }
              )
              {
                value
                signature
              }
            }Downloading z access token GraphQLr6   )ri   )r)   rg   Z
token_kind
param_namemethodrh   r*   r*   r+   _download_access_token   s    

z#TwitchBaseIE._download_access_tokenc                 C   s$   |r t dd|ddd|igS d S )Nz\d+x\d+(\.\w+)($|(?=[?#]))z0x0\g<1>r   r1   
preferencer1   )rP   sub)r)   	thumbnailr*   r*   r+   _get_thumbnails   s    zTwitchBaseIE._get_thumbnailsFc                 C   s  zH| j | j d| d| d|ddddtddddd	d||d

d}W n ty$ } zt|jtr|jjdks|jj	
ddkr t|jj	 tjhdthfpi }|ddv rd}	| ddrtd|	 dd| d|	  tdd|dd }
rt|
dd W Y d }~n
d }~0 0 |D ]d}|drd|d drd|di dd dgi |r*|di d!d"d#gi d|d$< q*|S )%N/z.m3u8mp4rN   i@B i ZwebZ	twitchwebzav1,h265,h264)
Zallow_sourceZallow_audio_onlyZallow_spectrepplatformZplayerZsupported_codecsZplaylist_include_frameratesigtokenrp   i  zcontent-typezapplication/jsonr   r9   )Zvod_manifest_restrictedZunauthorized_entitlementsz&access to this subscriber-only contentrb   rc   zYour account does not have Tr-   z,You must be logged into an account that has r8   z: )	from_dictdelimvcodecZav01Zdownloader_optionsZffmpeg_args_outz-fZffmpeg_argsz-live_start_index0Zis_from_start)Z_extract_m3u8_formats_USHER_BASErandomrandintr   
isinstancecauser   statusrI   
get_headerr   readr@   loadsdictrC   rf   Zraise_login_requiredr   
startswith
setdefaultr<   )r)   pathrg   r   	signaturelive_from_startr_   e
error_infoZ
common_msg	error_msgfmtr*   r*   r+   _extract_twitch_m3u8_formats   sN    



"z)TwitchBaseIE._extract_twitch_m3u8_formatsN)T)T)F)__name__
__module____qualname__Z_VALID_URL_BASEZ	_API_BASEr   rO   r>   Z_NETRC_MACHINErm   propertyr,   rS   ra   ri   ro   rt   ry   r   r*   r*   r*   r+   r   "   s6   
@


r   c                   @   s  e Zd ZdZdZddddddd	d
ddedddddgddddiddddddddddded
ddidd d!dd"d#dd"d$dd"d%dd"d&dd"d'd(ddd)ddd*d+dd,ddd,d-d.dd-d)d/dgdded0ddidd1d'd(d2d3dd)ddd*d+dd,ddd,d-d.dd-d)d/dgddeeed4d3dd5d6d7d8d9dd:d;ddd<d=dd;ddgdded0ddid>gd?d@dd"gZdAdB ZdCdD ZdEdF Z	dGdH Z
dIdJ ZdKdL ZdMS )NTwitchVodIEz
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=5m10sZv6528877r{   zLCK Summer Split - Week 6 Day 1zre:^https?://.*\.jpg$i8C  iV_UZ20150624z
Riot GamesZ	riotgamesi6  r   zLeague of Legends
start_timeZend_timetitlewas_live)idextr   rx   duration	timestampupload_dateuploaderuploader_id
view_countr   chapterslive_statusskip_downloadTr1   	info_dictparamsz(http://www.twitch.tv/belkao_o/v/11230755Z	v11230755Untitled Broadcastif  iUZ20150816ZBelkAO_oZbelkao_o)
r   r   r   rx   r   r   r   r   r   r   zHTTP Error 404: Not Foundr1   r   r   skipz/http://player.twitch.tv/?t=5m10s&video=v6528877r1   Z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/635475444Z
v635475444i{-  i;^Z20200529i=  iR  zLegends of RuneterraZArt)r   r   r   r   r   r   r   r   r   r   rx   r   ZStoryboardsZsb0mhtml)r   rT   r   r   r   r   r   r   r   r   r   rx   r   columnsrows)formatr   )rF   r1   r   r   zVOD with single chapterz'https://www.twitch.tv/videos/1536751224Zv1536751224z8Porter Robinson Star Guardian Stream Tour with LilyPichui   iS(bZ20220719z;Unable to download JSON metadata: HTTP Error 403: Forbidden)rF   r1   r   r   Zexpected_warningsz8https://www.twitch.tv/tangotek/schedule?vodID=1822395420c              	   C   s   |  |dd|dddd|dddd|ddgd	}t|d
dd}|d u rbtd| dddt|d|d< t|ddddthfdd|d< |S )Nr$   r:   )channelLoginvideoIDrj   	variablesr%   F)ZincludePrivater   r&   z#Downloading stream metadata GraphQL).r6   video)get_allzVideo  does not existTr-   ).r6   r   momentsedges.noder   .r6   r   ZseekPreviewsURL
storyboard)ro   r   r   r   )r)   item_idr6   r   r*   r*   r+   _download_info  s8    
zTwitchVodIE._download_infoc           
      C   s   | d}|dkrd}n|dkr&d}nd }d}t|}g }| d}t|tr| D ]4\}}	t|	}	|	slqV||vrvqV||	||d qV|d	 | d
pd| dt| d|| di  d| di  dt| dt| d|ddS )Nr   Z	recordingTZrecordedF)smallZmediumZlargepreviewru   Z_idr   r   descriptionlengthchannelZdisplay_namenameZrecorded_atviews)r   r   r   r   
thumbnailsr   r   r   r   is_liver   )	rC   r   r   r   itemsr   appendr   r   )
r)   infor   r   Z
_QUALITIESZquality_keyr   r   Zthumbnail_idZthumbnail_urlr*   r*   r+   _extract_info  sB    



zTwitchVodIE._extract_infoc                 c   s   | ds&t|d}|r"d|iV  d S |d D ]h}t| dd}t| dd}t| d}|d u sp|d u r| d| | q.||| |d	V  q.d S )
Nr   )gamedisplayNamer   ZpositionMillisecondsi  ZdurationMillisecondsr   z2Important chapter information missing for chapter r   )rC   r   r   r   report_warning)r)   r   r   r   Zmomentr   r   r   r*   r*   r+   _extract_chapters  s     


zTwitchVodIE._extract_chaptersc                 C   s   | dp|}|d dkr$d| }t| d}d }|r^td|rZ| ddk}d }nd}|| d	pld
| dt| d| |t|dd tt|dd tt| dt| dt	| 
|||ddS )Nr   r   vpreviewThumbnailURLz/404_processing_[^.?#]+\.pngbroadcastTypeARCHIVEFr   r   r   lengthSecondsc                 S   s   | d d S )Nownerr   r*   xr*   r*   r+   <lambda>  rY   z/TwitchVodIE._extract_info_gql.<locals>.<lambda>c                 S   s   | d d S )Nr   loginr*   r   r*   r*   r+   r     rY   publishedAt	viewCountT)r   r   r   r   r   r   r   r   r   r   r   r   )rC   r   rP   findallr   ry   r   strr   listr   )r)   r   r   vod_idrx   r   r*   r*   r+   _extract_info_gql  s.    
zTwitchVodIE._extract_info_gqlc           	      #   s   |r|sd S | j ||dddp g }|jdd dd t| t|D ]\}}t|d}|d	}|rD|snqD|t| d
| dddddt |d t|dt|d|| t|dt|d fdd|D dV  qDd S )Nz$Downloading storyboard metadata JSONFre   c                 S   s   t | dpdS )Nwidthr   )r   rC   r   r*   r*   r+   r   !  rY   z1TwitchVodIE._extract_storyboard.<locals>.<lambda>T)keyreversecountimagesZsbr   r   noner   r   heightr   colsc                    s   g | ]}t  |d qS ))r1   r   )r   )rV   r   baseZfragment_durationr*   r+   
<listcomp>6  s   z3TwitchVodIE._extract_storyboard.<locals>.<listcomp>)rT   r\   r   protocolZacodecr   r1   r   r   fpsr   r   	fragments)r?   sortr   	enumerater   rC   lenr   )	r)   r   Zstoryboard_json_urlr   specisr   r   r*   r   r+   _extract_storyboard  s6    
zTwitchVodIE._extract_storyboardc           	   	   C   s   |  |}| |}| ||}| |dd}| jd||d |d | dd}|| ||d|d	 | 	| ||d
< t
j|}t
j|j}d|v rt|d d |d< |dd urdtd| dd| jiddgi|d< |S )Nr   r   Zvodr   r   r   )r   r   r   r_   tr   r   r   Zrechatz https://api.twitch.tv/v5/videos/z	/commentsr'   r@   )r1   r   Z	subtitles)	_match_idr   r   rt   r   	get_paramextendr   rC   ra   urllibparseurlparser   rp   r   r   r,   )	r)   r1   r   r   r   access_tokenr_   
parsed_urlrp   r*   r*   r+   _real_extract<  s4    

 


zTwitchVodIE._real_extractN)r   r   r   IE_NAME
_VALID_URLint_TESTSr   r   r   r   r   r  r*   r*   r*   r+   r      s2  $")  *!%!r   c                 C   sd   t | tsJ | d}|s d S dt d| d| | d| dt| dt| dd	S )
Nr   url_transparentr   https://www.twitch.tv/videos/r   r   r   r   )_typer(   r   r1   r   rx   r   r   )r   r   rC   r   r(   r   r   r   rg   r*   r*   r+   _make_video_result^  s    
r  c                   @   s0   e Zd ZdZddddddgZdZd	d
 ZdS )TwitchCollectionIEz@https?://(?:(?:www|go|m)\.)?twitch\.tv/collections/(?P<id>[^/]+)z0https://www.twitch.tv/collections/wlDCoH0zEBZZbQZwlDCoH0zEBZZbQz'Overthrow Nook, capitalism for childrenr   r      r1   r   Zplaylist_mincountr   c           	      C   s   |  |}| || jd|idgdd d d }|d}g }|d d	 D ]<}t|ts\qL|d
}t|tsrqLt|}|rL|| qL| j|||dS )NZcollectionIDr   zDownloading collection GraphQLr   r6   
collectionr   r   r   r   Zplaylist_idZplaylist_title)	r   ro   _OPERATION_NAMErC   r   r   r  r   playlist_result)	r)   r1   collection_idr  r   entriesedger   r   r*   r*   r+   r  }  s8    




z TwitchCollectionIE._real_extractN)r   r   r   r  r
  r  r  r*   r*   r*   r+   r  o  s   	r  c                   @   s   e Zd ZdZdd ZdS )TwitchPlaylistBaseIEd   c                 '   s*  d}| j |g|R  }| j d tdD ]}| }| j|d< |rN||d< | j|| j|dgd| j d| d	d
}|s q&t	| fddt
}|s q&|D ]h}	t|	tsq|	d| jkrq|	d}
t|
tsq|
d| jkrq| |
}|r|	d}|V  q|rt|ts, q&q,dS )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   rq   zs GraphQL page Fr   c                    s   | d d d   d S )Nr   r6   userr   r*   r   Zentries_keyr*   r+   r     rY   z/TwitchPlaylistBaseIE._entries.<locals>.<lambda>Z
__typenamer   )_make_variables_ENTRY_KIND	itertoolsr   copy_PAGE_LIMITro   r  
_NODE_KINDr   r   r   r   rC   
_EDGE_KIND_extract_entryr   )r)   channel_nameargsr  Zvariables_commonZpage_numr   rE   r   r  r   entryr*   r   r+   _entries  sN    





zTwitchPlaylistBaseIE._entriesN)r   r   r   r%  r,  r*   r*   r*   r+   r    s   r  c                   @   s(   e Zd ZdZdZdZdZedd ZdS )TwitchVideosBaseIEr   r   Z	VideoEdgeZVideoc                 C   s   | ||  dS )N)ZchannelOwnerLoginr   Z	videoSort)upper)r)  Zbroadcast_typer   r*   r*   r+   r!    s    z"TwitchVideosBaseIE._make_variablesN)	r   r   r   r  r"  r'  r&  staticmethodr!  r*   r*   r*   r+   r-    s   r-  c                       s  e Zd ZdZddddddddd	dd
ddddddddddddddddddddddddddddddddddg	ZedddgZed d!Zed"d#ed$d%ed&d'ed(d)ed*Z	d+Z
e
d,d-Ze fd.d/Zed0d1 Zd2d3 Z  ZS )4TwitchVideosIEzGhttps?://(?:(?: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=timeZ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 Videosr   zPast BroadcastsZ	HIGHLIGHTZ
HighlightsZUPLOADZUploadsZPAST_PREMIEREzPast Premieres)ZarchivesZ
highlightsZuploadsZpast_premieresallDateZPopular)timer   c                    s*   t  fddttfD rdS t  S )Nc                 3   s   | ]}|  V  qd S NsuitablerV   Zier1   r*   r+   rX   $  rY   z*TwitchVideosIE.suitable.<locals>.<genexpr>F)anyTwitchVideosClipsIETwitchVideosCollectionsIEsuperr<  clsr1   	__class__r>  r+   r<  !  s    
zTwitchVideosIE.suitablec                 C   s   t | S r:  )r  )r   r*   r*   r+   r(  )  s    zTwitchVideosIE._extract_entryc                 C   s   |  |}t|}|ddgd }|ddgd }| j|| j}| j| ||j||| d|j d| j	|| j
 dS )	Nfilterr7  r   r   r9  z - z sorted by r  )r   r   rC   _BROADCASTS_DEFAULT_BROADCASTr  r,  r5  r6  
_SORTED_BY_DEFAULT_SORTED_BY)r)   r1   r)  qsZvideo_filterr   	broadcastr*   r*   r+   r  -  s    
zTwitchVideosIE._real_extract)r   r   r   r  r
  collections
namedtupler4  rI  rH  rK  rJ  classmethodr<  r/  r(  r  __classcell__r*   r*   rE  r+   r0    s   




	;

r0  c                   @   s   e Zd ZdZdddddddd	d
gZedddgZeddZeddeeddedddZ	dZ
dZdZdZdZedd Zedd Zdd  Zd!S )"r@  z[https?://(?:(?:www|go|m)\.)?twitch\.tv/(?P<id>[^/]+)/(?:clips|videos/*?\?.*?\bfilter=clips)z<https://www.twitch.tv/vanillatv/clips?filter=clips&range=allZ	vanillatvzvanillatv - Clips Top Allr  r   r  z=https://www.twitch.tv/dota2ruhub/videos?filter=clips&range=7dTr   CliprG  r6  Z	LAST_WEEKzTop 7DZLAST_DAYzTop 24HZ
LAST_MONTHzTop 30DZALL_TIMEzTop All)Z24hr7dZ30dr7     r   clipZClipEdgec                 C   s   | d|idS )NrG  )r   criteriar*   )r)  Zchannel_filterr*   r*   r+   r!  ]  s    z#TwitchVideosClipsIE._make_variablesc                 C   sx   t | tsJ t| d}|s$d S dt | d|| d| dt| dt| dt| d| d	d

S )Nr1   r  r   r   thumbnailURLdurationSeconds	createdAtr   language)
r  r(   r   r1   r   rx   r   r   r   rZ  )	r   r   r   rC   TwitchClipsIEr(   r   r   r   )r   Zclip_urlr*   r*   r+   r(  f  s    z"TwitchVideosClipsIE._extract_entryc                 C   sZ   |  |}t|}|ddgd }| j|| j}| j| ||j|| d|j dS )NrangerS  r   z	 - Clips r  )	r   r   rC   _RANGE_DEFAULT_CLIPr  r,  rG  r6  )r)   r1   r)  rL  Z
date_rangerU  r*   r*   r+   r  y  s    
z!TwitchVideosClipsIE._real_extractN)r   r   r   r  r
  rN  rO  rR  r^  r]  r%  r  r"  r'  r&  r/  r!  r(  r  r*   r*   r*   r+   r@  ;  s8   	


r@  c                   @   sd   e Zd ZdZdddddddd	d
dddgZdZdZdZdZe	dd Z
e	dd Zdd ZdS )rA  zWhttps?://(?:(?:www|go|m)\.)?twitch\.tv/(?P<id>[^/]+)/videos/*?\?.*?\bfilter=collectionsz8https://www.twitch.tv/spamfish/videos?filter=collectionsr1  zspamfish - Collectionsr     r  z:https://www.twitch.tv/monstercat/videos?filter=collections
monstercatzmonstercat - Collectionsr  r    r  ZCollectionsItemEdge
Collectionc                 C   s   d| iS )NZ
ownerLoginr*   )r)  r*   r*   r+   r!    s    z)TwitchVideosCollectionsIE._make_variablesc                 C   sl   t | tsJ | d}|s d S dt |d| | d| dt| dt| dt| dd		S )
Nr   r  z"https://www.twitch.tv/collections/r   rW  r   Z	updatedAtr   )	r  r(   r   r1   r   rx   r   r   r   )r   r   rC   r  r(   r   r   r   )r   r  r*   r*   r+   r(    s    
z(TwitchVideosCollectionsIE._extract_entryc                 C   s&   |  |}| j| ||| ddS )Nz - Collectionsr  )r   r  r,  )r)   r1   r)  r*   r*   r+   r    s
    

z'TwitchVideosCollectionsIE._real_extractN)r   r   r   r  r
  r  r"  r'  r&  r/  r!  r(  r  r*   r*   r*   r+   rA    s.   	

rA  c                       s   e Zd ZdZdZddddddd	d
dddeddd	idddd	ddd	ddd	ddd	ddddddd	dddddddd dd!id"gZd#Ze fd$d%Z	e
d&d' Zd(d) Z  ZS )*TwitchStreamIEztwitch:streama  (?x)
                    https?://
                        (?:
                            (?:(?:www|go|m)\.)?twitch\.tv/|
                            player\.twitch\.tv/\?.*?\bchannel=
                        )
                        (?P<id>[^/#?]+)
                    zhttp://www.twitch.tv/shroomztvZ12772022048Z	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 - @ShroomzTVTieTZ20150122Z	ShroomzTV)r   
display_idr   r   r   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/monstercatZ40500071752r`  zre:Monstercatz$md5:0945ad625e615bc8f0469396537d87d9icZ20230222Z
Monstercatr   zre:https://.*.jpg)r   rc  r   r   r   r   r   r   r   r   rx   r   Z
Livestreamr   r   c                    s2   t  fddttttttfD r&dS t  S )Nc                 3   s   | ]}|  V  qd S r:  r;  r=  r>  r*   r+   rX      rY   z*TwitchStreamIE.suitable.<locals>.<genexpr>F)	r?  r   r  r0  r@  rA  r[  rB  r<  rC  rE  r>  r+   r<    s    
zTwitchStreamIE.suitablec              	   C   sT   t | tr| dsd S | d }dt d| d| | dt| dpNddS )	Nr   r1   r   r  r   r   r   )r  r(   r   r1   r   r   )r   r   rC   r   r(   r   r  r*   r*   r+   r(  	  s    zTwitchStreamIE._extract_entryc                 C   s  |  | }| |dd|idd|dddddddd	d
|idgd}|d d d }|spt| ddd|d }|st|dt|d}| dr| | d t	| 
|d dd }|r|d|ptdkr|S | jd|d | |dd}|dp
|}	| d||d |d }
| |
 |d}t|d d! tpLi }|d"}t|d#d! t}tt|d$d! t}|p|}|d%}|d&v r|d'| d(7 }|	|||| ||||||
|d)kd*S )+Nr!   r   r   r"   r:   FT)r   ZclipSlugZisClipZisLiveZisVodOrCollectionZvodIDr#   r   zDownloading stream GraphQLr   r6   r  r   r-   stream)rg   rY  r   z,: Extracting VOD to download live from startr9  r   infz9Unable to extract the VOD associated with this livestreamZchannelNamer   zapi/channel/hlsr   r   Zviewersc                 S   s   | d d d S )Nr   r6   r  r*   r   r*   r*   r+   r   M  rY   z.TwitchStreamIE._real_extract.<locals>.<lambda>r   c                 S   s   | d d S )NZbroadcastSettingsr   r*   r   r*   r*   r+   r   P  rY   c                 S   s   | d d d d d S )Nr   r6   r  rd  ZpreviewImageURLr*   r   r*   r*   r+   r   S  rY   r5  )Zrerunlivez ()rf  )r   rc  r   r   r   r   r   r   r   r_   r   )r   lowerro   r   r   r   rC   r   Z	to_screenr]   r,  popfloatr   rt   r   ra   r   r   r   r   ry   )r)   r1   r)  Zgqlr  rd  r   r+  r  Z	stream_idr_   r   Zsq_userr   r   rx   r   Zstream_typer*   r*   r+   r    s    









zTwitchStreamIE._real_extract)r   r   r   r  r  r	  r
  r%  rP  r<  r/  r(  r  rQ  r*   r*   rE  r+   rb    sn   
4
rb  c                   @   s   e Zd ZdZdZddddddd	ed
dddgdddeddddddddddded
dddgdddedd d!gd"dd#dd$d%dd$d&dd$d'dd$d(dd$d)dd$gZd*d+ Zd,S )-r[  ztwitch:clipsa2  (?x)
                    https?://
                        (?:
                            clips\.twitch\.tv/(?:embed\?.*?\bclip=|(?:[^/]+/)*)|
                            (?:(?:www|go|m)\.)?twitch\.tv/(?:[^/]+/)?clip/
                        )
                        (?P<id>[^/?#&]+)
                    z0https://clips.twitch.tv/FaintLightGullWholeWheatZ 761769e1eafce0ffebfb4089cb3847cdZ	396245304ZFaintLightGullWholeWheatr{   z'EA Play 2016 Live from the Novo Theatre    zre:^https?://.*\.jpgi]WZ20160612ZEAZ25163635FZstereotype_Z43566419)r   rc  r   r   r   r   rx   r   r   creatorsr   
channel_idchannel_is_verifiedchannel_follower_countr   r   )r1   md5r   zLhttps://www.twitch.tv/xqc/clip/CulturedAmazingKuduDatSheffy-TiZ_-ixAGYR3y2UyZ e90fe616b36e722a8cfa562547c543f0Z
3207364882z-CulturedAmazingKuduDatSheffy-TiZ_-ixAGYR3y2UyzA day in the life of xQc<   iogZ20250325ZxQcZ71092938TZ
okSTFUdudeZ	744085721zJust Chatting)r   rc  r   r   r   r   rx   r   r   rl  r   rm  rn  ro  r   r   
categoriesz;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                 C   s  |  |}| |dd|idgdd d d }|s@tdd	d
|d d |d d d}t|ddthfpni }t|ddthfpi }g }t|d}|t|ddd dt|dhfdt	hfdt
hfdthft|hdf t|d}	t|ddd fD ]H}
|t|
d |td|
dt
|
dt|
d|	dd qg }t|d}|rv|d|dd  t|d }r|d|d!d  t|d}|r||kr|d"|dd  | jd#|d! d$ d%d d&}|d'p||rt| |gnd |||d(t|d)t	hfd*t
hfd+t
hfd,thfd-d.t	httfd-d.t	hfd-d't	hfd-d/d0t
hfd-d1thfd2d.t	hfd2d't	hfd3d.t	htttfd4S )5Nr   slugr   zDownloading clip GraphQLr   r6   rU  z This clip is no longer availableTr-   ZplaybackAccessTokenr   r   )r~   r   Zassetsr   ZaspectRatioZvideoQualitiesc                 S   s   t |d S N	sourceURLr   _r   r*   r*   r+   r     rY   z-TwitchClipsIE._real_extract.<locals>.<lambda>ru  r   r[   Z	frameRate)r1   rT   r   r   aspect_ratioc                 S   s   t |d S rt  rv  rw  r*   r*   r+   r     rY   Zportrait)r1   rT   r   r   ry  r[   rW  r2   )r   r1   rv   r   z%7C(\d+)(?:-\d+)?.mp4r1   zold id)r2   r   )r   Z_old_archive_idsrc  r_   r   r   rX  r   rY  Zbroadcasterr   Z	followersZ
totalCountZ	isPartnerZcuratorr   )r   r   r   r   rl  r   rm  ro  rn  r   r   rr  )r   ro   r   r   r   r   rC   r   r   r   r   r   r   r   r   r=   r   r   rG  r7  bool)r)   r1   rs  rU  Zaccess_queryZasset_defaultZasset_portraitr_   Zdefault_aspect_ratioZportrait_aspect_ratior`   r   Zthumb_asset_default_urlZthumb_asset_portrait_urlZthumb_default_urlZold_idr*   r*   r+   r    s    


	




zTwitchClipsIE._real_extractN)r   r   r   r  r  r	  r
  r  r*   r*   r*   r+   r[  j  s~   
@r[  )-rN  r#  r@   r   rP   urllib.parser  commonr   Znetworking.exceptionsr   utilsr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zutils.traversalr   r   r   r   r  r  r  r-  r0  r@  rA  rb  r[  r*   r*   r*   r+   <module>   s0   T K  t%/iI8 /