o
    j;                     @   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   H/home/kuhnn/.local/lib/python3.10/site-packages/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      t d| dd S )Nz!Q   r   structunpackr   r   r   r   r   read_unsigned_long_long!      z!FlvReader.read_unsigned_long_longc                 C   r   )N!I   r   r   r   r   r   r   read_unsigned_int$   r   zFlvReader.read_unsigned_intc                 C   r   )Nz!Br   r   r   r   r   r   r   read_unsigned_char'   r   zFlvReader.read_unsigned_charc                 C   s(   d}	 |  d}|dkr	 |S ||7 }q)N    Tr       )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   	real_sizesizebox_type
header_endr   r   r   read_box_info3   s   
zFlvReader.read_box_infoc                 C   sp   |    | d |   }t|D ]}|   q|  }g }t|D ]}|  }|  }|||f q"d|iS )N   segment_run)r!   r   ranger&   r    append)r   quality_entry_count_segment_run_countsegmentsfirst_segmentfragments_per_segmentr   r   r   	read_asrt?   s   

zFlvReader.read_asrtc           	      C   s   |    | d |   |   }t|D ]}|   q|  }g }t|D ]#}|  }|  }|  }|dkr=|   }nd }|||||d q&d|iS )Nr-   r   )firsttsdurationdiscontinuity_indicator	fragments)r!   r   r    r/   r&   r   r0   )	r   r1   r2   fragments_countr<   r8   first_tsr:   r;   r   r   r   	read_afrtT   s.   



zFlvReader.read_afrtc                 C   s6  |    | d |   |   }|d@ dk}|   |   |   |   |   }t|D ]}|   q/|   }t|D ]}|   q>|   |   |   }g }t|D ]}|  \}}	}
|	dksfJ t|
 }|	| qW|   }g }t|D ]}|  \}}	}
|	dksJ |	t|

  q||||dS )Nr-       r   s   asrts   afrt)r4   r<   live)r!   r   r    r   r&   r/   r,   r   r7   r0   r?   )r   flagsrA   server_countr2   quality_countsegments_countr4   	_box_sizer*   box_datasegmentfragments_run_countr<   r   r   r   	read_abstv   sD   


zFlvReader.read_abstc                 C   s&   |   \}}}|dksJ t| S )Ns   abst)r,   r   rJ   )r   r2   r*   rG   r   r   r   read_bootstrap_info   s   zFlvReader.read_bootstrap_infoN)r
   r   r   __doc__r   r   r    r!   r&   r,   r7   r?   rJ   rK   r   r   r   r   r      s    		"3r   c                 C   s   t |  S N)r   rK   )bootstrap_bytesr   r   r   rK         rK   c           	      C   s   g }| d d }| d d d }|d d }t |}|d D ]\}}|dkr-| d r-d}t|D ]}||t|f q1q| d rH|d	d
 }|S )zE Return a list of (segment, fragment) for each fragment in the video r4   r   r<   r8   r.   l    rA   r   N)	itertoolscountr/   r0   next)		boot_infor$   segment_run_tablefragment_run_entry_tablefirst_frag_numberfragments_counterrH   r=   r2   r   r   r   build_fragments_list   s   
rY   c                 C   s   |  td| d S )Nr   writer   packstreamvalr   r   r   write_unsigned_int   r   r`   c                 C   s   |  td|dd   d S )Nr   r   rZ   r]   r   r   r   write_unsigned_int_24   s   ra   c                 C   s,   |  d |  d |  d |  d dS )zWrites the FLV header to streams   FLV   s      	s       N)r[   )r^   r   r   r   write_flv_header   s   


rc   c                 C   sR   d}d}|r'|  | t| t| |  d |  | t| |t|  dS dS )z&Writes optional metadata tag to stream      s          N)r[   ra   r   r`   )r^   metadata
SCRIPT_TAGFLV_TAG_HEADER_LENr   r   r   write_metadata_tag   s   


ri   c                 C   s   t tdd | S )Nc                 S   s   d| j vo	d| j vS )NdrmAdditionalHeaderIddrmAdditionalHeaderSetId)attrib)er   r   r   <lambda>   s   
 
z(remove_encrypted_media.<locals>.<lambda>)listfilter)mediar   r   r   remove_encrypted_media   s   
rr   c                 C   s   d|| f S )Nz {http://ns.adobe.com/f4m/%d.0}%sr   )propverr   r   r   _add_ns   rO   ru   c                 C   s.   t | tdtddgdd d}|r| }|S )NbaseURLr   zbase URL)default)r   ru   strip)manifestbase_urlr   r   r   get_base_url   s   r{   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s3| td| td D ]}d|jvr.| d q"t|}|s:| d |S )	Nrq   zNo media foundallow_unplayable_formatsdrmAdditionalHeaderdrmAdditionalHeaderSetidzMissing ID in f4m DRMzUnsupported DRM)findallru   report_errorparamsgetrl   rr   )r   docrq   rm   r   r   r   _get_unencrypted_media   s   



zF4mFD._get_unencrypted_mediac                 C   s   | j | }t|S rM   )ydlurlopenr   rK   )r   bootstrap_url	bootstrapr   r   r   _get_bootstrap_from_url  s   zF4mFD._get_bootstrap_from_urlc                    sl   g }d}|s-|dkr-|  |}t|} fdd|D }|s'td |d8 }|s-|dks
|s4| 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)r   rY   timesleepr   )r   r   r   fragments_listretriesrT   r   r   r   _update_live_fragments  s   

	
zF4mFD._update_live_fragmentsc                 C   sN   | d}|rtj||}| |}||fS d }t|j}t|}||fS )Nurl)	r   urllibparseurljoinr   base64	b64decodetextrK   )r   noderz   r   rT   r   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 u sDt|d	krSt|d
d d}|d \}}	ntt fdd|\}}	t|pe|}
tj|
|	jd }|td}| ||
\}}|d }|	td}|d urt|j}nd }t|}| j dd}|r|d d	 }t|}t|td}||t|d}|  | |d }|d dkrt!| |st"|| tj#|}| $|| d}|r|%d\}}|d	7 }||d krqd||f }g }|j&r|'|j& |r|'|
d | dr$|'|d  |j(|j)| d*|d}zF| +||, |}|sAW dS | -|} t.| }!	 z	|!/ \}}"}#W n t0yg   |rf|1|  Y n w |"d krt| 2||# nqKW n/ t3y }$ z"|r|$j4d!ks|$j4d"krd#| }%| 5|% g }n W Y d }$~$nd }$~$ww |s|s|r|r| 6||}|t|7 }|r|d d	 |d	 krd$|d d	 |d	   }%| 5|% |s| 7||S )%Nr   tbr[z] Downloading f4m manifestzutf-8ignorec                 S   s"   g | ]}t |jd d|fqS )bitrate)intrl   r   r   r   r   r   r   B  s    z'F4mFD.real_download.<locals>.<listcomp>r   c                 S   s   | d S Nr   r   r   r   r   r   rn   F  s    z%F4mFD.real_download.<locals>.<lambda>)keyr   c                    s   t | d  kS r   )r   r   requested_bitrater   r   rn   J  s    bootstrapInforA   rf   testFzpv-2.0)filenametotal_fragsrA   dest_streamcomplete_frags_downloaded_bytesr   fragment_indexzSeg%d-Frag%d;extra_param_to_segment_url&)pathqueryTs   mdati  i  zFragment %d unavailablezMissed %d fragments)8r   	to_screenFD_NAMEr   r   _prepare_urlr   r   r   decoderx   r   r   r   sortedrS   rp   r{   r   r   r   rl   findru   r   r   r   r   rY   r   r   bool_prepare_frag_downloadrc   ri   urlparse_start_frag_downloadpopr   r0   _replacer   join_download_fragmentgeturl_read_fragmentr   r,   r	   r[   _append_fragmentr   statusreport_warningr   _finish_frag_download)&r   r   	info_dictman_urlurlhry   r   formatsr2   rq   man_base_urlrz   bootstrap_noderT   r   rA   metadata_noderf   r   r   r   	akamai_pvctxr   base_url_parsed
frag_indexseg_ifrag_inamer   
url_parsedsuccess	down_datareaderr*   rG   errmsgr   r   r   real_download5  s   






	


4zF4mFD.real_downloadN)	r
   r   r   rL   r   r   r   r   r   r   r   r   r   r|      s    r|   r   )r   iorQ   r   r   urllib.parser   fragmentr   compatr   networking.exceptionsr   utilsr   r   	Exceptionr	   BytesIOr   rK   rY   r`   ra   rc   ri   rr   ru   r{   r|   r   r   r   r   <module>   s.     	
	