U
    gF                     @   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 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urljoinc                   @   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
    Z	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   9/tmp/pip-unpacked-wheel-q5ljy6pj/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   s>    d V   D ]} t|  V  qs: V  d S )NZis_live)getr   r   r   )ZfeatureZUNSUPPORTED_FEATURESallow_unplayable_formatscls	info_dictr   r   r   check_resultsA   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j d j||}|j}| dd}||j	
dd  }}|rt }tj o|d|k}	|	r|rd\}}n<|	rd	}n2|
d
dkrtd|r|rdnd}
d|
 d}|sn|r2j	
ds2|
dr j	
dr j dj ddd njddd dS |p:d}tjj	}| d|   |||S |r~| |d dk}|rd }nt|j	d d|dkd}|r||sd }|r dj d |   d!d" }d#d$ }g }d%}d%}d}| D ]`}| }|s$q|d&rR||r@d}n||rd}q|rd|d'7 }q|d'7 }q|||d(}|r| n|| |d)i  |
d*}d }|
d+ }rtj |}d }|
d, }rtj |}d%}d%}d-d.i}t!|d/}|r6t"#t$|d0}t%|d1ks6t&d2t!|d3}|r\t"#t$|d0'd4}i } d%}!d%}"d}| D ]}| }|rt|d&s|r|!|krqt|rqt|"d'7 }"|"|d5 kr̐qtt(||}#|rt)|#|}#|*|"|#|| |d6 |d'7 }n^|d7r|r(|!|kr(qt|"d%krBd8  dS |"d'7 }"t+|d9d  }$t(||$
d:}#|rzt)|#|}#|$
d;r|$
d;,d<}%t%|%d=krt-|%d' n| d> }&|&|&t-|%d%  d?} |*|"|#|| |d6 |d'7 }nv|d@r|
d:}'t+|d9d  }|d- dAkrf|r4||dB< n*dB|kr^t"#|dB d=d  'd4|dB< |rn||dC< nLt(||d: |d:< |s|rt)|d: |p||d:< |'|d: krfd |dC< n|dDrt-|dEd  }n|dFr2|dGd  ,d<}%t%|%d=krt-|%d' n| d> }&|&|&t-|%d%  d?} n4||rBd}n$||rRd}n|dHrf|!d'7 }!|d'7 }qtj	
ddr|r|d% nd g}|r||dI< |jj	}|||S |r fdJdK}( fdLdM})t%|d'kr.||| nj.||||(|)dN n.|||S d S )ONurl[z] Downloading m3u8 manifestzutf-8ignorer   z#EXT-X-KEY:METHOD=AES-128)FzDThe stream has AES-128 encryption and pycryptodomex is not availablezThe stream has AES-128 encryption and neither ffmpeg nor pycryptodomex are available; Decryption will be performed natively, but will be extremely slowZ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 commandZhas_drmtestz] This format is DRM protectedT)Zskip_eolzThis format is DRM protected; Try selecting another format with --format or add --check-formats to automatically fallback to the next best formatF)tbz'Unsupported features have been detectedz"; extraction will be delegated to extZvttZm3u8_frag_urls-)protocolZ	to_stdoutz*] Fragment downloads will be delegated to c                 S   s&   |  drd| kp$|  do$| dS )N#ANVATO-SEGMENT-INFOztype=ad#UPLYNK-SEGMENTz,ad
startswithendswithsr   r   r   is_ad_fragment_starty   s    z1HlsFD.real_download.<locals>.is_ad_fragment_startc                 S   s&   |  drd| kp$|  do$| dS )Nr+   ztype=masterr,   z,segmentr-   r0   r   r   r   is_ad_fragment_end}   s    z/HlsFD.real_download.<locals>.is_ad_fragment_endr   #r   )filenameZtotal_fragsad_fragsextra_stateformat_indexextra_param_to_segment_urlextra_param_to_key_urlZMETHODNONE)hls_aeskey0x)          z"Invalid length for HLS AES-128 key)r<   ZivrA   Zfragment_index)
frag_indexr!   decrypt_info
byte_rangemedia_sequencez
#EXT-X-MAPzGInitialization fragment found after media fragments, unable to download   URIZ	BYTERANGE@r   end)startrI   z
#EXT-X-KEYzAES-128ZIVZKEYz#EXT-X-MEDIA-SEQUENCE   z#EXT-X-BYTERANGE   z#EXT-X-DISCONTINUITY	fragmentsc                    sP  t  }d}d}d }t| D ]"}t|tjr,| d< |rR d  d7  < d}| j|7  _| j|7  _ dg }g }d}	d}
|	t	|k r||	 }tj
|}|	d7 }	||r|j|d< d}
q||krd}
q|j|jkrq|| |	d8 }	||	= q|
r||j |D ]}|| qqnt|tjr|jd krLd|_ dd | j d d	> 7  _|j ddk rd}| jd
7  _|j}|dkr|jpd d< |jpd d< n:|jd k	r|jd k	r|j dd |j dd  }qn6t|tjr8|dkr8tdt|j d q|| q|  S )Nr   FZwebvtt_mpegts_lastZwebvtt_mpegts_adjustr   webvtt_dedup_windowTrI   !   l        Zwebvtt_mpegtsZwebvtt_localzDiscarding a zO block found in the middle of the stream; if the subtitles display incorrectly,)ioStringIOr   Zparse_fragment
isinstanceCueBlockrJ   rI   
setdefaultlen	from_jsonZhingesappendZas_json
write_intoZMagicZmpegtsr   localZHeaderBlockreport_warningr	   type__name__getvalueencode)Zfrag_contentrB   outputadjustZoverflowZmpegts_lastblockdedup_windowreadyiZis_newZwcueZwblockr7   selfr   r   pack_fragment  s~    




z*HlsFD.real_download.<locals>.pack_fragmentc                     sB     d} | sdS t }| D ]}tj|| q|  S )NrN       )	r   rP   rQ   r   rS   rV   rX   r]   r^   )rb   r_   Zcue)r7   r   r   fin_fragmentsl  s    
z*HlsFD.real_download.<locals>.fin_fragments)Z	pack_funcZfinish_func)/Z	to_screenFD_NAMEZydlurlopenZ_prepare_urlr!   readdecoder    paramsr   r   	availabler   ZAESr   r   r   Zreport_errorrZ   Zget_basenamereal_downloadr   Zsupports_manifest
splitlinesstripr.   Z_prepare_external_frag_downloadZ _prepare_and_start_frag_downloadrT   urllibparseparse_qsr   binascii	unhexlifyr   rU   AssertionErrorzfillr   r   rW   r
   splitintZdownload_and_append_fragments)*rf   r5   r   Zman_urlZurlhr1   r    messageZ
has_ffmpegZ	no_cryptoZinstall_ffmpegfdZ	is_webvttZreal_downloaderr2   r3   rM   Zmedia_fragsr6   Zad_frag_nextlinectxr8   Zextra_segment_queryr9   Zextra_key_queryr:   rd   rE   rC   Zexternal_aes_keyZexternal_aes_ivrD   Zdiscontinuity_countrB   Zfrag_urlZmap_infoZsplitted_byte_rangeZsub_range_startZdecrypt_urlrg   ri   r   re   r   rp   I   s   


    








"


 
 
"

N    zHlsFD.real_downloadN)F)
r\   
__module____qualname____doc__rj   staticmethodr   classmethodr    rp   r   r   r   r   r      s   
!r   )rv   rP   r   urllib.parsers   r%   r   Zexternalr   fragmentr   r   Zdependenciesr   utilsr	   r
   r   r   r   r   r   r   r   r   r   <module>   s    
