o
    eP0                     @   s  d dl mZ d dlZd dlZd dlZd dlZd dlmZmZ d dl	m
Z
mZ d dlmZ d dlmZ d dlmZ zd dlZW n eyK   d dlZY nw ejdkrSeZd	d
ddZddddZddddZdd ZdBddZdd ZdCddZdBddZdDdd Z dEd!d"Z!d#d$ Z"d%d& Z#d'd( Z$d)d* Z%d+d, Z&d-d. Z'd/d0 Z(dFd2d3Z)d4d5 Z*d6d7 Z+e+d8d9 Z,d:d; Z-d<d= Z.d>d? Z/d@dA Z0dS )G    )divisionN)PopenPIPE)logceil)TemporaryFile)warnwraps)   r            )          bhi)i   )i i  )i   ic                 C      t |  S N)FRAME_WIDTHS	bit_depth r   ;D:\Projects\ConvertPro\env\Lib\site-packages\pydub/utils.pyget_frame_width&      r   Tc                 C   s   t |  }|s
| }|S r   )ARRAY_TYPESupper)r   signedtr   r   r   get_array_type*   s   r#   c                 C   r   r   )ARRAY_RANGESr   r   r   r   get_min_max_value1   r   r%   w+bc                 C   s   d}| d u r|rt |d} d}t| trt| |d} d}zt| tjr0t| |d} d}W | |fS W | |fS  ty@   Y | |fS w )NF)modeT)r   
isinstance
basestringopenosPathLikeAttributeError)fdr'   tempfileZclose_fdr   r   r   _fd_or_path_or_tempfile5   s$   

r0   c                 C   s$   t | } |rd| d  S d| d  S )z_
    Converts the input db to a float, which represents the equivalent
    ratio in power.
    
      )float)dbusing_amplituder   r   r   db_to_floatK   s   r6   c                 C   sJ   t | } |dur| | } | dkrt d S |rdt| d S dt| d S )z
    Converts the input float to db, which represents the equivalent
    to the ratio in power represented by the multiplier passed in.
    Nr   infr2   r1   )r3   r   )ratioZval2r5   r   r   r   ratio_to_dbW   s   
r9   c                    sD   t | tr|   fddS  du r| j ddlm} t| |  | S )a>  
    decorator for adding pydub effects to the AudioSegment objects.
    example use:
        @register_pydub_effect
        def normalize(audio_segment):
            ...
    or you can specify a name:
        @register_pydub_effect("normalize")
        def normalize_audio_segment(audio_segment):
            ...
    c                    s
   t |  S r   )register_pydub_effect)fnnamer   r   <lambda>z   s   
 z'register_pydub_effect.<locals>.<lambda>Nr   )AudioSegment)r(   r)   __name__audio_segmentr?   setattr)r;   r=   r?   r   r<   r   r:   l   s   
r:   c                    s0   t t t } fddtt|D S )z
    Breaks an AudioSegment into chunks that are <chunk_length> milliseconds
    long.
    if chunk_length is 50 then you'll get a list of 50 millisecond long audio
    segments back (except the last one, which can be shorter)
    c                    s$   g | ]} | |d    qS )r   r   ).0r   rA   chunk_lengthr   r   
<listcomp>   s    zmake_chunks.<locals>.<listcomp>)r   lenr3   rangeint)rA   rE   Znumber_of_chunksr   rD   r   make_chunks   s   
rJ   c                 C   st   t jdkr| ds| d7 } t jgt jd t j }|D ]}t j|| }t j	|r7t 
|t jr7|  S qdS )z0
    Mimics behavior of UNIX which command.
    ntz.exePATHN)r+   r=   endswithcurdirenvironsplitpathseppathjoinisfileaccessX_OK)programZenvdir_listZenvdirZprogram_pathr   r   r   which   s   rX   c                   C   &   t drdS t drdS tdt dS )Q
    Return enconder default application for system, either avconv or ffmpeg
    ZavconvZffmpegzGCouldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not workrX   r   RuntimeWarningr   r   r   r   get_encoder_name      
r]   c                   C   rY   )rZ   ZavplayZffplayzGCouldn't find ffplay or avplay - defaulting to ffplay, but may not workr[   r   r   r   r   get_player_name   r^   r_   c                   C   rY   )z;
    Return probe application, either avconv or ffmpeg
    ZavprobeffprobezJCouldn't find ffprobe or avprobe - defaulting to ffprobe, but may not workr[   r   r   r   r   get_prober_name   r^   ra   c                 C   sv   t jdkrttf}t jdkr|tjf7 }t| |rt| S nt| tr+| t 	 S t| tr2| S t
dt| )z<Wrapper for os.fsdecode which was introduced in python 3.2 .)r   r   )r      z!type {0} not accepted by fsdecode)sysversion_infor)   bytesr+   r,   r(   fsdecodedecodegetfilesystemencoding	TypeErrorformattype)filenameZPathLikeTypesr   r   r   rf      s   





rf   c                 C   s   i }d}t || D ]>}|ddur/t|dt|dkr/d|d|dg}n|d}dd	 t d
|D }||t|d< q
|S )a|  
    avprobe sometimes gives more information on stderr than
    on the json output. The information has to be extracted
    from stderr of the format of:
    '    Stream #0:0: Audio: flac, 88200 Hz, stereo, s32 (24 bit)'
    or (macOS version):
    '    Stream #0:0: Audio: vorbis'
    '      44100 Hz, stereo, fltp, 320 kb/s'

    :type stderr: str
    :rtype: list of dict
    z}(?P<space_start> +)Stream #0[:\.](?P<stream_id>([0-9]+))(?P<content_0>.+)\n?(?! *Stream)((?P<space_end> +)(?P<content_1>.+))?Z	space_endNZspace_start,Z	content_0Z	content_1c                 S   s   g | ]}|r|  qS r   )striprC   xr   r   r   rF      s    z"get_extra_info.<locals>.<listcomp>z[:,]Z	stream_id)refinditergrouprG   rS   rP   rI   )stderr
extra_infoZ	re_streamr   Zcontent_linetokensr   r   r   get_extra_info   s   
rw   c                 C   sD  t  }g d}z|t| g7 }d}d}W n6 tyJ   |dkr)|dt|dg7 }n|dg7 }t}t| ddd	\}}|d
 | }|rH|  Y nw |ddg| }t	||ttd}	|	j
|d\}
}|
dd}
|dd}t|
}|sw|S t|}dd |d D }t|d
kr|S |d
 }dd }||d  D ]}td|}td|}|r||d|d ||dt|d ||dt|d q|r||d|d ||dt|d ||dt|d qtd|r||d| ||dd  ||dd  qtd!|r||d| ||dd" ||dd" q|S )#z\Return json dictionary with media info(codec, duration, size, bitrate...) from filepath
    )-vinfo-show_format-show_streamsNr`   z-read_ahead_limitzcache:pipe:0-rbF)r/   r   -ofjson)stdinstdoutrt   )inpututf-8ignorec                 S   s   g | ]
}|d  dkr|qS )Z
codec_typeZaudior   ro   r   r   r   rF      s    z"mediainfo_json.<locals>.<listcomp>streamsc                 S   s$   || vs
| | dkr|| |< d S d S Nr   r   )streampropvaluer   r   r   set_property'  s   z$mediainfo_json.<locals>.set_propertyindexz*([su]([0-9]{1,2})p?) \(([0-9]{1,2}) bit\)$z$([su]([0-9]{1,2})p?)( \(default\))?$Z
sample_fmtr   Zbits_per_sampler   Zbits_per_raw_sampler   z(flt)p?( \(default\))?$r   z(dbl)p?( \(default\))?$@   )ra   rf   ri   strr   r0   seekreadcloser   communicaterg   r   loadsrw   rG   rq   matchrs   rI   )filepathZread_ahead_limitprobercommand_argsZstdin_parameterZ
stdin_datafileZ
close_filecommandresoutputrt   rz   ru   Zaudio_streamsr   r   tokenmm2r   r   r   mediainfo_json   sn   



r   c              	   C   s  t  }dddd| g}|ddg| }t|td}| d d	}|jdkr7|g| }t|td d d	}td
}i }tj	dkrI|
dd}|dD ]1}||}	|	r|	 \}
}}|
r{z||
  W n tys   i ||
< Y nw |||
 |< qN|||< qN|S )zWReturn dictionary with media info(codec, duration, size, bitrate...) from filepath
    ry   quietr{   r|   r   old)r   r   r   z6(?:(?P<inner_dict>.*?):)?(?P<key>.*?)\=(?P<value>.*?)$win32 
)ra   r   r   r   rg   
returncoderq   compilerc   platformreplacerP   r   groupsKeyError)r   r   r   r   r   r   rgxrz   lineZmobjZ
inner_dictkeyr   r   r   r   	mediainfoA  s<   




r   c                    s   i  t  fdd}|S )Nc                      s(   z d W S      d<  d  Y S r   r   r   cachefunctionr   r   wrapperr  s
   

zcache_codecs.<locals>.wrapperr	   )r   r   r   r   r   cache_codecso  s   r   c                  C   s   t  } | dg}t|ttd}| d d}|jdkrg S tjdkr)|dd}t	
d}t }t }|d	D ])}|| }|sEq9| \}	}
}|	d d
krW||
 |	d dkrb||
 q9||fS )Nz-codecs)r   rt   r   r   r   r   r   z)^([D.][E.][AVS.][I.][L.][S.]) (\w*) +(.*)r   Dr   E)r]   r   r   r   rg   r   rc   r   r   rq   r   setrP   r   rn   r   add)encoderr   r   r   r   Zdecodersencodersr   r   flagscodecr=   r   r   r   get_supported_codecs}  s,   




r   c                   C   
   t  d S r   r   r   r   r   r   get_supported_decoders     
r   c                   C   r   )Nr   r   r   r   r   r   get_supported_encoders  r   r   c                 C   sD   |   }|d |d |d |d  g}t|d |d S )z
	Left-Right -> Mid-Side
	r   r   Zsplit_to_monooverlayZinvert_phaser?   Zfrom_mono_audiosegmentsrA   Zchannelr   r   r   stereo_to_ms  s   (r   c                 C   sL   |   }|d |d d |d |d  d g}t|d |d S )z
	Mid-Side -> Left-Right
	r   r   r   r   r   r   r   r   ms_to_stereo  s   0r   )T)r&   T)NTr   )rx   )1
__future__r   r   r+   rq   rc   
subprocessr   r   mathr   r   r/   r   warningsr   	functoolsr
   ZaudioopImportErrorZ	pyaudiooprd   r   r)   r   r   r$   r   r#   r%   r0   r6   r9   r:   rJ   rX   r]   r_   ra   rf   rw   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sh    






J.
