a
    )ºDf-)  ã                   @   sþ   d 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 dZejdkrld	Zn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jƒZdd„ Zdd„ Ze ¡ ZG dd„ deƒZdS )zLRead audio data using the ffmpeg command line tool via its standard
output.
é    N)ÚDEFAULT_BUFFER_SIZEé   )ÚDecodeError)Ú	AudioFile)ZffmpegZavconvÚwin32i   c                   @   s   e Zd ZdS )ÚFFmpegErrorN)Ú__name__Ú
__module__Ú__qualname__© r   r   ú\/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/audioread/ffdec.pyr   &   s   r   c                   @   s   e Zd ZdZdS )ÚCommunicationErrorz2Raised when the output of FFmpeg is not parseable.N©r   r	   r
   Ú__doc__r   r   r   r   r   *   s   r   c                   @   s   e Zd ZdZdS )ÚUnsupportedErrorz(The file could not be decoded by FFmpeg.Nr   r   r   r   r   r   .   s   r   c                   @   s   e Zd ZdZdS )ÚNotInstalledErrorz!Could not find the ffmpeg binary.Nr   r   r   r   r   r   2   s   r   c                   @   s   e Zd ZdZdS )ÚReadTimeoutErrorz4Reading from the ffmpeg command-line tool timed out.Nr   r   r   r   r   r   6   s   r   c                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )	ÚQueueReaderThreadzWA thread that consumes data from a filehandle and sends the data
    over a Queue.
    é   Fc                    s8   t ƒ  ¡  || _|| _d| _|| _|r*d nt ¡ | _d S )NT)ÚsuperÚ__init__ÚfhÚ	blocksizeÚdaemonÚdiscardÚqueueÚQueue)Úselfr   r   r   ©Ú	__class__r   r   r   >   s    
zQueueReaderThread.__init__c                 C   s,   | j  | j¡}| js | j |¡ |s q(q d S ©N)r   Úreadr   r   r   Úput)r   Údatar   r   r   ÚrunF   s
    zQueueReaderThread.run)r   F)r   r	   r
   r   r   r$   Ú__classcell__r   r   r   r   r   :   s   r   c              	   O   sd   t | ƒD ]V\}}|g| }ztj|g|¢R i |¤ŽW   S  ty\   |t| ƒd krX‚ Y q0 qdS )ak  Like `subprocess.Popen`, but can try multiple commands in case
    some are not available.

    `commands` is an iterable of command names and `command_args` are
    the rest of the arguments that, when appended to the command name,
    make up the full first argument to `subprocess.Popen`. The
    other positional and keyword arguments are passed through.
    r   N)Ú	enumerateÚ
subprocessÚPopenÚOSErrorÚlen)ÚcommandsÚcommand_argsÚargsÚkwargsÚiÚcommandÚcmdr   r   r   Úpopen_multipleP   s    	
r2   c                  C   sH   zt tdgtjtjtd} W n ty0   Y dS 0 |  ¡  | jdkS dS )zBDetect whether the FFmpeg backend can be used on this system.
    z-version)ÚstdoutÚstderrÚcreationflagsFr   N)r2   ÚCOMMANDSr'   ÚPIPEÚ
PROC_FLAGSr)   ÚcommunicateÚ
returncode)Úprocr   r   r   Ú	availablec   s    û
r<   c                   @   s^   e Zd ZdZefdd„Zd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 )ÚFFmpegAudioFilez9An audio file decoded by the ffmpeg command-line utility.c                 C   s2  t j d¡}|rDt ¡  d}dd l}|jj |¡}|jj ||B ¡ zzz*t	t
d|dddgtjtjtjtd| _W n tyˆ   tƒ ‚Y n0 W |rôz"dd l}|jj |¡ W t ¡  qôt ¡  0 n4|ròz"dd l}|jj |¡ W t ¡  n
t ¡  0 0 t| jj|ƒ| _| j ¡  |  ¡  t| jjƒ| _| j ¡  d S )	NÚwiné   r   z-iz-fZs16leú-)r3   r4   Ústdinr5   )ÚsysÚplatformÚ
startswithÚwindows_error_mode_lockÚacquireÚctypesÚwindllÚkernel32ZSetErrorModer2   r6   r'   r7   ÚDEVNULLr8   r;   r)   r   Úreleaser   r3   Ústdout_readerÚstartÚ	_get_infor4   Ústderr_reader)r   ÚfilenameÚ
block_sizeZwindowsZSEM_NOGPFAULTERRORBOXrG   Zprevious_error_moder   r   r   r   |   sH    ÿÿú	û
zFFmpegAudioFile.__init__ç      $@c              	   c   sˆ   t   ¡ }d}z$| jjj|d}|r*|V  nW q„W q tjy€   t   ¡ }|s||| |krttd d | jjj¡¡ƒ‚n|}Y qY q0 qdS )z*Read blocks of raw PCM data from the file.N)Útimeoutzffmpeg output: {}ó    )	ÚtimerL   r   ÚgetÚEmptyr   ÚformatÚjoinrO   )r   rS   Ú
start_timer#   Zend_timer   r   r   Ú	read_data³   s     ÿzFFmpegAudioFile.read_datac                 C   sž   g }| j j ¡ }|stdƒ‚t|tƒr2| dd¡}| ¡  ¡ }d|v rPt	dƒ‚qd|v r`t
ƒ ‚qd|v rt| |¡ qd|v r| |¡ |  d	 |¡¡ qšqd
S )zrReads the tool's output from its stderr stream, extracts the
        relevant information, and parses it.
        zstream info not foundÚutf8Úignorezno such filezfile not foundzinvalid data foundz	duration:zaudio:Ú N)r;   r4   Úreadliner   Ú
isinstanceÚbytesÚdecodeÚstripÚlowerr)   r   ÚappendÚ_parse_inforY   )r   Z	out_partsÚliner   r   r   rN   Ñ   s"    


zFFmpegAudioFile._get_infoc                 C   sô   t  d|¡}|r"t| d¡ƒ| _nd| _t  d|¡}|r†| d¡}|dkrRd| _qŒt  d|¡}|r~ttt| ¡  	d¡ƒƒ| _qŒd| _nd| _t  d	|¡}|rêt
tt| ¡ ƒƒ}|d d
 d
 |d d
  |d  t|d ƒd  }|| _nd| _dS )zgGiven relevant data from the ffmpeg output, set audio
        parameter fields on this object.
        z(\d+) hzr   r   zhz, ([^,]+),Zstereor?   z(\d+)\.?(\d)?Ú.z duration: (\d+):(\d+):(\d+).(\d)é<   é   é
   N)ÚreÚsearchÚintÚgroupZ
samplerateZchannelsÚmatchÚsumÚmapÚsplitÚlistÚgroupsÚfloatÚduration)r   Úsrp   ÚmodeZcmatchZdurpartsrw   r   r   r   rf   í   s:    
ÿ
ÿþýÿzFFmpegAudioFile._parse_infoc                 C   sx   t | dƒrt| j ¡  | jjdu r4| j ¡  | j ¡  t | dƒrH| j ¡  t | dƒr\| j ¡  | jj	 
¡  | jj 
¡  dS )z6Close the ffmpeg process used to perform the decoding.r;   NrO   rL   )Úhasattrr;   Úpollr:   ÚkillÚwaitrO   rY   rL   r3   Úcloser4   ©r   r   r   r   r~     s    







zFFmpegAudioFile.closec                 C   s   |   ¡  d S r    ©r~   r   r   r   r   Ú__del__3  s    zFFmpegAudioFile.__del__c                 C   s   |   ¡ S r    )r[   r   r   r   r   Ú__iter__7  s    zFFmpegAudioFile.__iter__c                 C   s   | S r    r   r   r   r   r   Ú	__enter__;  s    zFFmpegAudioFile.__enter__c                 C   s   |   ¡  dS )NFr€   )r   Úexc_typeÚexc_valÚexc_tbr   r   r   Ú__exit__>  s    zFFmpegAudioFile.__exit__N)rR   )r   r	   r
   r   r   r   r[   rN   rf   r~   r   r‚   rƒ   r‡   r   r   r   r   r=   z   s   7
+r=   )r   r   rl   r'   rB   Ú	threadingrU   Úior   Ú
exceptionsr   Úbaser   r6   rC   r8   r   r   r   r   r   ÚThreadr   r2   r<   ÚLockrE   r=   r   r   r   r   Ú<module>   s.   
