o
    igL                     @   s   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
 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 dd
lmZ G dd de
ZdS )    N   )get_suitable_downloader)FFmpegFD)
FragmentFD   )webvtt)
Cryptodome)bug_reports_messageparse_m3u8_attributesremove_starttraverse_objupdate_url_queryurljoin)_request_dump_filenamec                   @   s6   e Zd ZdZdZedd ZedddZdd	 Z	d
S )HlsFDz
    Download segments in a m3u8 manifest. External downloaders can take over
    the fragment downloads by supporting the 'm3u8_frag_urls' protocol and
    re-defining 'supports_manifest' function
    	hlsnativec                 C   s   t tdd| S )N|)z&#EXT-X-(?:SESSION-)?KEY:.*?URI="skd://zG#EXT-X-(?:SESSION-)?KEY:.*?KEYFORMAT="com\.apple\.streamingkeydelivery"z@#EXT-X-(?:SESSION-)?KEY:.*?KEYFORMAT="com\.microsoft\.playready"z#EXT-X-FAXS-CM:)boolresearchjoin)manifest r   I/home/ubuntu/.local/lib/python3.10/site-packages/yt_dlp/downloader/hls.py_has_drm   s   zHlsFD._has_drmFc                    s0   g  s	 dg7   fdd}t | S )Nz"#EXT-X-KEY:METHOD=(?!NONE|AES-128)c                  3   sD     d V   D ]
} t|  V  q
s  V  d S d S )Nis_live)getr   r   r   )featureUNSUPPORTED_FEATURESallow_unplayable_formatscls	info_dictr   r   r   check_resultsB   s   z)HlsFD.can_download.<locals>.check_results)all)r!   r   r"   r    r#   r   r   r   can_download(   s   
zHlsFD.can_downloadc           /   	      s  |d }| d}|rdj d n[dj d j||}|j}| }j drkt	||d d j dd	}dj d
|  t
|d}|| W d    n1 sfw   Y  |dd}||j dd }	}
|	rt }tjsd|v rt|dtf }d|r|sdnd}
|r|rd}	n|
d7 }
n| ddkrtd|r|rdnd}d| d}
|	s|rj ds| drj drjdj dd d! dS jd"dd# dS |
pd$}
tjj}|
 d%|   |||S |
r|
 |d& d'k}|r%d }nt|jd d(|d)kd*}|r<||s<d }|rMdj d+|   d,d- }d.d/ }g }d0}d0}d}| D ]0}| }|slqa| d1r||rzd }n||rd}qa|r|d27 }qa|d27 }qa|||d3}|r!| n"|| |#d4i  | d5}d }| d6 }rt$j%&|}d }| d7 }rt$j%&|}d0}d0}d8d9i} t|d:}!|!rt'(t)|!d;}!t*|!d<v sJ d=t|d>}"|"rt'(t)|"d;+d?}"i }#d0}$d0}%d0}&d}| D ]}| }|r| d1sk|d ur2|%|kr2q|r7q|&d27 }&|&|d@ krDqt,||}'|rQt-|'|}'|.|&|'| |#|dA |d27 }|#ri|#dB }$i }#n.| dCr|d ur}|%|kr}q|&d0krdD  dS |&d27 }&t/|dEd  }(t,||( dF}'|rt-|'|}'i })|( dGr|( dG0dH}*t*|*dIkrt1|*d2 nd0}+|+|+t1|*d0  dJ})|.|&|'| |)|dA |d27 }n| dKrF|  dF},t/|dEd  } | d8 dLkrE|"r|"| dM< ndM| v rt'(| dM dId  +d?| dM< |!r|!| dN< nzt,|| dF | dF< |s.|r:t-| dF |p6|| dF< |,| dF krEd | dN< nS| dOrUt1|dPd  }nD| dQr|dRd  0dH}*t*|*dIkrqt1|*d2 n|$}+|+|+t1|*d0  dJ}#n||rd }n||rd}n
| dSr|%d27 }%|d27 }qj ddr|r|d0 nd g}|r||dT< |jj}|||S |r fdUdV}- fdWdX}.t*|d2kr2||| d S j2||||-|.dY d S 2|||S )ZNurlhls_media_playlist_data[z)] Using m3u8 manifest from extracted infoz] Downloading m3u8 manifestwrite_pagesidtrim_file_name)trim_lengthz] Saving request to wbzutf-8ignorer    z#EXT-X-KEY:METHOD=AES-128)extra_param_to_segment_urlextra_param_to_key_urlr'   )hls_aes)urikeyivz2The stream has AES-128 encryption and {} availablez$neither ffmpeg nor pycryptodomex arezpycryptodomex is notFzC; decryption will be performed natively, but will be extremely slowextractor_keyGenericz (?m)#EXT-X-MEDIA-SEQUENCE:(?!0$) zinstall ffmpeg and z]Live HLS streams are not supported by the native downloader. If this is a livestream, please z:add "--downloader ffmpeg --hls-use-mpegts" to your commandhas_drmtestz] This format is DRM protectedT)skip_eolzThis format is DRM protected; Try selecting another format with --format or add --check-formats to automatically fallback to the next best format)tbz'Unsupported features have been detectedz"; extraction will be delegated to extvttm3u8_frag_urls-)protocol	to_stdoutz*] Fragment downloads will be delegated to c                 S   &   |  dr	d| v p|  do| dS )N#ANVATO-SEGMENT-INFOztype=ad#UPLYNK-SEGMENTz,ad
startswithendswithsr   r   r   is_ad_fragment_start      z1HlsFD.real_download.<locals>.is_ad_fragment_startc                 S   rB   )NrC   ztype=masterrD   z,segmentrE   rH   r   r   r   is_ad_fragment_end   rK   z/HlsFD.real_download.<locals>.is_ad_fragment_endr   #r   )filenametotal_fragsad_fragsextra_stateformat_indexr/   r0   METHODNONE)r1   r3   0x)          z"Invalid length for HLS AES-128 key)r1   r4   rX   fragment_index)
frag_indexr&   decrypt_info
byte_rangemedia_sequenceendz
#EXT-X-MAPzGInitialization fragment found after media fragments, unable to download   URI	BYTERANGE@r   )startr^   z
#EXT-X-KEYzAES-128IVKEYz#EXT-X-MEDIA-SEQUENCE   z#EXT-X-BYTERANGE   z#EXT-X-DISCONTINUITY	fragmentsc                    sB  t  }d}d}d }t| D ]
}t|tjr| d< |r( d  d7  < d}| j|7  _| j|7  _ dg }g }d}	d}
|	t	|k r||	 }tj
|}|	d7 }	||rc|j|d< d}
qB||krjd}
qB|j|jkrqqB|| |	d8 }	||	= |	t	|k sH|
r||j |D ]}|| qqt|tjr|jd u rd|_ dd | j d d	> 7  _|j ddk rd}| jd
7  _|j}|dkr|jpd d< |jpd d< n8|jd ur|jd ur|j dd |j dd  }qt|tjr|dkrtdt|j d q|| q|  S )Nr   Fwebvtt_mpegts_lastwebvtt_mpegts_adjustr   webvtt_dedup_windowTr^   !   l        webvtt_mpegtswebvtt_localzDiscarding a zO block found in the middle of the stream; if the subtitles display incorrectly,)ioStringIOr   parse_fragment
isinstanceCueBlockrc   r^   
setdefaultlen	from_jsonhingesappendas_json
write_intoMagicmpegtsr   localHeaderBlockreport_warningr	   type__name__getvalueencode)frag_contentrZ   outputadjustoverflowmpegts_lastblockdedup_windowreadyiis_newwcuewblockrQ   selfr   r   pack_fragment:  s   




z*HlsFD.real_download.<locals>.pack_fragmentc                     sB     d} | s	dS t }| D ]}tj|| q|  S )Nrk       )	r   ro   rp   r   rs   rv   rz   r   r   )r   r   cue)rQ   r   r   fin_fragments  s   
z*HlsFD.real_download.<locals>.fin_fragments)	pack_funcfinish_func)3r   	to_screenFD_NAMEydlurlopen_prepare_urlr&   readparamsr   openwritedecoder%   r   	availabler   AESr   anyformatr   r   r   report_errorr   get_basenamereal_downloadr   supports_manifest
splitlinesstriprF   _prepare_external_frag_download _prepare_and_start_frag_downloadrt   urllibparseparse_qsbinascii	unhexlifyr   ru   zfillr   r   rx   r
   splitintdownload_and_append_fragments)/r   rN   r"   man_urlrI   urlhs_bytesdump_filenameoutfr%   message
has_ffmpegffmpeg_can_dlinstall_ffmpegfd	is_webvttreal_downloaderrJ   rL   rh   media_fragsrP   ad_frag_nextlinectxrR   extra_segment_queryr/   extra_key_queryr0   r   r]   r[   external_aes_keyexternal_aes_ivr\   byte_range_offsetdiscontinuity_countrZ   frag_urlmap_infomap_byte_rangesplitted_byte_rangesub_range_startdecrypt_urlr   r   r   r   r   r   J   s  

















 


N

zHlsFD.real_downloadN)F)
r   
__module____qualname____doc__r   staticmethodr   classmethodr%   r   r   r   r   r   r      s    
!r   )r   ro   r   urllib.parser   r7   r   externalr   fragmentr   r   dependenciesr   utilsr	   r
   r   r   r   r   utils._utilsr   r   r   r   r   r   <module>   s     