
    }i6                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlZ	d dl
Z
d dlmZmZ d dlmZ d dlmZ d dlmZmZmZ d dlmZmZ d dlmZ  ej2                  e      Zdeddfd	Zd-d
ededededdf
dZ dede!deddfdZ"d.dedee   dee   ddfdZ#dededededef
dZ$d/dededee   ddfdZ%d/dededee   ddfdZ&d0dedee   dee   ddfdZ'd/dededee   ddfdZ(d/ded edee   ddfd!Z)d/ded"edee   ddfd#Z*d$ee   ddfd%Z+deddfd&Z,d/d'ejZ                  d(ee   dej\                  fd)Z/ded(ej\                  ddfd*Z0d+ Z1ed,k(  r e1        yy)1    N)ListOptional)__version__)CaptionQueryPlaylistStream)safe_filenamesetup_logger)YouTubeyoutubereturnc           
      H   t        t        j                  j                  t        j                  j
                        j                               }t        j                  j                  t        j                         d| j                   d| d      }| j                  }| j                  }| j                  }t        j                   |d      5 }|j#                  t%        j&                  | j(                  |||d      j+                  d             ddd       y# 1 sw Y   yxY w)zySerialize the request data to json for offline debugging.
    
    :param YouTube youtube:
        A YouTube object.
    z	yt-video--z.json.gzwb)urljs
watch_html
video_infoutf8N)intdtdatetimenowtimezoneutc	timestampospathjoingetcwdvideo_idr   r   vid_infogzipopenwritejsondumps	watch_urlencode)r   tsfpr   r   r"   fhs          8/usr/local/lib/python3.12/dist-packages/pytubefix/cli.pybuild_playback_reportr.      s     
R[[__R[[__-779	:B	biikYw/?/?.@"X#N	OB	B##JH	2t	 


JJ",,","*	 fVn		


 

 

s   ADD!bytes_receivedfilesizechscalec                    t        j                         j                  }t        ||z        }t        t	        || z  t        |      z              }||z
  }||z  d|z  z   }t	        d| z  t        |      z  d      }	d| d|	 d}
t        j                  j                  |
       t        j                  j                          y)uz  Display a simple, pretty progress bar.

    Example:
    ~~~~~~~~
    PSY - GANGNAM STYLE(강남스타일) MV.mp4
    ↳ |███████████████████████████████████████| 100.0%

    :param int bytes_received:
        The delta between the total file size (bytes) and bytes already
        written to disk.
    :param int filesize:
        File size of the media stream in bytes.
    :param str ch:
        Character to use for presenting progress segment.
    :param float scale:
        Scale multiplier to reduce progress bar size.
     g      Y@   u    ↳ |z| z%N)
shutilget_terminal_sizecolumnsr   roundfloatsysstdoutr%   flush)r/   r0   r1   r2   r8   	max_widthfilled	remainingprogress_barpercenttexts              r-   display_progress_barrD   .   s    $ &&(00GGeO$Iy>1E(OCDEFF"I;y0LEN*U8_<a@GL>G9C0DJJTJJ    streamchunkbytes_remainingc                 >    | j                   }||z
  }t        ||       y N)r0   rD   )rF   rG   rH   r0   r/   s        r-   on_progressrK   K   s    H/N2rE   targetfilenamec                 *   | j                   dz  }t        |xs | j                   d| d       | j                  ||      }| j	                  |      rt        d|        y | j                  ||       t        j                  j                  d       y )Ni   z | z MBrM   output_pathzAlready downloaded at:
)rP   rM   
)	r0   printdefault_filenameget_file_pathexists_at_pathdownloadr;   r<   r%   )rF   rL   rM   filesize_megabytes	file_paths        r-   	_downloadrY   P   s    G3	X00015G4H
LM$$hF$KIY'(45
OOO:JJTrE   basesubtype
media_typec                     d}	 |  d| d| }t         j                  j                  || d|       }t         j                  j                  |      s|S |dz  }V)a  
    Given a base name, the file format, and the target directory, will generate
    a filename unique for that directory and file format.
    
    :param str base:
        The given base-name.
    :param str subtype:
        The filetype of the video which will be downloaded.
    :param str media_type:
        The media_type of the file, ie. "audio" or "video"
    :param Path target:
        Target directory for download.
    r   _.r5   )r   r   r   exists)rZ   r[   r\   rL   counter	file_namerX   s          r-   _unique_namerc   [   se     G
fAj\7)4	GGLLI;ay)AB	ww~~i(1 rE   
resolutionc                 ^   | j                  t               |xs t        j                         }|dk(  s|dk(  r| j                  j                  d      j                  d      j                         }| j                  j                  dd      j                  d      j                         }|j                  |j                  k(  r|}n.|}n+| j                  j                  d|      j                         }|st        d	|        y| j                  j                  d      j                  d
      j                         }t        | j                  dd|      }t        | j                  dd|      }|j                  ||      }	|j                  ||      }
t        j                  j                  |	      r+t        j                  j                  |
      rt        d       yt!        |||       t!        |||       dd|	d|
dddddd| d| j                   dg}t#        j$                  |       y)a  
    Decides the correct video stream to download, then calls _ffmpeg_downloader.

    :param YouTube youtube:
        A valid YouTube object.
    :param str resolution:
        YouTube video resolution.
    :param str target:
        Target directory for download
    NbestFprogressiverd   mp4rh   r[   )rh   rd   z No streams found for resolution abrvideoaudiorO   z(Already downloaded both video and audio.)rL   rM   ffmpegz-iz-c:vcopyz-c:aaacz-strictexperimental/z.mp4)register_on_progress_callbackrK   r   r    streamsfilterorder_bylastrd   firstrR   rc   titlerT   r   r`   rY   
subprocessrun)r   rd   rL   highest_quality_stream
mp4_streamvideo_streamaudio_streamvideo_file_nameaudio_file_name
video_path
audio_pathcommands               r-   ffmpeg_processr   q   s    ))+6"ryy{FTZ61!(!7!7E!7!J!S!ST`!a!f!f!h__++u+MVVWcdiik
!,,
0E0EE%L1L--%J-W]]_0=>??))e)<EEeLQQSL"7==%&IO"7==%&IO++_RX+YJ++_RX+YJ	ww~~j!bggnnZ&@89l6ODl6OD z4VVVUZ\egu  {A  zB  BC  DK  DQ  DQ  CR  RV  xW  XG NN7rE   c                     t        d| d       | j                  j                  |      j                         }|t        d|        yt	        ||       y)a	  Download a stream by the specified resolution.

    :param YouTube youtube:
        A valid YouTube object.
    :param str resolution:
        The desired resolution of the stream.
    :param Optional[str] target:
        The target directory for the download.
    zDownloading ...)rd   NzNo stream found for resolution )rR   rt   ru   rx   rY   r   rd   rL   rF   s       r-   download_by_resolutionr      sT     
LC
()__##z#:@@BF~/
|<=&&!rE   filetypec                     t        d       | j                  j                  d|      j                  d      j	                         }|t        d|        yt        ||       y)a  Download audio stream of a YouTube video.

    :param YouTube youtube:
        A valid YouTube object.
    :param Optional[str] filetype:
        The filetype for the audio. Defaults to "mp4".
    :param Optional[str] target:
        The target directory for the download.
    zDownloading audio...Frj   rk   Nz#No audio stream found for filetype rR   rt   ru   rv   rw   rY   )r   r   rL   rF   s       r-   download_audior      sZ     

 !__##x#HQQRWX]]_F~3H:>?&&!rE   c                     t        d       | j                  j                  d      j                  d      j	                         }|t        d       yt        ||       y)a  Download a YouTube video stream at the highest resolution.

    :param YouTube youtube:
        A valid YouTube object.
    :param str resolution:
        The resolution of the stream.
    :param Optional[str] target:
        The target directory for the download.
    z4Downloading highest resolution progressive stream...Trg   rd   NzNo progressive stream found.r   r   s       r-   'download_highest_resolution_progressiver      sP     

@A__###5>>|LQQSF~,-&&!rE   itagc                     | j                   j                  |      }|t        d| d       yt        d| d       t        ||       y)zDownload a YouTube stream by its itag.

    :param YouTube youtube:
        A valid YouTube object.
    :param int itag:
        The itag of the desired stream.
    :param Optional[str] target:
        The target directory for the download.
    NzNo stream found with itag r_   zDownloading stream with itag r   )rt   get_by_itagrR   rY   )r   r   rL   rF   s       r-   download_by_itagr      sK     __((.F~*4&23-dV378&&!rE   	lang_codec                     t        d| d       | j                  j                  |      }|t        d| d       y|j                  |       y)a  Download captions for a given YouTube video.

    :param YouTube youtube:
        A valid YouTube object.
    :param str lang_code:
        The language code for the desired captions.
    :param Optional[str] target:
        The target directory for the downloaded captions.
    z#Downloading captions for language: r   Nz%No captions found for language code: r_   )rR   captionsget_by_language_coderV   )r   r   rL   captions       r-   download_captionr      sQ     
/	{#
>?33I>G5i[BC rE   r   c                 r    t        d       | D ]'  }t        d|j                   d|j                          ) y)zPrint available captions for a YouTube video.

    :param List[CaptionQuery] captions:
        The list of available captions.
    zAvailable captions: - z: N)rR   language_codename)r   r   s     r-   _print_available_captionsr      s<     

  =G))*"W\\N;<=rE   c                 t    t        d| j                   d       | j                  D ]  }t        d|         y)zxDisplay available streams for the given YouTube video.

    :param YouTube youtube:
        A valid YouTube object.
    zAvailable streams for :r   N)rR   ry   rt   )r   rF   s     r-   display_streamsr     s;     
"7==/
34// F8nrE   parserargsc                    | j                  ddd       | j                  ddddt         	       | j                  d
t        d       | j                  ddt        d       | j                  dddd       | j                  ddd       | j                  ddddd       | j                  ddd       | j                  ddd        | j                  d!d"t        d#       | j                  d$d%dd&       | j                  d'd(d)*       | j                  d+d,d-dd./       | j                  d0d1d2dd3/       | j	                  |      S )4Nr   z#The YouTube /watch or /playlist url?)helpnargsz-Vz	--versionversionz	%(prog)s )actionr   z--itagzThe itag for the desired stream)typer   z-rz--resolutionz%The resolution for the desired streamz-lz--list
store_truezVThe list option causes pytubefix cli to return a list of streams available to download)r   r   z--oauthzuse oauth tokenz-vz	--verboseverbosez$Set logger output to verbose output.)r   destr   z	--logfilestorez0logging debug and error messages into a log filez--build-playback-reportzSave the html and js to diskz-cz--caption-codezcDownload srt captions for given language code. Prints available language codes if no argument givenz-lcz--list-captionsz(List available caption codes for a videoz-tz--targetzTThe output directory for the downloaded stream. Default is current working directory)r   z-az--audiori   zpDownload the audio for a given URL at the highest bitrate available. Defaults to mp4 format if none is specified)constr   r   z-fz--ffmpegrf   zDownloads the audio and video stream for resolution provided. If no resolution is provided, downloads the best resolution. Runs the command line program ffmpeg to combine the audio and video)add_argumentr   r   str
parse_args)r   r   s     r-   _parse_argsr     s   
$IQTU
k)yQ\P]E^_
s1RS
n3=de
h|  C[  \
	,=NO
k,YU{|
G:lm
1,Mkl
.S  @e  f
0Lvw
j  0F  G
iuC  Gy  z
jc  II  JT""rE   c                 |   t        t        j                        dk(  rt        | d|j                         |j
                  rt        | j                         |j                  rt        |        |j                  r#t        | |j                  |j                         n|j                  r#t        | |j                  |j                         n]|j                  r#t        | |j                  |j                         n.|j                   r"t#        | |j                   |j                         |j$                  r"t'        | |j                  |j                         |j(                  rt)        |        d}d}|j*                  r@d}d}t-        d	       t/        |j0                  ||
      } t        | d|j                         y y )N   highest)r   rd   rL   )r   r   rL   )r   r   rL   )r   r   rL   FTLoading video...)	use_oauthallow_oauth_cache)lenr;   argvr   rL   list_captionsr   r   listr   r   r   caption_coder   rd   r   rm   r   rn   r   r.   oauthrR   r   r   )r   r   r   caches       r-   _perform_args_on_youtuber     s8   
388}/I^b^i^ij!'"2"23yy yytyyM			D4E4EdkkZ	w4??SWS^S^_	wDKKP{{w4??4;;W!!g&EEzz !$((euM/I^b^i^ij rE   c                     t        j                  t        j                        } t	        |       }|j
                  r|j                  nd }t        |j
                  rt        j                  nt        j                  |       |j
                  rt        j                  dt                |j                  rd|j                  vr%| j                          t!        j"                  d       d|j                  v rgt%        d       t'        |j                        }|j(                  xs t+        |j,                        |_        |j.                  D ]  }	 t1        ||        y t%        d	       t7        |j                        }t1        ||       y # t2        j4                  $ r#}t%        d|        t%        |       Y d }~qd }~ww xY w)
N)description)log_filenamezPytubefix version: youtur   z	/playlistzLoading playlist...zThere was an error with video: r   )argparseArgumentParsermain__doc__r   r   logfiler
   loggingDEBUGINFOloggerdebugr   r   
print_helpr;   exitrR   r   rL   r	   ry   videosr   
exceptionsPytubeFixErrorr   )r   r   r   playlistyoutube_videoer   s          r-   r   r   C  sA   $$>FvD#'<<4<<TL$,,GLL|\||*;-8988wdhh.dhh#$DHH%kkB]8>>%B%__ 	M(=	 	 !$((# $/ ,, 7GHas   F

G F;;G __main__)u   █g?)NNrJ   )ri   N)2randomr   r#   r&   r   r   r6   r;   r   r   rz   typingr   r   pytubefix.exceptionsr   	pytubefixr   r   r   r   pytubefix.helpersr	   r
   r   	getLogger__name__r   r.   r   r   r:   rD   bytesrK   rY   rc   r   r   r   r   r   r   r   r   r   	Namespacer   r   r    rE   r-   <module>r      s{        	  
   ! ) ! 4 4 9 			8	$
7 
t 
2   UZ fj :3 3u 3s 3t 3
	f 	hsm 	hsm 	_c 	s S c 3 3 ,/G / /hsm /W[ /b"G " "hsm "_c """G "x} "hWZm "gk """W "# "W_`cWd "pt """g "S "(3- "SW ""!g !# !x} !X\ !"=\(: =t =W  #// #x~ #QYQcQc #$"kg "kX5G5G "kD "kJ0> zF rE   