U
    -Z$dP0                     @   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k
r   d dlZY nX ejdkre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dDddZdEdd Z dFd!d"Z!d#d$ Z"d%d& Z#d'd( Z$d)d* Z%d+d, Z&d-d. Z'd/d0 Z(dGd2d3Z)d4d5 Z*d6d7 Z+e+d8d9 Z,d:d; Z-d<d= Z.d>d? Z/d@dA Z0dS )H    )divisionN)PopenPIPE)logceil)TemporaryFile)warnwraps)   r            )          bhi)i   )i i  )i   ic                 C   s   t |  S N)FRAME_WIDTHS	bit_depth r   //tmp/pip-unpacked-wheel-94qg_ebr/pydub/utils.pyget_frame_width&   s    r   Tc                 C   s   t |  }|s| }|S r   )ARRAY_TYPESupper)r   signedtr   r   r   get_array_type*   s    r!   c                 C   s   t |  S r   )ARRAY_RANGESr   r   r   r   get_min_max_value1   s    r#   w+bc                 C   sv   d}| d kr|rt |d} d}t| tr8t| |d} d}z t| tjrVt| |d} d}W n tk
rl   Y nX | |fS )NF)modeT)r   
isinstance
basestringopenosPathLikeAttributeError)fdr%   tempfileZclose_fdr   r   r   _fd_or_path_or_tempfile5   s    

r.   c                 C   s(   t | } |rd| d  S d| d  S dS )z_
    Converts the input db to a float, which represents the equivalent
    ratio in power.
    
      N)float)dbusing_amplituder   r   r   db_to_floatK   s    r4   c                 C   sN   t | } |dk	r| | } | dkr*t d S |r<dt| d S dt| d S 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   infr0   r/   )r1   r   )ZratioZval2r3   r   r   r   ratio_to_dbW   s    
r6   c                    sD   t | tr|   fddS  dk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       z'register_pydub_effect.<locals>.<lambda>Nr   )AudioSegment)r&   r'   __name__audio_segmentr=   setattr)r8   r:   r=   r   r9   r   r7   l   s    
r7   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   r?   chunk_lengthr   r   
<listcomp>   s   zmake_chunks.<locals>.<listcomp>)r   lenr1   rangeint)r?   rC   Znumber_of_chunksr   rB   r   make_chunks   s    
rH   c                 C   st   t jdkr| ds| d7 } t jgt jd t j }|D ]4}t j|| }t j	|r:t 
|t jr:|  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    rV   c                   C   s*   t drdS t drdS tdt dS 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 workNrV   r   RuntimeWarningr   r   r   r   get_encoder_name   s    
rZ   c                   C   s*   t drdS t drdS tdt dS dS )rW   ZavplayZffplayzGCouldn't find ffplay or avplay - defaulting to ffplay, but may not workNrX   r   r   r   r   get_player_name   s    
r[   c                   C   s*   t drdS t drdS tdt dS dS )z;
    Return probe application, either avconv or ffmpeg
    ZavprobeffprobezJCouldn't find ffprobe or avprobe - defaulting to ffprobe, but may not workNrX   r   r   r   r   get_prober_name   s    
r]   c                 C   sz   t jdkr>ttf}t jdkr(|tjf7 }t| |rdt| S n&t| trV| t 	 S t| trd| S t
dt| dS )z<Wrapper for os.fsdecode which was introduced in python 3.2 .)r   r   )r      z!type {0} not accepted by fsdecodeN)sysversion_infor'   bytesr)   r*   r&   fsdecodedecodegetfilesystemencoding	TypeErrorformattype)filenameZPathLikeTypesr   r   r   rb      s    




rb   c                 C   s   i }d}t || D ]|}|ddk	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rA   xr   r   r   rD      s      z"get_extra_info.<locals>.<listcomp>z[:,]Z	stream_id)refinditergrouprE   rQ   rN   rG   )stderr
extra_infoZ	re_streamr   Zcontent_linetokensr   r   r   get_extra_info   s    
rs   c                 C   sT  t  }ddddg}z|t| g7 }d}d}W nn tk
r   |dkrX|dt|dg7 }n
|d	g7 }t}t| d
dd\}}|d | }|r|  Y nX |ddg| }t	||ttd}	|	j
|d\}
}|
dd}
|dd}t|
}|s|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! n|r||d|d ||dt|d ||d t|d nftd"|r||d| ||dd# ||d d# n2t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stdoutrp   )inpututf-8ignorec                 S   s   g | ]}|d  dkr|qS )Z
codec_typeaudior   rk   r   r   r   rD      s      z"mediainfo_json.<locals>.<listcomp>Zstreamsc                 S   s    || ks| | dkr|| |< 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\))?$@   )r]   rb   re   strr   r.   seekreadcloser   communicaterc   r|   loadsrs   rE   rm   matchro   rG   )filepathZread_ahead_limitprobercommand_argsZstdin_parameterZ
stdin_datafileZ
close_filecommandresoutputrp   rv   rq   Zaudio_streamsr   r   tokenmm2r   r   r   mediainfo_json   sp     



r   c              	   C   s  t  }dddd| g}|ddg| }t|td}| d d	}|jdkrn|g| }t|td d d	}td
}i }tj	dkr|
dd}|dD ]d}||}	|	r|	 \}
}}|
rz||
  W n tk
r   i ||
< Y nX |||
 |< q|||< q|S )zWReturn dictionary with media info(codec, duration, size, bitrate...) from filepath
    ru   quietrw   rx   r{   old)r~   r   r   z6(?:(?P<inner_dict>.*?):)?(?P<key>.*?)\=(?P<value>.*?)$win32 
)r]   r   r   r   rc   
returncoderm   compiler_   platformreplacerN   r   groupsKeyError)r   r   r   r   r   r   rgxrv   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 X d 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rR|dd}t	
d}t }t }|d	D ]R}|| }|sqr| \}	}
}|	d d
kr||
 |	d dkrr||
 qr||fS )Nz-codecs)r~   rp   r   r   r   r   r   z)^([D.][E.][AVS.][I.][L.][S.]) (\w*) +(.*)r   Dr   E)rZ   r   r   r   rc   r   r_   r   r   rm   r   setrN   r   rj   r   add)encoderr   r   r   r   Zdecodersencodersr   r   flagscodecr:   r   r   r   get_supported_codecs}  s*    



r   c                   C   s
   t  d S r   r   r   r   r   r   get_supported_decoders  s    r   c                   C   s
   t  d S )Nr   r   r   r   r   r   get_supported_encoders  s    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r?   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)T)NT)N)rt   )1
__future__r   r|   r)   rm   r_   
subprocessr   r   mathr   r   r-   r   warningsr   	functoolsr
   ZaudioopImportErrorZ	pyaudioopr`   r   r'   r   r   r"   r   r!   r#   r.   r4   r6   r7   rH   rV   rZ   r[   r]   rb   rs   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sd   






J.
