
    }i(                         d Z ddlZddlmZ ddlmZmZmZmZm	Z	m
Z
 ddlZddlmZ ddlmZmZ ddlmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ  ej8                  e      Z G d d      Zy)a	  
This module implements the core developer interface for pytubefix.

The problem domain of the :class:`YouTube <YouTube> class focuses almost
exclusively on the developer interface. Pytubefix offloads the heavy lifting to
smaller peripheral modules and functions.

    N)CalledProcessError)AnyCallableDictListOptionalTuple)extractrequest)StreamStreamQuery)install_proxy)	InnerTube)YouTubeMetadata)	Monostate)	bot_guardc                   f   e Zd ZdZ e       j
                  dddddddddf
dededeee	e
egdf      deee	ee   gdf      d	eeeef      d
ededee   deeeegdf      dee   deedgeeef   f      fdZd ZdedefdZed        Zed        Zed        Zed        Zed        Zedefd       Zedefd       Zed        Zed        Zed        Zd Zedefd        Z ed!        Z!ed"        Z"ed#        Z#e#jH                  d$        Z#dGd%Z%ed&        Z&e&jH                  d'        Z&d( Z'ede(e)jT                     fd)       Z+ede)jX                  fd*       Z-ede(e)j\                     fd+       Z/ede(e)j`                     fd,       Z1ede(eee2f      fd-       Z3ede4fd.       Z5edefd/       Z6ed0        Z7e7jH                  d1        Z7de8fd2Z9edefd3       Z:e:jH                  d4        Z:ed5        Z;de8fd6Z<edefd7       Z=ede2fd8       Z>edefd9       Z?edefd:       Z@edefd;       ZAeAjH                  d<        ZAede(e   fd=       ZBedefd>       ZCedefd?       ZDed@        ZEedeeF   fdA       ZGdBee	e
egdf   fdCZHdBee	ee   gdf   fdDZIeJdEedd fdF       ZKy)HYouTubez'Core developer interface for pytubefix.NFTurlclienton_progress_callbackon_complete_callbackproxies	use_oauthallow_oauth_cache
token_fileoauth_verifieruse_po_tokenpo_token_verifierc                    d| _         d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _	        d| _
        t        j                  |      | _        d| j                   | _        d| j                   | _        || _        |rdn| j                  | _        ddg| _        i | _        d| _        t'        |||       | _        |rt+        |       d| _        d| _        d| _        d| _        || _        || _        || _        |	| _        |
| _        || _        | j<                  s| j>                  rt@        jC                  d       d| _"        d| _#        y)a  Construct a :class:`YouTube <YouTube>`.

        :param str url:
            A valid YouTube watch URL.
        :param str client:
            (Optional) A YouTube client,
            Available:
                WEB, WEB_EMBED, WEB_MUSIC, WEB_CREATOR, WEB_SAFARI,
                ANDROID, ANDROID_MUSIC, ANDROID_CREATOR, ANDROID_VR, ANDROID_PRODUCER, ANDROID_TESTSUITE,
                IOS, IOS_MUSIC, IOS_CREATOR,
                MWEB, TV, TV_EMBED, MEDIA_CONNECT.
        :param func on_progress_callback:
            (Optional) User defined callback function for stream download
            progress events.
        :param func on_complete_callback:
            (Optional) User defined callback function for stream download
            complete events.
        :param dict proxies:
            (Optional) A dict mapping protocol to proxy address which will be used by pytube.
        :param bool use_oauth:
            (Optional) Prompt the user to authenticate to YouTube.
            If allow_oauth_cache is set to True, the user should only be prompted once.
        :param bool allow_oauth_cache:
            (Optional) Cache OAuth and Po tokens locally on the machine. Defaults to True.
            These tokens are only generated if use_oauth is set to True as well.
        :param str token_file:
            (Optional) Path to the file where the OAuth and Po tokens will be stored.
            Defaults to None, which means the tokens will be stored in the pytubefix/__cache__ directory.
        :param Callable oauth_verifier:
            (optional) Verifier to be used for getting oauth tokens. 
            Verification URL and User-Code will be passed to it respectively.
            (if passed, else default verifier will be used)
        Nzhttps://youtube.com/watch?v=zhttps://www.youtube.com/embed/TVIOS)on_progresson_completeyoutubezN`use_po_token` and `po_token_verifier` is deprecated and will be removed soon.)$_js_js_url	_vid_info_vid_details_watch_html_embed_html_player_config_args_age_restricted_fmt_streams_initial_data	_metadatar
   video_id	watch_url	embed_urlr   fallback_clients_signature_timestamp_visitor_datar   stream_monostater   _author_title_original_title_publish_dater   r   r   r   r   r   loggerwarningpo_token_pot)selfr   r   r   r   r   r   r   r   r   r   r   s               =/usr/local/lib/python3.12/dist-packages/pytubefix/__main__.py__init__zYouTube.__init__5   sl   ` #' '+ *.,0 +/*. 48 /348!48  ((-7G9$--I (dT[[!%u*,!! !*,:NX\!
 '"#!"!2$,
 )!2 6 6NNkl	    c                 "    d| j                    dS )Nz,<pytubefix.__main__.YouTube object: videoId=>r1   r@   s    rA   __repr__zYouTube.__repr__   s    =dmm_ANNrC   oreturnc                 f    t        |      t        |       k(  xr |j                  | j                  k(  S N)typer2   )r@   rI   s     rA   __eq__zYouTube.__eq__   s'    Aw$t*$F)FFrC   c                     | j                   r| j                   S t        j                  | j                        | _         | j                   S N)r   )r*   r   getr2   rG   s    rA   
watch_htmlzYouTube.watch_html   8    ###";;4>>:rC   c                     | j                   r| j                   S t        j                  | j                        | _         | j                   S rP   )r+   r   rQ   r3   rG   s    rA   
embed_htmlzYouTube.embed_html   rS   rC   c                     | j                   r| j                   S t        j                  | j                        | _         | j                   S rL   )r-   r
   is_age_restrictedrR   rG   s    rA   age_restrictedzYouTube.age_restricted   s:    '''&88I###rC   c                 
   | j                   r| j                   S | j                  r0t        j                  | j                        | _         | j                   S t        j                  | j
                        | _         | j                   S rL   )r'   rX   r
   js_urlrU   rR   rG   s    rA   rZ   zYouTube.js_url   s\    <<<<">>$//:DL || #>>$//:DL||rC   c                 b   | j                   r| j                   S t        j                  | j                  k7  rZt	        j
                  | j                        | _         | j                   t        _        | j                  t        _        | j                   S t        j                  | _         | j                   S rL   )r&   	pytubefix
__js_url__rZ   r   rQ   __js__rG   s    rA   jsz
YouTube.js   su    8888O 4;;.{{4;;/DH#xxI#';;I  xx !''DHxxrC   c                    | j                   r| j                   S t        | j                        j                  rg	 t        j                  d       t        j                  t        | j                  d               | _         t        j                  d       | j                   S t        j                  d       t        d      j                  | j                        }	 |d   d   | _         t        j                  d       | j                   S # t        t        j                  j                  f$ r t        j                  d       Y w xY w# t        $ r+ |d   d   d	   d
   }t!        d |D              d   | _         Y w xY w)z@
        Retrieves the visitorData from the WEB client.
        z'Looking for visitorData in initial_dataresponseContextz!VisitorData obtained successfullyzUUnable to obtain visitorData from initial_data. Trying to request from the WEB clientz(Looking for visitorData in InnerTube APIWEBvisitorDataserviceTrackingParamsr   paramsc              3   2   K   | ]  }|d    dk(  s|  yw)keyvisitor_dataN ).0ps     rA   	<genexpr>z'YouTube.visitor_data.<locals>.<genexpr>   s     %WAAeH<Va%Ws   value)r6   r   r   require_po_tokenr<   debugr
   rh   strinitial_dataKeyErrorr\   
exceptionsRegexMatchErrorplayerr1   next)r@   innertube_responsep_dictss      rA   rh   zYouTube.visitor_data   sQ   
 %%%T[[!22vFG%,%9%9#d>O>OPa>b:c%d"@A))) 	?@&u-44T]]C	a!34E!F}!UD 	89!!! i22BBC vtuv  	a():;<STUVWX`aG!%%W%W!WX_!`D	as$   A%D E 8EE1E98E9c                 x   | j                   r| j                   S t        j                  d       	 t        j                  | j
                        | _         t        j                  d       | j                   S # t        $ r;}t        j                  d|j                         z          Y d}~| j                   S d}~ww xY w)zv
        Retrieves the poToken generated by botGuard.

        This poToken only works for WEB-based clients.
        zRunning botGuardrF   zPoToken generated successfullyz=Unable to run botGuard. Skipping poToken generation, reason: N)	r?   r<   ro   r   generate_po_tokenr1   	Exceptionr=   __str__r@   es     rA   potzYouTube.pot   s     9999'(	j!33T]]KDILL9: yy  	jNNZ]^]f]f]hhiiyy	js   :A5 5	B9>&B44B9c                     | j                   r| j                   S t        j                  | j                        | _         | j                   S rL   )r/   r
   rq   rR   rG   s    rA   rq   zYouTube.initial_data  s:    %%%$11$//B!!!rC   c                    dg}d| j                   vs| j                   d   d   |v r| j                  }| j                  D ]1  }|| _        d| _         	 | j                          d| j                   v s1 n d| j                   vr1t        j                  | j                  d| d| j                         | j                   d   S # t        $ r
}Y d}~d}~ww xY w)	z%Return streamingData from video info.aQvGIIdgFDMstreamingDatavideoDetailsvideoIdNz,Streaming data is missing, original client: z, fallback clients: )r1   developer_message)vid_infor   r4   check_availabilityr{   rs   UnknownVideoErrorr1   )r@   invalid_id_listoriginal_clientr   r~   s        rA   streaming_datazYouTube.streaming_data  s    
 )/
 $--/4==3PQZ3[_n3n"kkO // $ $++- #dmm3 dmm3 22DMMHYYhXi jZZ^ZoZoYpFrs s
 }}_-- ! s   C  	CCc                    | j                          | j                  r| j                  S g | _        t        j                  | j                        }t        | j                        }| j                  r+t        j                  || j                  | j                         |j                  r7	 t        j                  || j                  | j                  | j                         |D ]J  }t+        || j,                  | j                  | j.                        }| j                  j1                  |       L | j2                  | j,                  _        | j4                  | j,                  _        | j                  S # t        j                  $ r^ d| _        d| _        dt$        _        dt$        _        t        j                  || j                  | j                  | j                         Y w xY w)zReturns a list of streams if they have been initialized.

        If the streams have not been initialized, finds all relevant
        streams and initializes them.
        N)stream	monostater>   video_playback_ustreamer_config)r   r.   r
   apply_descramblerr   r   r   r>   apply_po_tokenr   require_js_playerapply_signaturer_   rZ   rs   ExtractErrorr&   r'   r\   r^   r]   r   r7   r   appendtitlelengthduration)r@   stream_manifest
inner_tuber   videos        rA   fmt_streamszYouTube.fmt_streams7  s}    	!$$$!33D4G4GHt{{+
==""?DMM4==Q''^''QUQ\Q\] & 	,F//040T0T	E $$U+	, '+jj#)-&   - ** ^##'	 '+	$''QUQ\Q\]^s   (6E/ /A-G G c                    t        j                  | j                        \  }}t        | j                        j
                  r/| j                  s#t        j                  d| j                   d       |D ]  }|dk(  r|dk(  r t        j                  | j                        d|v r t        j                  | j                        |dk(  r t        j                  | j                        |dk(  r t        j                  | j                        |d	k(  r t        j                  | j                        d
|v r!t        j                  | j                  |      t        j                   | j                        |dk(  rk|dk(  r t        j"                  | j                        |dk(  r t        j$                  | j                        t        j&                  | j                  |      |dk(  r>| j(                  r| j+                          t        j,                  | j                        |dk(  r!t        j.                  | j                  |      |dk(  r|dk(  r t        j                   | j                        |dk(  r t        j0                  | j                        |dk(  r t        j                   | j                        |dk(  r!t        j2                  | j                  |      |dk(  r!t        j4                  | j                  |      |dk(  r!t        j6                  | j                  |      t        j8                  | j                  ||d      |dk(  r t        j:                  | j                        |dk(  rI|dk(  r!t        j<                  | j                  |      t        j8                  | j                  ||d      |`t        j8                  | j                  ||d       y)zCheck whether the video is available.

        Raises different exceptions based on why the video is unavailable,
        otherwise does nothing.
        The z{ client requires PoToken to obtain functional streams, See more details at https://github.com/JuanBindez/pytubefix/pull/209
UNPLAYABLEzcJoin this channel to get access to members-only content like this video, and other exclusive perks.rF   zRJoin this channel to get access to members-only content and other exclusive perks.z,This live stream recording is not available.zSorry, something is wrong. This video may be inappropriate for some users. Sign in to your primary account to confirm your age.z>The uploader has not made this video available in your countryz/blocked it in your country on copyright grounds)r1   reasonLOGIN_REQUIREDzSign in to confirm your ageu%   Sign in to confirm you’re not a botAGE_CHECK_REQUIREDLIVE_STREAM_OFFLINEERRORzVideo unavailablezThis video is privatezThis video is unavailablez+This video has been removed by the uploaderzmThis video is no longer available because the YouTube account associated with this video has been terminated.zHThis video has been removed for violating YouTube's Community Guidelinesz$Unknown reason type for Error status)r1   statusr   r   LIVE_STREAMOKzThis live event has ended.zUnknown video statusN)r
   playability_statusr   r   r   rn   r>   r<   r=   rs   MembersOnlyr1   RecordingUnavailableAgeCheckRequiredAccountErrorVideoRegionBlockedVideoBlockedByCopyrightVideoUnavailableAgeRestrictedErrorBotDetectionLoginRequiredr   	age_checkAgeCheckRequiredErrorLiveStreamOfflineVideoPrivateVideoRemovedByUploaderAccountTerminated$VideoRemovedByYouTubeForViolatingTOSr   LiveStreamErrorLiveStreamEnded)r@   r   messagesr   s       rA   r   zYouTube.check_availabilityf  s    #55dmmDT[[!224==NNT$++ /b c d  H	TF%F %00$--HHimss$00$--HHMM$994==QQO %AA4==YY `a$77OOF&P$<<dmm\bcc$55t}}MM++5 %77OO? %114==II$22DMMRXYY//>>NN$$::DMMRR00 22DMMRXYY7"00$55t}}MM66$114==II::$55t}}MMLL$;;T]][abb   O  O$66V\]]ii$IISWS`S`iopp$66V\ek  Bf  h  h=( 00$--HH499$44dmmTZ[[$66V\ek  BV  X  X 22DMMRXag  ~R  T  TQH	TrC   c                     | j                   s*dddt        j                  | j                        iii| _         | j                   S )zWEB clients need to be signed with a signature timestamp.

        The signature is found inside the player's base.js.

        :rtype: Dict
        playbackContextcontentPlaybackContextsignatureTimestamp)r5   r
   signature_timestampr_   rG   s    rA   r   zYouTube.signature_timestamp  sI     ((!,,g.I.I$''.R/$)D% (((rC   c                 2    | j                   d   d   d   d   S )NplayerConfigmediaCommonConfigmediaUstreamerRequestConfigvideoPlaybackUstreamerConfig)r   rG   s    rA   r   z'YouTube.video_playback_ustreamer_config  s2    }}! *+ +	, 	,rC   c                     	 | j                   d   d   }d|ig}t        j                  || j                   | j                  | j                         |d   d   S # t
        $ r Y yw xY w)zN
        Extract the url for abr server and decrypt the `n` parameter
        r   serverAbrStreamingUrlr   )r   r_   url_jsr   N)r   r
   r   r_   rZ   r{   )r@   r   r   s      rA   server_abr_streaming_urlz YouTube.server_abr_streaming_url  su    
	--!')C !&s|nO##OdmmPTPWPW`d`k`kl"1%e,, 		s   AA 	A$#A$c                 t    | j                   r| j                   S | j                         | _         | j                   S )z]Parse the raw vid info and return the parsed result.

        :rtype: Dict[Any, Any]
        )r(   vid_info_clientrG   s    rA   r   zYouTube.vid_info  s/     >>>>!--/~~rC   c                     || _         y rL   )r(   r@   rm   s     rA   r   zYouTube.vid_info  s	    rC   c                     |$ j                   r j                   S  j                  } fd} ||      } j                  D ]f  }|d   }|d   dk(  rVd|v rR|d   dk(  rJt        j	                   j                   d       | _        t        j	                  d|         ||      }f n |s4t
        j                  j                   j                   j                        |S )	Nc           	         t        | j                  j                  j                  j                  j
                  j                        }|j                  r%|j                  j                  j                         |j                  rWj
                  sKt        j                  d|  d       t        j                  d       |j                  j                         n(j
                  s|j                  j                         |j!                  j"                        }j
                  s|j                  r|j$                  xs j&                  _        |S )Nr   r   allow_cacher   r   r   r   r   z5 client requires poToken to obtain functional streamsz Automatically generating poToken)rh   )r   r   r   r   r   r   r   r   innertube_contextupdater   rn   r<   ro   insert_visitor_datarh   ru   r1   access_po_tokenr   r>   )optional_client	innertuberesponser@   s      rA   call_innertubez/YouTube.vid_info_client.<locals>.call_innertube  s   !&.. 22??#22!.."&"8"8I **++2243K3KL ))$2C2CtO#44ijk?@--4;L;L-M&&--4;L;L-M ''6H   I$>$> ) 9 9 ETXXOrC   playabilityStatusr   r   r   zThis video is not availablez- client returned: This video is not availablezSwitching to client: )	r(   r   r4   r<   r=   r\   rs   InnerTubeResponseErrorr1   )r@   r   r   rw   r   r   s   `     rA   r   zYouTube.vid_info_client  s    "~~~~%"kkO	: ,O<++ 
	F "44G!H!(+|;L^@^cuv~c  Da  da$++.[\]$!6vh?@%3F%;"
	 "&&==dmmT[[YY!!rC   c           	      F   | j                   r| j                   S t        | j                  rdnd| j                  | j                  | j                  | j
                  | j                  | j                        }|j                  | j                        }|| _         | j                   S )zParse the raw vid details and return the parsed result.

        The official player sends a request to the `next` endpoint to obtain some details of the video.

        :rtype: Dict[Any, Any]
        r!   rb   r   )
r)   r   r   r   r   r   r   r   rv   r1   )r@   r   rw   s      rA   vid_detailszYouTube.vid_details,  s     $$$>>4unn....**"44
	 '^^DMM:.   rC   c                     || _         y rL   )r)   r   s     rA   r   zYouTube.vid_detailsD  s
    !rC   c           	      X   d| _         t        | j                   | j                  | j                  | j                  | j
                  | j                  | j                        }|j                  r%|j                  j                  | j                         |j                  | j                         |j                  | j                        }|d   j                  dd      }|dk7  rC|dk(  rt!        j"                  | j                        t!        j$                  | j                        || _        y)zIf the video has any age restrictions, you must confirm that you wish to continue.

        Originally the WEB client was used, but with the implementation of PoToken we switched to MWEB.
        r!   r   r   r   Nr   r   )r   r   r   r   r   r   r   r   r   r   r   r   
verify_ager1   ru   rQ   rs   r   r   r(   )r@   r   rw   r   s       rA   r   zYouTube.age_checkH  s     ;;nn....**"44
	 &&''..t/G/GHT]]+&--dmm</0CDHHSWX %!\1 ==dmmLL 66t}}EE+rC   c           	         t        | j                  sdn| j                  | j                  | j                  | j                  | j
                  | j                  | j                        j                  | j                        }|j                  di       j                  di       j                  dg       }|D cg c]  }t        j                  |       c}S c c}w )zQGet a list of :class:`Caption <Caption>`.

        :rtype: List[Caption]
        rb   r   captionsplayerCaptionsTracklistRenderercaptionTracks)r   r   r   r   r   r   r   r   ru   r1   rQ   r\   Caption)r@   rw   
raw_trackstracks       rA   caption_trackszYouTube.caption_tracksk  s     ' $5DKKnn....**"44
 &
 	 "":r2S2B7S"% 	
 7AAU	!!%(AAAs   6Cc                 @    t        j                  | j                        S )zbInterface to query caption tracks.

        :rtype: :class:`CaptionQuery <CaptionQuery>`.
        )r\   CaptionQueryr   rG   s    rA   r   zYouTube.captions  s     %%d&9&9::rC   c                    	 g }| j                   d   d   d   d   d   d   d   }|D ]8  }|d   j                         dk(  s|d   j                         d	k(  s0|d
   d   } n g }t	        |      D ]y  \  }}t        |d   d   dz        }|t        |      dz
  k(  r| j                  }nt        ||dz      d   d   dz        }|j                  t        j                  |||z
               { |S # t        t        f$ r g cY S w xY w)zQGet a list of :class:`Chapter <Chapter>`.

        :rtype: List[Chapter]
        playerOverlaysplayerOverlayRendererdecoratedPlayerBarRenderer	playerBarmultiMarkersPlayerBarRenderer
markersMaprg   DESCRIPTION_CHAPTERSAUTO_CHAPTERSrm   chapterschapterRenderertimeRangeStartMillis     )rq   upperrr   
IndexError	enumerateintlenr   r   r\   Chapter)	r@   chapters_datamarkers_mapmarkerresultichapter_datachapter_startchapter_ends	            rA   r   zYouTube.chapters  s`   
	M++,<=>UV,..JLLWY/11=?K & %=&&(,BBfUmFYFYF[_nFn$*7OJ$?M +-(7 	XOA|./0FG$NM C&**"kk!!!a%():;<RSVZZ MM)++L+:UVW	X ' *% 	I	s   AC- C- -D Dc                 .   	 | j                   d   d   d   }d}|D ]X  }|j                  di       j                  di       j                  di       j                  d      d	k(  sH|d   d   d   d
   }d} n |sg S 	 g }t	              D ]s  \  }}t        |d         dz  }|t        |      dz
  k(  r| j                  }	nt        ||dz      d         dz  }	|j                  t        j                  ||	|z
               u |S # t        t        f$ r g cY S w xY w)zWGet a list of :class:`KeyMoment <KeyMoment>`.

        :rtype: List[KeyMoment]
        frameworkUpdatesentityBatchUpdate	mutationsFpayloadmacroMarkersListEntitymarkersList
markerTypeMARKER_TYPE_TIMESTAMPSmarkersTstartMillisr   r   )rq   rQ   rr   r   r   r   r   r   r   r\   	KeyMoment)
r@   r  foundmutationkey_moments_datar  r  key_moment_datakey_moment_startkey_moment_ends
             rA   key_momentszYouTube.key_moments  sb   	))*<=>QRS^_IE% <<	2.223KRPTTUbdfgkk$&)AB'/	':;S'TUb'cdm'n$ E 	 
 -/"+,<"= 	cA"?=#ABdJC()A--!%!$%5a!e%<]%K!LPT!TMM)--o~P`?`ab	c  *% 	I	s   A D  #D   DDc                    	 | j                   d   d   d   }d}|D ]X  }|j                  di       j                  di       j                  di       j                  d      d	k(  sH|d   d   d   d
   }d} n |sg S 	 g }D ]G  }t	        |d         dz  }t	        |d         dz  }t        |d         }	|j                  |||	d       I |S # t        t        f$ r g cY S w xY w)zTGet a list of : `Dict<str, float>`.

        :rtype: List[Dict[str, float]]
        r	  r
  r  Fr  r  r  r  MARKER_TYPE_HEATMAPr  Tr  r   durationMillisintensityScoreNormalized)start_secondsr   norm_intensity)rq   rQ   rr   r   r   floatr   )
r@   r  r  r  heatmaps_datar  heatmap_dataheatmap_startr   r   s
             rA   replayed_heatmapzYouTube.replayed_heatmap  s7   	))*<=>QRS^_IE% <<	2.223KRPTTUbdfgkk$&)>?$,Y$78P$QR_$`aj$kM E 	 
 *,) 
	L] ;<tCM<(89:TAH"<0J#KLNMM!.$"0 
	 # *% 	I	s   A C #C CCc                 L    | j                          t        | j                        S )z~Interface to query both adaptive (DASH) and progressive streams.

        :rtype: :class:`StreamQuery <StreamQuery>`.
        )r   r   r   rG   s    rA   streamszYouTube.streams  s!     	!4++,,rC   c                     | j                   j                  di       j                  di       j                  d      }|r
|d   }|d   S d| j                   dS )z:Get the thumbnail url image.

        :rtype: str
        r   	thumbnail
thumbnailsr   zhttps://img.youtube.com/vi/z/maxresdefault.jpg)r   rQ   r1   )r@   thumbnail_detailss     rA   thumbnail_urlzYouTube.thumbnail_url   sb     MMnb1Sb!S 	
  1" 5$U++,T]]O;MNNrC   c                     | j                   r| j                   S t        j                  | j                        | _         | j                   S )z8Get the publish date.

        :rtype: datetime
        )r;   r
   publish_daterR   rG   s    rA   r/  zYouTube.publish_date  s<     %%%$11$//B!!!rC   c                     || _         y)zSets the publish date.N)r;   r   s     rA   r/  zYouTube.publish_date  s     #rC   c                     | j                   j                  dg       D ]  }	 |d   d   d   d   c S  y # t        $ r
}Y d }~$d }~ww xY w)NengagementPanels"engagementPanelSectionListRenderercontent$structuredDescriptionContentRendereritems)r   rQ   rr   )r@   r  r~   s      rA   vid_engagement_itemszYouTube.vid_engagement_items!  sa    !!%%&8"= 	A=>yIJpqryzz	
   s   3	AAc                 :   | j                   j                  di       j                  dd      | _        | j                  r| j                  S | j                  dk(  rG| j                         | _        | j                  dk7  r#| j                  d   d   d   d	   d   d
   | _        	 d| j                   d   v r8| j                   d   d   | _        t        j                  d       | j                  S d| j                  d   v rj| j                  d   d   d   d   d   d   d   d   d   }d|v r"|d   d   d	   d   d
   | _        | j                  S |d   d   d   | _        	 | j                  S d| j                  d   v rI| j                  d   d   d   d   d   }|D ])  }d|v s|d   d   d	   d   d
   | _         | j                  S  | j                  S # t        $ rF}| j                          t        j                  d| j                   d| j                   d      |d}~ww xY w)z2Get the video title.

        :rtype: str
        r   authorunknownTNr   videoDescriptionHeaderRendererr   runstextzFound title in vid_infosingleColumnWatchNextResultscontentsresultsitemSectionRenderervideoMetadataRenderermusicWatchMetadataRenderer
simpleTexttwoColumnWatchNextResultsvideoPrimaryInfoRendererz#Exception while accessing title of  in  client.)r   rQ   r8   r9   r   r7  r<   ro   r   rr   r   rs   PytubeFixErrorr2   r   )r@   r?  rF  r~   s       rA   r   zYouTube.title)  s    }}((<@@i
 ;;;;>>T!335DK{{d""kk!n-MNwWX^_`abcij/	 $--77"mmN;GD67X {{U 2T5E5Ej5QQ#//
;6 8! # " # #	 $ %&	 '
 . / # $ %& 'H /(:&./F&G&PQW&XYZ&[\b&c@ {{; '//K&LW&UVb&c: {{3 1D4D4DZ4PP#//
;3 5! # " # #	 $H
 5= "059QQ*B :+< '+) !'+( )*++ !'	+(DK
 " {{'"& {{  	 ##%++9$..9Idkk]Zbc 			s8   !=G *AG G %5G G >G 	HAHHc                     || _         y)zSets the title value.N)r9   r   s     rA   r   zYouTube.titlen  s     rC   c                    | j                   r| j                   S 	 | j                  dk(  r)| j                  d   d   d   d   | _         | j                   S | j                  d      d   d   d   d   | _         	 | j                   S # t        $ rF}| j                          t        j                  d| j                   d| j                   d      |d }~ww xY w)	Nrb   microformatplayerMicroformatRendererr   rD  z,Exception while accessing original title of rG  rH  )	r:   r   r   r   rr   r   rs   rI  r2   r}   s     rA   original_titlezYouTube.original_titles  s     '''	{{e#'+}}]'CD_'`ah'ijv'w$ ### (,';';E'B='QRm'nov'w  yE  (F$ ###  	 ##%++B4>>BRRVW[WbWbVcckl 			s   ,B "B 	C
ACCc           
         	 | j                   d   }|t        |j                               d      d   d   d   }|S # t        $ rF}t	        j
                  d| j                   d| j                   dj                                |d }~ww xY w)Nr?  r   r@  z,Exception: accessing vid_details_content of rG  z and trying to use key in )r   listkeysr{   rs   PyTubeFixErrorr2   r   )r@   r?  r@  r~   s       rA   vid_details_contentzYouTube.vid_details_content  s    	''
3HtHMMO4Q78CINzZG   	++Ft~~FVVZ[_[f[fZg  hB  CK  CP  CP  CR  BS  T 		s   7; 	B
ABB
c                 "   | j                   j                  di       j                  d      }| j                  dk(  r)| j                         }|dk7  r|d   d   d   d   d	   d
   }|)| j	                         }|D ]  }d|v s|d   d   d   } |S  |S )z8Get the video description.

        :rtype: str
        r   shortDescriptionTN   &expandableVideoDescriptionBodyRendererdescriptionBodyTextr<  r   r=  videoSecondaryInfoRendererattributedDescriptionr4  )r   rQ   r   r7  rS  )r@   descriptionr@  cs       rA   r[  zYouTube.description  s     mm'';??@RS>>T!335Kd")!n-UVWlmntuvwxy  A..0G /14"#$@"ABY"Z[d"eK	 rC   c                 X    | j                   j                  di       j                  d      S )z>Get the video average rating.

        :rtype: float

        r   averageRatingr   rQ   rG   s    rA   ratingzYouTube.rating  s&     }}  488IIrC   c                     | j                          t        | j                  j                  di       j                  d            S )z>Get the video length in seconds.

        :rtype: int
        r   lengthSeconds)r   r   r   rQ   rG   s    rA   r   zYouTube.length  s7     	!4==$$^R8<<_MNNrC   c           
      .   t        | j                  j                  di       j                  dd            }| j                  dk(  r\| j	                         }|dk7  rG|d   d   d   d	   }t        d
j                  |D cg c]  }|j                         s| c}            }|sh| j                         }|D ]S  }d|v s|d   d   d   d   d	   }t        d
j                  |D cg c]  }|j                         s| c}            } |S  |S c c}w c c}w )zTGet the number of the times the video has been viewed.

        :rtype: int
        r   	viewCount0TNr   r;  viewsrD   rF  videoViewCountRenderer)r   r   rQ   r   r7  joinisdigitrS  )r@   viewsimple_textcharr@  r\  s         rA   rf  zYouTube.views  s(    4==$$^R8<<[#NO>>T!335Kd")!n-MNwWXde277[#STDLLND#STU..0G -2"#$>"?##%0#2 $#% %	#&K
 rww'W'WXYD  $T (Xs   <DD"D8Dc                     | j                   j                  di       j                  dd      }| j                  dk(  r | j                         }|r|d   d   d   d   }|| _        | j                  S )	z2Get the video author.
        :rtype: str
        r   r9  r:  Tr   r;  channelrD  )r   rQ   r   r7  r8   )r@   r8   s     rA   r9  zYouTube.author  so     --##NB7;;HiP>>T!//1G!!*%EFyQR^_||rC   c                     || _         y)zSet the video author.N)r8   r   s     rA   r9  zYouTube.author  s     rC   c                 Z    | j                   j                  di       j                  dg       S )z;Get the video keywords.

        :rtype: List[str]
        r   keywordsr_  rG   s    rA   rr  zYouTube.keywords  s(     }}  488RHHrC   c                 Z    | j                   j                  di       j                  dd      S )z@Get the video poster's channel id.

        :rtype: str
        r   	channelIdNr_  rG   s    rA   
channel_idzYouTube.channel_id  s(     }}  488dKKrC   c                      d| j                    S )zcConstruct the channel url for the video's poster from the channel id.

        :rtype: str
        z https://www.youtube.com/channel/)ru  rG   s    rA   channel_urlzYouTube.channel_url   s     2$//1BCCrC   c                    | j                   dk(  r,| j                         }|dk7  r|d   d   d   d   d   d   d   S 	 d	}| j                         }|D ]1  }d
|v s|d
   d   d   d   d   d   d   d   d   d   d   d   d   } n dj                  |D cg c]  }|j	                         s| c}      S c c}w # t
        t        f$ r5}t        j                  d| j                   d| j                         |d}~ww xY w)z1Get the video likes

        :rtype: str
        TNr   r;  factoidfactoidRendererrm   rD  re  rF  videoActionsmenuRenderertopLevelButtons#segmentedLikeDislikeButtonViewModellikeButtonViewModeltoggleButtonViewModeldefaultButtonViewModelbuttonViewModelaccessibilityTextrg  zException: accessing likes of rG  )r   r7  rS  ri  rj  rr   r   rs   rR  r2   r   )r@   likesr?  r\  rm  r~   s         rA   r  zYouTube.likes  sq    >>T!--/E}Qx @A)LQOPabcjklxyy	E//1H -289"$"$ &' 	
 :; *+ *+ ,- ,	- -
. &' ()E " 77UETdllnDEFFE*% 	++88HT[[MZ 		s5   B: ;B: B5*B5.B: 5B: :C>	0C99C>c                 z    | j                   s$t        j                  | j                        | _         | j                   S )zIGet the metadata for the video.

        :rtype: YouTubeMetadata
        )r0   r
   metadatarq   rG   s    rA   r  zYouTube.metadata1  s0     ~~$--!!#DN~~rC   funcc                 &    || j                   _        y)zRegister a download progress callback function post initialization.

        :param callable func:
            A callback function that takes ``stream``, ``chunk``,
             and ``bytes_remaining`` as parameters.

        :rtype: None

        N)r7   r#   r@   r  s     rA   register_on_progress_callbackz%YouTube.register_on_progress_callback<  s     -1)rC   c                 &    || j                   _        y)zRegister a download complete callback function post initialization.

        :param callable func:
            A callback function that takes ``stream`` and  ``file_path``.

        :rtype: None

        N)r7   r$   r  s     rA   register_on_complete_callbackz%YouTube.register_on_complete_callbackH  s     -1)rC   r1   c                     t        d|        S )zConstruct a :class:`YouTube <YouTube>` object from a video id.

        :param str video_id:
            The video id of the YouTube video.

        :rtype: :class:`YouTube <YouTube>`
        z https://www.youtube.com/watch?v=)r   rF   s    rA   from_idzYouTube.from_idS  s     9(DEErC   rL   )L__name__
__module____qualname____doc__r   client_namerp   r   r   r   bytesr   r   boolr	   rB   rH   objectrN   propertyrR   rU   rX   rZ   r_   rh   r   rq   r   r   r   dictr   r   r   r   setterr   r   r   r   r\   r   r   r   r   r   r   r  r  r!  r%  r   r'  r-  r/  rP  r7  r   rN  rS  r[  r`  r   rf  r9  rr  ru  rw  r  r   r  r  r  staticmethodr  ri   rC   rA   r   r   2   s   1
 $+11PTSW04#&*(,CG+0MQrr r #+8S%4Et4K+L"M	r
 #+8S(3-4H$4N+O"Pr d38n-r r  $r !r %XsCj$.>%?@r #4.r  ($sCx1H(IJrhOG G4 G         $ $ 	 	   "c " "6 S    " " . .B ,! ,!\TTl )T ) )" , ,   
 
 __ 4"l ! !. " "!,F BY%6%6 7 B B. ;)00 ; ; !$y001 ! !F  T)"5"56    D "$tCJ'7"8 " "H - - - Os O O  " " # #d  Bs B BH \\  $ $,
T 
 S  * J J J O O O s  4     ]]  I$s) I I LC L L DS D D & &P (?3  
1(C;Ld;R2S 
1	1(C#;OQU;U2V 	1 F# F) F FrC   r   ) r  logging
subprocessr   typingr   r   r   r   r   r	   r\   pytubefix.exceptionsrs   r
   r   r   r   pytubefix.helpersr   pytubefix.innertuber   pytubefix.metadatar   pytubefix.monostater   pytubefix.botGuardr   	getLoggerr  r<   r   ri   rC   rA   <module>r     sS   0  ) = =  ) & ) + ) . ) (			8	$jF jFrC   