U
    àM‘fë;  ã                   @   sä   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 ddlmZmZ G dd	„ d	eƒZG d
d„ dejƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd dd„Zdd„ ZG dd„ deƒZdS )!é    Né   )Ú
FragmentFDé   )Úcompat_etree_fromstring)Ú	HTTPError)Úfix_xml_ampersandsÚ
xpath_textc                   @   s   e Zd ZdS )ÚDataTruncatedErrorN)Ú__name__Ú
__module__Ú__qualname__© r   r   ú9/tmp/pip-unpacked-wheel-zk9bgjdq/yt_dlp/downloader/f4m.pyr	      s   r	   c                   @   s`   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZdS )Ú	FlvReaderzi
    Reader for Flv files
    The file format is documented in https://www.adobe.com/devnet/f4v.html
    c                 C   s.   |   |¡}t|ƒ|k r*td|t|ƒf ƒ‚|S )Nz6FlvReader error: need %d bytes while only %d bytes got)ÚreadÚlenr	   )ÚselfÚnÚdatar   r   r   Ú
read_bytes   s    
 ÿÿzFlvReader.read_bytesc                 C   s   t  d|  d¡¡d S )Nz!Qé   r   ©ÚstructÚunpackr   ©r   r   r   r   Úread_unsigned_long_long!   s    z!FlvReader.read_unsigned_long_longc                 C   s   t  d|  d¡¡d S )Nú!Ié   r   r   r   r   r   r   Úread_unsigned_int$   s    zFlvReader.read_unsigned_intc                 C   s   t  d|  d¡¡d S )Nz!Br   r   r   r   r   r   r   Úread_unsigned_char'   s    zFlvReader.read_unsigned_charc                 C   s&   d}|   d¡}|dkrq"||7 }q|S )Nó    r   ó    )r   )r   ÚresÚcharr   r   r   Úread_string*   s    

zFlvReader.read_stringc                 C   sB   |   ¡  }}|  d¡}d}|dkr.|  ¡ }d}|||  || ¡fS )z[
        Read a box and return the info as a tuple: (box_size, box_type, box_data)
        r   r   r   é   )r   r   r   )r   Z	real_sizeÚsizeÚbox_typeZ
header_endr   r   r   Úread_box_info3   s    
zFlvReader.read_box_infoc                 C   sp   |   ¡  |  d¡ |   ¡ }t|ƒD ]}|  ¡  q"|  ¡ }g }t|ƒD ]"}|  ¡ }|  ¡ }| ||f¡ qDd|iS )Né   Úsegment_run)r   r   Úranger$   r   Úappend)r   Úquality_entry_countÚ_Zsegment_run_countÚsegmentsZfirst_segmentZfragments_per_segmentr   r   r   Ú	read_asrt?   s    

 ÿzFlvReader.read_asrtc           	      C   sœ   |   ¡  |  d¡ |  ¡  |   ¡ }t|ƒD ]}|  ¡  q*|  ¡ }g }t|ƒD ]F}|  ¡ }|  ¡ }|  ¡ }|dkrz|   ¡ }nd }| ||||dœ¡ qLd|iS )Nr)   r   )ÚfirstÚtsÚdurationÚdiscontinuity_indicatorÚ	fragments)r   r   r   r+   r$   r   r,   )	r   r-   r.   Úfragments_countr5   r1   Zfirst_tsr3   r4   r   r   r   Ú	read_afrtT   s0    


ü
 ÿzFlvReader.read_afrtc                 C   s8  |   ¡  |  d¡ |  ¡  |   ¡ }|d@ dk}|  ¡  |  ¡  |  ¡  |  ¡  |   ¡ }t|ƒD ]}|  ¡  q^|   ¡ }t|ƒD ]}|  ¡  q||  ¡  |  ¡  |   ¡ }g }t|ƒD ]4}|  ¡ \}}	}
|	dksÌt‚t|
ƒ 	¡ }| 
|¡ q®|   ¡ }g }t|ƒD ]2}|  ¡ \}}	}
|	dkst‚| 
t|
ƒ ¡ ¡ qø|||dœS )Nr)   é    r   s   asrts   afrt)r/   r5   Úlive)r   r   r   r   r$   r+   r(   ÚAssertionErrorr   r0   r,   r7   )r   Úflagsr9   Zserver_countr.   Zquality_countZsegments_countr/   Zbox_sizer'   Úbox_dataÚsegmentZfragments_run_countr5   r   r   r   Ú	read_abstv   sD    


ýzFlvReader.read_abstc                 C   s&   |   ¡ \}}}|dkst‚t|ƒ ¡ S )Ns   abst)r(   r:   r   r>   )r   Z
total_sizer'   r<   r   r   r   Úread_bootstrap_info©   s    zFlvReader.read_bootstrap_infoN)r
   r   r   Ú__doc__r   r   r   r   r$   r(   r0   r7   r>   r?   r   r   r   r   r      s   		"3r   c                 C   s   t | ƒ ¡ S ©N)r   r?   )Zbootstrap_bytesr   r   r   r?   ¯   s    r?   c           	      C   s”   g }| d d }| d d d }|d d }t  |¡}|d D ]<\}}|dkrZ| d rZd}t|ƒD ]}| |t|ƒf¡ qbq>| d r|d	d
… }|S )zE Return a list of (segment, fragment) for each fragment in the video r/   r   r5   r1   r*   l   ÿÿ r9   r   éþÿÿÿN)Ú	itertoolsÚcountr+   r,   Únext)	Ú	boot_infor"   Zsegment_run_tableZfragment_run_entry_tableZfirst_frag_numberZfragments_counterr=   r6   r.   r   r   r   Úbuild_fragments_list³   s    
rG   c                 C   s   |   t d|¡¡ d S )Nr   ©Úwriter   Úpack©ÚstreamÚvalr   r   r   Úwrite_unsigned_intÉ   s    rN   c                 C   s   |   t d|¡dd … ¡ d S )Nr   r   rH   rK   r   r   r   Úwrite_unsigned_int_24Í   s    rO   c                 C   s,   |   d¡ |   d¡ |   d¡ |   d¡ dS )zWrites the FLV header to streams   FLVó   s      	s       N)rI   )rL   r   r   r   Úwrite_flv_headerÑ   s    


rQ   c                 C   sN   d}d}|rJ|   |¡ t| t|ƒƒ |   d¡ |   |¡ t| |t|ƒ ƒ dS )z&Writes optional metadata tag to streamó   é   s          N)rI   rO   r   rN   )rL   ÚmetadataZ
SCRIPT_TAGZFLV_TAG_HEADER_LENr   r   r   Úwrite_metadata_tagÚ   s    


rU   c                 C   s   t tdd„ | ƒƒS )Nc                 S   s   d| j kod| j kS )NZdrmAdditionalHeaderIdZdrmAdditionalHeaderSetId)Úattrib)Úer   r   r   Ú<lambda>è   s   
z(remove_encrypted_media.<locals>.<lambda>)ÚlistÚfilter)Úmediar   r   r   Úremove_encrypted_mediaç   s    
þr\   c                 C   s   d|| f S )Nz {http://ns.adobe.com/f4m/%d.0}%sr   )ÚpropÚverr   r   r   Ú_add_nsí   s    r_   c                 C   s.   t | tdƒtddƒgdd d}|r*| ¡ }|S )NZbaseURLr   zbase URL)Údefault)r   r_   Ústrip)ÚmanifestÚbase_urlr   r   r   Úget_base_urlñ   s      þrd   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚF4mFDz5
    A downloader for f4m manifests or AdobeHDS.
    c                 C   sx   |  tdƒ¡}|s|  d¡ | j d¡sf|  tdƒ¡|  tdƒ¡ D ]}d|jkrD|  d¡ qDt|ƒ}|st|  d¡ |S )	Nr[   zNo media foundZallow_unplayable_formatsZdrmAdditionalHeaderZdrmAdditionalHeaderSetÚidzMissing ID in f4m DRMzUnsupported DRM)Úfindallr_   Úreport_errorÚparamsÚgetrV   r\   )r   Údocr[   rW   r   r   r   Ú_get_unencrypted_mediaÿ   s    
ÿ

zF4mFD._get_unencrypted_mediac                 C   s   | j  |¡ ¡ }t|ƒS rA   )ÚydlÚurlopenr   r?   )r   Úbootstrap_urlÚ	bootstrapr   r   r   Ú_get_bootstrap_from_url  s    zF4mFD._get_bootstrap_from_urlc                    sb   g }d}|sP|dkrP|   |¡}t|ƒ}‡ fdd„|D ƒ}|st d¡ |d8 }q|s^|  d¡ |S )Né   r   c                    s   g | ]}|d  ˆ kr|‘qS )r   r   ©Ú.0Úf©Úlatest_fragmentr   r   Ú
<listcomp>  s      z0F4mFD._update_live_fragments.<locals>.<listcomp>g      @r   zFailed to update fragments)rq   rG   ÚtimeÚsleeprh   )r   ro   rw   Úfragments_listÚretriesrF   r   rv   r   Ú_update_live_fragments  s    



zF4mFD._update_live_fragmentsc                 C   sH   |  d¡}|r(tj ||¡}|  |¡}nd }t |j¡}t|ƒ}||fS )NÚurl)	rj   ÚurllibÚparseÚurljoinrq   Úbase64Ú	b64decodeÚtextr?   )r   Únoderc   ro   rF   rp   r   r   r   Ú_parse_bootstrap_node$  s    
 ÿzF4mFD._parse_bootstrap_nodec           '   
      sÞ  |d }|  d¡‰ |  d| j› d¡ | j |  ||¡¡}|j}t| ¡  	dd¡ƒ 
¡ }t|ƒ}dd„ |  |¡D ƒ}ˆ d ksˆt|ƒd	kr¦t|d
d„ d}|d \}}	ntt‡ fdd„|ƒƒ\}}	t|ƒpÊ|}
tj |
|	jd ¡}| tdƒ¡}|  ||
¡\}}|d }|	 tdƒ¡}|d k	r,t |j¡}nd }t|ƒ}| j  dd¡}|rX|d d	… }t|ƒ}t|tdƒƒ}||t|ƒdœ}|   |¡ |d }|d dkr¶t!|ƒ |s¶t"||ƒ tj #|¡}|  $||¡ d}|rÒ| %d¡\}}|d	7 }||d kr qÒd||f }g }|j&r$| '|j&¡ |r:| '| 
d¡¡ |  d¡rT| '|d ¡ |j(|j)| d *|¡d}z”|  +|| ,¡ |¡}|sŽW dS |  -|¡} t.| ƒ}!z|! /¡ \}"}#}$W n. t0k
rà   |rÚ| 1| ¡ Y q ‚ Y nX |#dkr |  2||$¡ q q W n\ t3k
r^ }% z<|rL|%j4d ks4|%j4d!krLd"| }&|  5|&¡ g }n‚ W 5 d }%~%X Y nX |sÒ|sÒ|rÒ|rÒ|  6||¡}|t|ƒ7 }|rÒ|d d	 |d	 krÒd#|d d	 |d	   }&|  5|&¡ qÒ|  7||¡S )$Nr~   Ztbrú[z] Downloading f4m manifestzutf-8Úignorec                 S   s"   g | ]}t |j d d¡ƒ|f‘qS )Zbitrateéÿÿÿÿ)ÚintrV   rj   rs   r   r   r   rx   B  s   ÿz'F4mFD.real_download.<locals>.<listcomp>r   c                 S   s   | d S ©Nr   r   ©ru   r   r   r   rX   F  r    z%F4mFD.real_download.<locals>.<lambda>)Úkeyr‰   c                    s   t | d ƒˆ kS r‹   )rŠ   rŒ   ©Zrequested_bitrater   r   rX   J  r    ZbootstrapInfor9   rT   ÚtestFzpv-2.0)ÚfilenameÚtotal_fragsr9   Údest_streamZcomplete_frags_downloaded_bytesr   Zfragment_indexzSeg%d-Frag%dú;Zextra_param_to_segment_urlú&)ÚpathÚquerys   mdati”  iš  zFragment %d unavailablezMissed %d fragments)8rj   Z	to_screenZFD_NAMErm   rn   Z_prepare_urlr~   r   r   Údecodera   r   rl   r   ÚsortedrE   rZ   rd   r   r€   r   rV   Úfindr_   r†   r‚   rƒ   r„   rG   ri   r   ÚboolZ_prepare_frag_downloadrQ   rU   ÚurlparseZ_start_frag_downloadÚpopr–   r,   Ú_replacer•   ÚjoinZ_download_fragmentÚgeturlZ_read_fragmentr   r(   r	   rI   Z_append_fragmentr   ÚstatusZreport_warningr}   Z_finish_frag_download)'r   r   Z	info_dictZman_urlZurlhrb   rk   ÚformatsZrater[   Zman_base_urlrc   Zbootstrap_noderF   ro   r9   Zmetadata_noderT   r{   r   r‘   Z	akamai_pvÚctxr’   Zbase_url_parsedZ
frag_indexZseg_iZfrag_iÚnamer–   Z
url_parsedÚsuccessZ	down_dataÚreaderr.   r'   r<   ÚerrÚmsgr   rŽ   r   Úreal_download5  s¶    
ÿ
 ÿ
 ÿ
ý





zF4mFD.real_downloadN)	r
   r   r   r@   rl   rq   r}   r†   r¨   r   r   r   r   re   ú   s   re   )r   )r‚   ÚiorC   r   ry   Úurllib.parser   Úfragmentr   Úcompatr   Znetworking.exceptionsr   Úutilsr   r   Ú	Exceptionr	   ÚBytesIOr   r?   rG   rN   rO   rQ   rU   r\   r_   rd   re   r   r   r   r   Ú<module>   s,    	
	