U
    g                     @   sD  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
 ddlmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z" ddd	d
d
ddddddddZ#dddddddddZ$dd Z%dd Z&G dd  d eZ'G d!d" d"e
Z(G d#d$ d$e(Z)G d%d& d&e(Z*G d'd( d(e*Z+G d)d* d*e(Z,G d+d, d,e(Z-G d-d. d.e(Z.G d/d0 d0e(Z/G d1d2 d2e/Z0G d3d4 d4e/Z1G d5d6 d6e/Z2G d7d8 d8e/Z3G d9d: d:e/Z4G d;d< d<e4Z5G d=d> d>e4Z6G d?d@ d@e(Z7G dAdB dBe(Z8G dCdD dDe(Z9G dEdF dFe(Z:dS )G    N   )PostProcessor   )imghdr)MEDIA_EXTENSIONSISO639UtilsPopenPostProcessingError_get_exe_version_outputdeprecation_warningdetect_exe_versiondetermine_extdfxp2srtencodeArgumentencodeFilenamefilter_dictfloat_or_noneis_outdated_version
orderedSetprepend_extensionreplace_extensionshell_quotetraverse_objvariadicwrite_json_fileadtsflacZipodZmatroskaZmpegoggmpegtsZasfwebmwebvtt)aacr   m4amkamkvZmpgZogvtswmaZwmvZwebavtt)mp3
libmp3lame )r"   r!   )-fr   )r"   r!   )-bsf:aaac_adtstoasc)opusZlibopusr*   )r   	libvorbisr*   )r   r   r*   )r"   N)-acodecalac)wavN)r+   r2   )r(   r!   r"   r.   vorbisr   r1   r2   c              	   C   s   t ddd| S )Nz{0}(?:/{0})*$z(?:\s*\w+\s*>)?\s*(?:{})\s*|)recompileformatjoin)	supportedr*   r*   ?/tmp/pip-unpacked-wheel-q5ljy6pj/yt_dlp/postprocessor/ffmpeg.pycreate_mapping_re@   s    r;   c                 C   s|   |  dD ]^}|dd}t|dks:|d  | kr|d  }|| kr`|d|  f  S |df  S qdd|  fS )	zo
    Get corresponding item from a mapping string like 'A>B/C>D/E'
    @returns    (target, error_message)
    />r   r   zalready is in target format Nzcould not find a mapping for )lowersplitlenstrip)sourcemappingpairkvtargetr*   r*   r:   resolve_mappingD   s    rH   c                   @   s   e Zd ZdS )FFmpegPostProcessorErrorN)__name__
__module____qualname__r*   r*   r*   r:   rI   S   s   rI   c                   @   s  e Zd ZejdddZdJddZedKddZedLdd	Z	d
ddZ
dd Zddii  ZZdd Zedd Zejdd Zejdd Zdd Zejdd Zejdd Zedd Zedd  Zed!d" Zed#d$ ZedMdd&d'd(Zd)d* Zd+d, Zg fd-d.Zd/d0 Z d1d2 Z!dNd3d4Z"dOd6d7Z#d8d9 Z$d:d;d<d=Z%d>d? Z&ed@dA Z'edBdC Z(dDdE Z)dPdFdGZ*e+dQdHdIZ,dS )RFFmpegPostProcessorffmpeg_locationN)defaultc                 C   s(   t | | | dd| _|  | _d S )NZprefer_ffmpegT)r   __init__	get_param_prefer_ffmpeg_determine_executables_paths)self
downloaderr*   r*   r:   rP   Z   s    zFFmpegPostProcessor.__init__c                 C   s   t | }|j|jfS N)rM   	_versions	_features)rV   ppr*   r*   r:   get_versions_and_features_   s    z-FFmpegPostProcessor.get_versions_and_featuresc                 C   s   t | d S )Nr   )rM   r[   )rV   r*   r*   r:   get_versionsd   s    z FFmpegPostProcessor.get_versionsavconvZavprobe)ffmpegffprobec                    s0  | j  | j  }| d| j }|d kr<dd |D S tj|sb| j	d| ddd i S tj
|r|d d    }nHtj|tfdd	|D d
}tjtj| || j krd| _ fdd|D }|r|kr|D ].}tj ||}tj|r|||< q|r,|||< |S )NrN   c                 S   s   i | ]
}||qS r*   r*   .0pr*   r*   r:   
<dictcomp>o   s      z>FFmpegPostProcessor._determine_executables.<locals>.<dictcomp>zffmpeg-location z* does not exist! Continuing without ffmpegT)Z	only_oncec                 3   s   | ]}| kr|V  qd S rW   r*   r`   )filenamer*   r:   	<genexpr>y   s      z=FFmpegPostProcessor._determine_executables.<locals>.<genexpr>r^   c                    s   i | ]}|t j |qS r*   )ospathr8   r`   )dirnamer*   r:   rc   ~   s      )_ffmpeg_to_avconvkeysvaluesrQ   _ffmpeg_locationgetrf   rg   existsreport_warningisdirbasenamenextrh   abspathrR   r8   replace)rU   Zprogramslocationrq   pathsrb   rg   r*   )rh   rd   r:   rS   j   s4    
 

z*FFmpegPostProcessor._determine_executablesc           
      C   s   | j |}|| jkr.| j| | j|i fS t|dg}|rFt|nd}|rzddg}|D ]}t||}|rZ|d}qZ|| j|< |dks|s|i fS t	d|}|r|d
d	d
nd }d|kd| kt|ddd | j|< }	||	fS )Nz-bsfsFz'(?:\d+:)?([0-9.]+)-[0-9]+ubuntu[0-9.]+$zn([0-9.]+)$r   r^   z>(?m)^\s+libavformat\s+(?:[0-9. ]+)\s+/\s+(?P<runtime>[0-9. ]+)Zruntime  z--enable-libfdk-aacsettsz	57.56.100)fdkry   Zneeds_adtstoasc)rT   rm   _version_cache_features_cacher
   r   r5   matchgroupsearchrt   
splitlinesr   )
rU   progrg   outverZregexsregexmobjZlavf_runtime_versionfeaturesr*   r*   r:   _get_ffmpeg_version   s.    



z'FFmpegPostProcessor._get_ffmpeg_versionc                 C   s   t | j| j| j| jiS rW   )r   rq   _versionprobe_basename_probe_versionrU   r*   r*   r:   rX      s    zFFmpegPostProcessor._versionsc                 C   s   | j }| jS rW   )r   rq   rU   _r*   r*   r:   rq      s    zFFmpegPostProcessor.basenamec                 C   s   | j }| jS rW   )r   r   r   r*   r*   r:   r      s    z"FFmpegPostProcessor.probe_basenamec                    s   |f} j s| j| f}ttdd  fdd|D d d i f\}}}|dkr`||  _ _n| _| j| kr d j|  d| d |S )	Nc                 S   s   | d S Nr   r*   )xr*   r*   r:   <lambda>       z2FFmpegPostProcessor._get_version.<locals>.<lambda>c                 3   s   | ]}|f  |V  qd S rW   )r   r`   r   r*   r:   re      s     z3FFmpegPostProcessor._get_version.<locals>.<genexpr>r^   zSupport for z; is deprecated and may be removed in a future version. Use z instead)rR   ri   rr   filterrq   rY   r   Zdeprecated_feature)rU   kindZexecutablesrq   versionr   r*   r   r:   _get_version   s     
z FFmpegPostProcessor._get_versionc                 C   s
   |  dS )Nr^   r   r   r*   r*   r:   r      s    zFFmpegPostProcessor._versionc                 C   s
   |  dS )Nr_   r   r   r*   r*   r:   r      s    z"FFmpegPostProcessor._probe_versionc                 C   s
   | j d k	S rW   )rq   r   r*   r*   r:   	available   s    zFFmpegPostProcessor.availablec                 C   s   | j | jS rW   )rT   rm   rq   r   r*   r*   r:   
executable   s    zFFmpegPostProcessor.executablec                 C   s
   | j d k	S rW   )r   r   r*   r*   r:   probe_available   s    z#FFmpegPostProcessor.probe_availablec                 C   s   | j | jS rW   )rT   rm   r   r   r*   r*   r:   probe_executable   s    z$FFmpegPostProcessor.probe_executableTextc                c   s8   dE d H  dE d H  | r"dE d H  |dkr4dE d H  d S )N)-map0)z-dnz-ignore_unknown)-ccopy)mp4movr"   )z-c:sZmov_textr*   )r   r   r*   r*   r:   stream_copy_opts   s    


z$FFmpegPostProcessor.stream_copy_optsc              	   C   sR   | j std| jdkrdnd}t| j|rN| d| j d| j d| d d S )	NzLffmpeg not found. Please install or provide the path using --ffmpeg-locationr]   10-0z1.0Your copy of z is outdated, update  to version z% or newer if you encounter any errors)r   rI   rq   r   r   ro   )rU   required_versionr*   r*   r:   check_version   s
    z!FFmpegPostProcessor.check_versionc           
      C   sP  | j s| jstdz| j r2t| jdtdg}nt| jdtdg}|t| |d | 	| j
 dt|  tj|dtjtjtjd\}}}|| j rdndkrW d S W n tk
r   Y d S X | j r|n|}| j r0d }|d	D ]@}|d
r|dd  }q| dkr|d k	r|  S qntd|}	|	rL|	dS d S )NzXffprobe and ffmpeg not found. Please install or provide the path using --ffmpeg-locationT-show_streams-iz command line: )textstdinstdoutstderrr   r   
zcodec_name==zcodec_type=audiozNStream\s*#\d+:\d+(?:\[0x[0-9a-f]+\])?(?:\([a-z]{3}\))?:\s*Audio:\s*([0-9a-z]+))r   r   r	   r   r   r   r   append_ffmpeg_filename_argumentwrite_debugrq   r   r   run
subprocessPIPEOSErrorr@   
startswithrB   r5   r   r~   )
rU   rg   cmdr   r   
returncodeoutputZaudio_codecliner   r*   r*   r:   get_audio_codec   sL    

    

z#FFmpegPostProcessor.get_audio_codecc                 C   s   | j dkr"| jr| d td|   t| jdtdtdtdtdtd	g}||7 }|| 	| | 
d
t|  tj|dtjtjtjd\}}}t|S )Nr_   z1Only ffprobe is supported for metadata extractionzMffprobe not found. Please install or provide the path using --ffmpeg-locationT-hide_bannerz-show_formatr   z-print_formatjsonzffprobe command line: r   r   r   r   )r   r   ro   r	   r   r   r   r   r   r   r   r   r   r   r   r   r   loads)rU   rg   optsr   r   r   r*   r*   r:   get_metadata_object  s"    


	 z'FFmpegPostProcessor.get_metadata_objectc                    s8   |  |d }t fddt|D d }|t|fS )Nstreamsc                 3   s(   | ] \}}t | d dkr|V  qdS )FZ	casesenseN)r   )ra   istreamrj   valuer*   r:   re   .  s      z8FFmpegPostProcessor.get_stream_number.<locals>.<genexpr>)r   rr   	enumeraterA   )rU   rg   rj   r   r   numr*   r   r:   get_stream_number+  s    z%FFmpegPostProcessor.get_stream_numberc                 C   s.   t |d}|r*|ds*| |d |d< d S )N)chaptersr>   end_timefilepath)r   rm   _get_real_video_duration)rU   infoZlast_chapterr*   r*   r:   _fixup_chapters2  s    
z#FFmpegPostProcessor._fixup_chaptersc              
   C   sb   z&t t| |d}|s"td|W S  tk
r\ } z|rLtd|j W 5 d }~X Y nX d S )N)r7   durationzffprobe returned empty durationz$Unable to determine video duration: )r   r   r   r	   msg)rU   r   fatalr   er*   r*   r:   r   7  s    z,FFmpegPostProcessor._get_real_video_durationr   c                 C   s   |r|sd S t || |kS rW   )abs)rU   d1Zd2Z	tolerancer*   r*   r:   _duration_mismatchB  s    z&FFmpegPostProcessor._duration_mismatchc                 K   s    | j dd |D ||fgf|S )Nc                 S   s   g | ]}|g fqS r*   r*   )ra   rg   r*   r*   r:   
<listcomp>K  s     zAFFmpegPostProcessor.run_ffmpeg_multiple_files.<locals>.<listcomp>)real_run_ffmpeg)rU   Zinput_pathsout_pathr   kwargsr*   r*   r:   run_ffmpeg_multiple_filesI  s    z-FFmpegPostProcessor.run_ffmpeg_multiple_files)r   )expected_retcodesc                   s     tdd |D }tjdtdg}jdkrL|tdtdg7 }fdd	d
|fd|ffD ],\ }|tj fddt	|D 7 }qh
dt|  tj|dtjtjtjd\}}}	|	t|kr
| t|  d |D ]\}
}|
r|
|| q|S )Nc                 s   s&   | ]\}}|rt t|jV  qd S rW   )rf   statr   st_mtime)ra   rg   r   r*   r*   r:   re   Q  s     z6FFmpegPostProcessor.real_run_ffmpeg.<locals>.<genexpr>Tz-yr^   z	-loglevelzrepeat+infoc                    s   d| | d| g}|dkr>|ddg7 }|dkr>| d |  j|7 }|dkrb| d d	d
 |D t | dg S )Nr   oz	-movflagsz
+faststartr   rx   r   r   c                 S   s   g | ]}t |qS r*   )r   )ra   argr*   r*   r:   r   c  s     zJFFmpegPostProcessor.real_run_ffmpeg.<locals>.make_args.<locals>.<listcomp>T)r   Z_configuration_argsrq   r   r   )fileargsnamenumberrj   r   r*   r:   	make_argsY  s    

z6FFmpegPostProcessor.real_run_ffmpeg.<locals>.make_argsr   r   c                 3   s0   | ](\}\}}|r|t | |d  V  qdS )r   N)list)ra   r   rg   r   )arg_typer   r*   r:   re   g  s   
 zffmpeg command line: r   r>   )r   minr   r   r   rq   	itertoolschainfrom_iterabler   r   r   r   r   r   r   r   rI   rB   r   	try_utime)rU   Zinput_path_optsZoutput_path_optsr   Zoldest_mtimer   Z	path_optsr   r   r   r   r*   )r   r   rU   r:   r   N  s6    
    
z#FFmpegPostProcessor.real_run_ffmpegc                 K   s   | j |g||f|S rW   )r   )rU   rg   r   r   r   r*   r*   r:   
run_ffmpegv  s    zFFmpegPostProcessor.run_ffmpegc                 C   s"   |  dr| S | dkrd|  S | S )N)zhttp://zhttps://-zfile:)r   )fnr*   r*   r:   r   y  s    
z-FFmpegPostProcessor._ffmpeg_filename_argumentc                 C   sT   |  dd dd} | d dkr,| dd  nd|  } | d dkrL| d d S | d S )N'z'\''z'''r   r   r>   )rt   )stringr*   r*   r:   _quote_for_ffmpeg  s     z%FFmpegPostProcessor._quote_for_ffmpegc              
   C   st   t |}|d dkr |dd  }t|d}| d| d | ||| jdt|ddd	d
d |D f |S )Nr   r   zkeyframes.tempzRe-encoding "z" with appropriate keyframesFr   z-force_key_frames,c                 s   s   | ]}|d V  qdS )z.6fNr*   )ra   tr*   r*   r:   re     s     z6FFmpegPostProcessor.force_keyframes.<locals>.<genexpr>)r   r   	to_screenr   r   r   r8   )rU   rd   Z
timestampsZkeyframe_filer*   r*   r:   force_keyframes  s    
 z#FFmpegPostProcessor.force_keyframesc              	   C   s   | d}|  d|  t|ddd}|| || W 5 Q R X t| jt|d}| |ddd	d
ddgfg||fg | | dS )z
        Use concat demuxer to concatenate multiple files having identical streams.

        Only inpoint, outpoint, and duration concat options are supported.
        See https://ffmpeg.org/ffmpeg-formats.html#concat-1 for details
        z.concatzWriting concat spec to wutf-8encodingr   r   z-nostdinr+   concatz-safer   N)	r   open
writelines_concat_specr   r   r   r   _delete_downloaded_files)rU   in_filesout_fileconcat_optsZconcat_filefZ	out_flagsr*   r*   r:   concat_files  s    
z FFmpegPostProcessor.concat_filesc                 c   sv   |d kri gt | }dV  t||D ]J\}}d| | | dV  dD ]"}||krL| d||  dV  qLq&d S )Nzffconcat version 1.0
zfile r   )ZinpointZoutpointr   rw   )rA   zipr   r   )clsr  r  r   r   	directiver*   r*   r:   r    s    z FFmpegPostProcessor._concat_spec)N)N)N)T)T)r   )N)N)-rJ   rK   rL   contextvarsZ
ContextVarrl   rP   staticmethodr[   r\   ri   rS   r{   r|   r   propertyrX   	functoolscached_propertyrq   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  classmethodr  r*   r*   r*   r:   rM   W   sb   











	%

(
	
	
rM   c                   @   s\   e Zd ZejdZee Z	e
de	ZdddZdd Zd	d
 Zejdddd ZdS )FFmpegExtractAudioPPr&   bestNFc                 C   s*   t | | |pd| _t|| _|| _d S )Nr  )rM   rP   rD   r   _preferredquality_nopostoverwrites)rU   rV   ZpreferredcodecZpreferredqualityZnopostoverwritesr*   r*   r:   rP     s    

zFFmpegExtractAudioPP.__init__c                 C   s   | j d krg S | j dkr(d| j  dgS ddddd|}|sDg S |d	 |d
 |d	  | j d   }|dkr|dt| gS d| gS )N
   z-b:ak)r  r   )r   r  )g?   )r      )r)   r/   r!   
libfdk_aacr   r   r  z-vbrz-q:a)r  rm   int)rU   codecZlimitsqr*   r*   r:   _quality_args  s"    

"z"FFmpegExtractAudioPP._quality_argsc              
   C   sl   |d krg }nd|g}d||}zt | ||| W n2 tk
rf } ztd|j W 5 d }~X Y nX d S )Nr0   -vnzaudio conversion failed: )r  )rM   r   rI   r	   r   )rU   rg   r   r  	more_optsZacodec_optsr   errr*   r*   r:   r     s    
zFFmpegExtractAudioPP.run_ffmpegimagesc                 C   sV  |d  }}t |d | j\}}|dkr>|d | jkr>d\}}|s`| d| d|  g |fS | |}|d krztd|dkr|d	krtd
 d\}}}	}
n~|dks||krzt| d\}}}	}
W n" tk
r   td \}}
}	Y nX n0t| \}}
}	|
dkr| j	drdg  }
}	t
|	}	|
dkr:| |
}	t|||d  }}||kr|
dkr| d| d|  g |fS t|d}t|d}| jrtjt|rtjt|r| d| d g |fS | d|  | |||
|	 t|| t|| ||d< ||d< |	dd k	rL| j|t |d dd |g|fS )Nr   r   r  )Nz,the file is already in a common audio formatzNot converting audio z; z7WARNING: unable to obtain file audio codec with ffprober!   )r"   r  r"   r   r(   rz   r  z#; file is already in target format origtempzPost-process file z exists, skippingzDestination: Zfiletimez!Cannot update utime of audio file)Zerrnote)r   )r   )rH   rD   COMMON_AUDIO_EXTSr   r   r	   ACODECSKeyErrorrY   rm   r   r  r   r   r  rf   rg   rn   r   r   rt   r   time)rU   Zinformation	orig_pathrg   Ztarget_format	_skip_msgZ	filecodec	extensionr   r  acodecZ	temp_pathnew_pathr*   r*   r:   r     sb    







   zFFmpegExtractAudioPP.run)r&   )r  )NNNF)rJ   rK   rL   r   common_audior%  tupler&  rj   SUPPORTED_EXTSr;   	FORMAT_RErP   r  r   r   _restrict_tor   r*   r*   r*   r:   r    s   


r  c                       sf   e Zd ZeejdeejdZeeZ	dZ
d fdd	Zedd	 Zejd
ddd Z  ZS )FFmpegVideoConvertorPPgifr!   r3   Z
convertingNc                    s   t  | || _d S rW   superrP   rD   )rU   rV   Zpreferedformat	__class__r*   r:   rP   *  s    zFFmpegVideoConvertorPP.__init__c                 c   s&   t dE d H  | dkr"dE d H  d S )NFZavi)z-c:vZlibxvidz-vtagZXVIDrM   r   
target_extr*   r*   r:   _options.  s    zFFmpegVideoConvertorPP._optionsFr!  c              	   C   s   |d |d    }}t|| j\}}|rP| d| j d| d|  g |fS t|||}| | j  d| d| d|  | ||| | ||d< | |d	< |d< |g|fS )
Nr   r   zNot z media file ""; z video from z to z; Destination: r7   )	r?   rH   rD   r   _ACTIONr   titler   r<  )rU   r   rd   
source_extr;  r*  Zoutpathr*   r*   r:   r   4  s    &zFFmpegVideoConvertorPP.run)r4  )r!   r3   )NN)rJ   rK   rL   sortedr   common_videor.  r0  r;   r1  r>  rP   r  r<  r   r2  r   __classcell__r*   r*   r7  r:   r3  "  s   

r3  c                   @   s   e Zd ZdZedd ZdS )FFmpegVideoRemuxerPPZremuxingc                 C   s   t  S rW   r9  r:  r*   r*   r:   r<  H  s    zFFmpegVideoRemuxerPP._optionsN)rJ   rK   rL   r>  r  r<  r*   r*   r*   r:   rD  E  s   rD  c                       s6   e Zd ZdZd	 fdd	Zejdddd Z  ZS )
FFmpegEmbedSubtitlePP)r   r   r"   r   r$   r#   NFc                    s   t  | || _d S rW   )r6  rP   _already_have_subtitle)rU   rV   Zalready_have_subtitler7  r*   r:   rP   P  s    zFFmpegEmbedSubtitlePP.__init__r!  c                 C   sh  |d | j kr0| dd| j  d g |fS |d}|sP| d g |fS |d }|d }g g g   }}}d}d}	| D ]\}
}tj|dd	s| d
|
 d q|d }|dkr| d nn|dks|dkr|dkr|	|
 |	|d |	|d  n(|s:|dkr:|dkr:d}| d |	s|dkr|dkrd}	| d q|slg |fS |f|}| j
|d dd"}tt||D ]\}\}
}|d|d  dg t|
p|
}|d| d| g |r|d| d| d| d| g qt|d}| d | d! | ||| t|| | jr\g n|}||fS )#Nr   z"Subtitles can only be embedded in , z filesrequested_subtitlesz#There aren't any subtitles to embedr   Frx   Skipping embedding % subtitle because the file is missingr   z!JSON subtitles cannot be embeddedr   r'   r   Tz3Only WebVTT subtitles can be embedded in webm filesr   ZasszEASS subtitles cannot be properly embedded in mp4 files; expect issuesr   r   -0:sr   z:0z-metadata:s:s:z	language=zhandler_name=title=r$  zEmbedding subtitles in "")r   rK  )r0  r   r8   rm   itemsrf   rg   rn   ro   r   r   r   r  extendr   
short2longr   r   rt   rF  )rU   r   	subtitlesrd   r   Z	sub_langsZ	sub_namessub_filenamesZwebm_vtt_warnZmp4_ass_warnlangZsub_infoZsub_extZinput_filesr   r   r   Z	lang_codetemp_filenamefiles_to_deleter*   r*   r:   r   T  sf    




    

zFFmpegEmbedSubtitlePP.run)NF)	rJ   rK   rL   r0  rP   r   r2  r   rC  r*   r*   r7  r:   rE  M  s   
rE  c                   @   sR   e Zd ZdddZedd Zejddd	d
 Zedd Z	dd Z
dd ZdS )FFmpegMetadataPPT	if_existsc                 C   s"   t | | || _|| _|| _d S rW   )rM   rP   _add_metadata_add_chapters_add_infojson)rU   rV   Zadd_metadataZadd_chaptersZadd_infojsonr*   r*   r:   rP     s    zFFmpegMetadataPP.__init__c                 c   s,   | dk}t | E d H  |r(dE d H  d S )Nr"   )r  r0   r   r9  )r;  Z
audio_onlyr*   r*   r:   r<    s    zFFmpegMetadataPP._optionsFr!  c              	   C   sB  |  | |d d  }}g g  }}| jr\|dr\t|d}|| |d | || | jrr|| | | j	r|d dkr|d}|| 
|| |s||d n| j	dkr| d |s| d	 g |fS t|d
}| d| d | ||f|tj| |d f|  | j|  t|| g |fS )Nr   r   metar   )r$   r#   infojson_filenameTz3The info-json can only be attached to mkv/mka fileszThere isn't any metadata to addr$  zAdding metadata to "rM  )r   rY  rm   r   rO  _get_chapter_optsr   rX  _get_metadata_optsrZ  _get_infojson_optsr   r   r   r   r   r<  r  rf   rt   )rU   r   rd   metadata_filenamerU  optionsr\  rT  r*   r*   r:   r     s<    








 
zFFmpegMetadataPP.runc              	   c   s   t |dddx}dd }d}| D ]V}|d7 }|d|d	 d
  7 }|d|d d
  7 }|d}|r |d|| d7 }q || W 5 Q R X dV  d S )Nr   r   r   c                 S   s   t dd| S )Nz([\\=;#\n])z\\\1)r5   sub)r   r*   r*   r:   ffmpeg_escape  s    z9FFmpegMetadataPP._get_chapter_opts.<locals>.ffmpeg_escapez;FFMETADATA1
z[CHAPTER]
TIMEBASE=1/1000
z	START=%d

start_timei  zEND=%d
r   r?  rL  r   )z-map_metadata1)r   rm   write)r   r`  r  rc  Zmetadata_file_contentchapterZchapter_titler*   r*   r:   r]    s    
z"FFmpegMetadataPP._get_chapter_optsc                 #   sB  dt td6 fdd	}|dd |dd |dd	 |d
d |dd |dd |dd |dd |d |dd |dd |dd |d |dd |dd d | d!g kr|d"d	 d# d$d  t d%}  D ]F\}}t||}|d k	r|r|	d&d'|
d(p.d# |
d)< qd*V  d#  D ]\}}d+| d,| fV  qNd-} d.p gD ]}	d/|	d0|	d1fkrd2nd3}
t|	d4pd'p|	d4}t|||
 D ]V}|rt| d4| t|  D ]$\}}d5| | d,| fV  qq||
7 }qd S )7Nr[  c                    sx   t fdd dft|p| D d   dkrtdttt   dd d  fd	d
t| D  d S )Nc                 3   s$   | ]}  |d k	r | V  qd S rW   )rm   )ra   key)r   r*   r:   re     s   zCFFmpegMetadataPP._get_metadata_opts.<locals>.add.<locals>.<genexpr>r   )rx   NrG   rx   commonc                    s   i | ]
}| qS r*   r*   )ra   Zmeta_fr   r*   r:   rc     s      zDFFmpegMetadataPP._get_metadata_opts.<locals>.add.<locals>.<dictcomp>)rr   r   r8   mapstrrt   update)Z	meta_listZ	info_listr   Zmeta_prefixmetadatark  r:   add  s    z0FFmpegMetadataPP._get_metadata_opts.<locals>.addr?  )trackr?  dateZupload_date)descriptionsynopsisrt  )purlcommentZwebpage_urlrr  Ztrack_numberartist)rx  ZartistsZcreatorZcreatorsZuploaderZuploader_idcomposer)ry  Z	composersgenre)rz  ZgenresZalbumalbum_artist)r{  Zalbum_artistsZdiscZdisc_numbershowZseriesZseason_number
episode_id)Zepisoder}  Zepisode_sortZepisode_numberzembed-metadataZcompat_optsrw  rj  ru  z(?P<i>\d+)?_(?P<key>.+)ri  rx   r   rh  )z-write_id3v1re  z	-metadatar   r   requested_formatsnonevcodecr,  r   r   language-metadata:s:)N)collectionsdefaultdictdictrQ   popr5   escaperN  	fullmatchrt   r~   rm   r   rP  rangerm  
setdefault)rU   r   rq  Z
meta_regexrh  r   r   r   Z
stream_idxfmtZstream_countrS  r   r*   ro  r:   r^    sN    














("""z#FFmpegMetadataPP._get_metadata_optsc                 c   s   |rt j|s| jdk	rd S |pJd| j|dpHt| j|d|d  }| j|s\d S | d|  t	| j
|| dd| ||d< | |d	 d
d\}}|d k	rdd| fV  |d8 }d| |d| dd| dfV  d S )NTz%s.tempZinfojsonz	info.jsonr   zWriting info-json to: Zclean_infojsonr\  r   )tagsmimetypezapplication/jsonr   z-0:r   z-attachr  zmimetype=application/jsonzfilename=info.json)rf   rg   rn   rZ  _downloaderprepare_filenamer   _ensure_dir_existsr   r   Zsanitize_inforQ   r   r   )rU   r   ZinfofnZ
old_streamZ
new_streamr*   r*   r:   r_    s.    
   z#FFmpegMetadataPP._get_infojson_optsN)TTrW  )rJ   rK   rL   rP   r  r<  r   r2  r   r]  r^  r_  r*   r*   r*   r:   rV    s   



!
<rV  c                   @   s.   e Zd ZejZejdddd Zdd Z	dS )FFmpegMergerPPFr!  c           	      C   s   |d }t |d}ddg}d}t|d D ]\}}|ddkr|d	| d
g |d dor| |d dk}|r|d| dg |d7 }|ddkr*|d	| dg q*| d| d | |d || t	t
|t
| |d |fS )Nr   r$  r   r   r   r~  r,  r  r   z:a:0protocolm3u8r!   z-bsf:a:r-   r   r  z:v:0zMerging formats into "rM  Z__files_to_merge)r   r   rm   rO  r   r   r   r   rf   renamer   )	rU   r   rd   rT  r   Zaudio_streamsr   r  Z	aac_fixupr*   r*   r:   r   8  s"    
 zFFmpegMergerPP.runc                 C   sR   | j dkrdS d}t| j| j  |rNd| j  d| j  d| d}| | dS dS )	Nr]   Tr   r   zw is outdated and unable to properly mux separate video and audio files, yt-dlp will download single file media. Update r   z or newer to fix this.F)rq   r   rX   ro   )rU   r   warningr*   r*   r:   	can_mergeL  s    

 
zFFmpegMergerPP.can_mergeN)
rJ   rK   rL   r   rB  r0  r   r2  r   r  r*   r*   r*   r:   r  5  s   

r  c                   @   s   e Zd Zdd ZdS )FFmpegFixupPostProcessorc                 C   s>   t |d}| | d| d | ||| t|| d S )Nr$  z of "rM  )r   r   r   rf   rt   )rU   r   rd   ra  rT  r*   r*   r:   _fixup]  s    
zFFmpegFixupPostProcessor._fixupN)rJ   rK   rL   r  r*   r*   r*   r:   r  \  s   r  c                   @   s"   e Zd Zejddddd ZdS )FFmpegFixupStretchedPPF)r"  audioc                 C   s<   | d}|dkr4| d|d |  d|df g |fS )Nstretched_ratior   zFixing aspect ratior   z-aspectr  rm   r  r   )rU   r   r  r*   r*   r:   r   g  s    
  zFFmpegFixupStretchedPP.runNrJ   rK   rL   r   r2  r   r*   r*   r*   r:   r  f  s   r  c                   @   s"   e Zd Zejddddd ZdS )FFmpegFixupM4aPPF)r"  videoc                 C   s0   | ddkr(| d|d |  d g |fS )N	containerZm4a_dashzCorrecting containerr   r+   r   )r+   r   r  rU   r   r*   r*   r:   r   q  s    zFFmpegFixupM4aPP.runNr  r*   r*   r*   r:   r  p  s   r  c                   @   s(   e Zd Zdd Zejdddd ZdS )FFmpegFixupM3u8PPc              
   c   s   |d dkV  |d  dV  z| |d }W n: tk
rj } z| d|j  dV  W 5 d }~X Y nX t|dd	d
dkV  d S )Nr   )r   r"   r  r  r   zUnable to extract metadata: T)r7   Zformat_nameFr   r   )r   r   r	   ro   r   r   )rU   r   rp  r   r*   r*   r:   _needs_fixupy  s    zFFmpegFixupM3u8PP._needs_fixupFr!  c                 C   sX   t | |rPddg}| |d dkr6|ddg | d|d |  | g |fS )Nr+   r   r   r!   r,   r-   zFixing MPEG-TS in MP4 container)allr  r   rO  r  r   )rU   r   r   r*   r*   r:   r     s     zFFmpegFixupM3u8PP.runN)rJ   rK   rL   r  r   r2  r   r*   r*   r*   r:   r  x  s   
r  c                       s2   e Zd Zd	 fdd	Zejdddd Z  ZS )
FFmpegFixupTimestampPPNMbP?c                    s,   t  | t|ttfstt|| _d S rW   )r6  rP   
isinstancer  floatAssertionErrorrm  trim)rU   rV   r  r7  r*   r:   rP     s    zFFmpegFixupTimestampPP.__init__Fr!  c                 C   sX   | j ds | d ddg}nddddg}| d	|d
 || dd| jf g |fS )Nry   zA re-encode is needed to fix timestamps in older versions of ffmpeg. Please install ffmpeg 4.4 or later to fixup without re-encodingz-vfzsetpts=PTS-STARTPTSr   r   z-bsfzsetts=ts=TS-STARTPTSzFixing frame timestampr   F-ss)rY   rm   ro   r  r   r  )rU   r   r   r*   r*   r:   r     s    
$zFFmpegFixupTimestampPP.run)Nr  )rJ   rK   rL   rP   r   r2  r   rC  r*   r*   r7  r:   r    s   
r  c                   @   s$   e Zd ZdZejdddd ZdS )FFmpegCopyStreamPPzCopying streamFr!  c                 C   s    |  | j|d |   g |fS )Nr   )r  MESSAGEr   r  r*   r*   r:   r     s    zFFmpegCopyStreamPP.runN)rJ   rK   rL   r  r   r2  r   r*   r*   r*   r:   r    s   
r  c                   @   s   e Zd ZdZdS )FFmpegFixupDurationPPzFixing video durationNrJ   rK   rL   r  r*   r*   r*   r:   r    s   r  c                   @   s   e Zd ZdZdS )FFmpegFixupDuplicateMoovPPzFixing duplicate MOOV atomsNr  r*   r*   r*   r:   r    s   r  c                       s,   e Zd ZejZd fdd	Zdd Z  ZS )FFmpegSubtitlesConvertorPPNc                    s   t  | || _d S rW   )r6  rP   r7   rU   rV   r7   r7  r*   r:   rP     s    z#FFmpegSubtitlesConvertorPP.__init__c              
   C   s  | d}| j}|}|dkr d}|d kr:| d g |fS | d g }| D ]v\}}tj| dds| d| d	 qP|d
 }||kr| d| d qPn|dkr| d qP|d }	||	 t	|	|}
|dkrl| d |	}t	|	d}t
|d}t| }W 5 Q R X t
|ddd}|| W 5 Q R X |}	d||d||< |dkrbqPn
|| | |	|
d|g t
|
dd}|| |
d||< W 5 Q R X t	|d |d  ||d |
< qP||fS )NrH  r'   r    z%There aren't any subtitles to convertzConverting subtitlesr   rx   rI  rJ  r   zSubtitle file for z# is already in the requested formatr   zaYou have requested to convert json subtitles into another format, which is currently not possible)ZdfxpZttmlttzpYou have requested to convert dfxp (TTML) subtitles into another format, which results in style information lossZsrtrbr   r   r   )r   datar   r+   __files_to_move)rm   r7   r   rN  rf   rg   rn   ro   r   r   r   r   readrf  r   )rU   r   subsZnew_extZ
new_formatrR  rS  rb  r   Zold_fileZnew_fileZ	dfxp_fileZsrt_filer  Zsrt_datar*   r*   r:   r     sn    









 zFFmpegSubtitlesConvertorPP.run)NN)	rJ   rK   rL   r   rQ  r0  rP   r   rC  r*   r*   r7  r:   r    s   r  c                   @   s:   e Zd ZdddZdd Zdd Zejddd	d
 ZdS )FFmpegSplitChaptersPPFc                 C   s   t | | || _d S rW   )rM   rP   _force_keyframes)rU   rV   r   r*   r*   r:   rP     s    zFFmpegSplitChaptersPP.__init__c                 C   s<   |  }|||d|d|dd | j|dS )Nr?  rd  r   )Zsection_numberZsection_titleZsection_startZsection_endrg  )r   rn  rm   r  r  )rU   r   rg  r   r*   r*   r:   _prepare_filename  s    z'FFmpegSplitChaptersPP._prepare_filenamec                 C   sd   |  |||}| jt|s"d S ||d< | d||f  |dt|d dt|d |d  gfS )Nr   zChapter %03d; Destination: %sr  rd  z-tr   )r  r  r  r   r   rm  )rU   r   rg  r   destinationr*   r*   r:   _ffmpeg_args_for_chapter  s     z.FFmpegSplitChaptersPP._ffmpeg_args_for_chapterr!  c                 C   s   |  | |dpg }|s.| d g |fS |d }| jr^t|dkr^| |dd |D }| dt| d t|D ]:\}}| |d ||\}}| ||fg|| 	 fg q|||d kr| j
|d d	 g |fS )
Nr   z"Chapter information is unavailabler   r   c                 s   s   | ]}|d  V  qdS )rd  Nr*   )ra   cr*   r*   r:   re   &  s     z,FFmpegSplitChaptersPP.run.<locals>.<genexpr>zSplitting video by chapters; z chapters found)r   )r   rm   r   r  rA   r   r   r  r   r   r  )rU   r   r   in_fileidxrg  r  r   r*   r*   r:   r     s    

zFFmpegSplitChaptersPP.runN)F)	rJ   rK   rL   rP   r  r  r   r2  r   r*   r*   r*   r:   r    s
   


r  c                       s^   e Zd ZejZeeZd fdd	Ze	dd Z
dddZed	d
 Zdd Zdd Z  ZS )FFmpegThumbnailsConvertorPPNc                    s   t  | || _d S rW   r5  r  r7  r*   r:   rP   4  s    z$FFmpegThumbnailsConvertorPP.__init__c                 C   s&   t | j d| j d t|dkS )N.z.is_webp is deprecatedwebp)r   rK   rJ   r   what)r	  rg   r*   r*   r:   is_webp8  s    z#FFmpegThumbnailsConvertorPP.is_webpr>   c                 C   s   |d | d }t j|\}}|r| dkrt|dkr| d| d t|d}t || ||d | d< t|d 	|d|d |< d S )N
thumbnailsr   z.webpr  zCorrecting thumbnail "z" extension to webpr  )
rf   rg   splitextr?   r   r  r   r   rt   r  )rU   r   r  thumbnail_filenamer   thumbnail_extZwebp_filenamer*   r*   r:   
fixup_webp=  s    
 z&FFmpegThumbnailsConvertorPP.fixup_webpc                 c   s    dE d H  | dkrdE d H  d S )N)z-updatere  jpg)z-bsf:vZ
mjpeg2jpegr*   r:  r*   r*   r:   r<  I  s    
z$FFmpegThumbnailsConvertorPP._optionsc                 C   sf   t ||}| d| d|  tj|\}}| ||dkrBg n
ddddgfg|| |fg |S )NzConverting thumbnail "z" to z.gifr+   Zimage2z-pattern_typer  )r   r   rf   rg   r  r   r<  )rU   r  r;  Zthumbnail_conv_filenamer   r@  r*   r*   r:   convert_thumbnailO  s    
z-FFmpegThumbnailsConvertorPP.convert_thumbnailc           
      C   s   g }d}t |dpg D ]\}}|d}|s2qd}| || |d }tj|d dd   }|dkrrd}t|| j\}}	|	r| 	d| d	|	  q| 
|||d< || t|d
 | ||d
 |d < q|s| 	d ||fS )NFr  r   Tr   Zjpegr  zNot converting thumbnail "r=  r  z&There aren't any thumbnails to convert)r   rm   r  rf   rg   r  r?   rH   rD   r   r  r   r   )
rU   r   rU  Zhas_thumbnailr  Zthumbnail_dictZoriginal_thumbnailr  r;  r*  r*   r*   r:   r   Y  s2    


 
zFFmpegThumbnailsConvertorPP.run)NN)r>   )rJ   rK   rL   r   r  r0  r;   r1  rP   r  r  r  r  r<  r  r   rC  r*   r*   r7  r:   r  0  s   



r  c                       sH   e Zd Zd fdd	Zdd Z fddZejdddd	d
 Z  Z	S )FFmpegConcatPPFc                    s   || _ t | d S rW   )_only_multi_videor6  rP   )rU   rV   Zonly_multi_videor7  r*   r:   rP   v  s    zFFmpegConcatPP.__init__c                 C   s.   t | |d}| dd|  t|S )N)r   .Z
codec_namez	Codecs = rG  )r   r   r   r8   r/  )rU   r   codecsr*   r*   r:   _get_codecsz  s    zFFmpegConcatPP._get_codecsc                    s   | j |sd S t|dkrhtj|d tj|krT| d|d  d| d t|d | g S ttt	| j
|dkrtd| dt| d|  t || |S )	Nr   r   zMoving "z" to "rM  zThe files have different streams/codecs and cannot be concatenated. Either select different formats or --recode-video them to a common formatzConcatenating z files; Destination: )r  r  rA   rf   rg   realpathr   rt   setrl  r  r	   r6  r  )rU   r  r  r7  r*   r:   r    s    zFFmpegConcatPP.concat_files)r"  Z	simulatedc                 C   s   | dpg }t|r(| jr0|d dkr0g |fS t|ddd frJtdt|dpVg }t|t|k rptd	t|d
d}tdtt|dkr|d ndi|| j	
|}| j	|d}| ||}||d dg|d< ||fS )Nentries_typeZmulti_video.c                 S   s   | dkot |dkS )Nrequested_downloadsr   )rA   )r  vr*   r*   r:   r     r   z$FFmpegConcatPP.run.<locals>.<lambda>zIConcatenation is not supported when downloading multiple separate formats).r  r   r   z4Aborting concatenation because some downloads failed).r  r   r   ).r   r   r   r   r$   Zpl_video)r   r   r  )rm   anyr  r   r	   rA   r  ChainMapr  r  Z_playlist_infodictr  r  )rU   r   r  r  extsZie_copyr  rU  r*   r*   r:   r     s&    " 
zFFmpegConcatPP.run)F)
rJ   rK   rL   rP   r  r  r   r2  r   rC  r*   r*   r7  r:   r  u  s
   r  );r  r  r  r   r   rf   r5   r   r(  rj  r   compatr   utilsr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   ZEXT_TO_OUT_FORMATSr&  r;   rH   rI   rM   r  r3  rD  rE  rV  r  r  r  r  r  r  r  r  r  r  r  r  r  r*   r*   r*   r:   <module>   st   \  cj#Q '

	L/E