U
    Ķb&)                     @   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   O/var/www/html/UseVoiceDocker/env/lib/python3.8/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   s`   t | D ]R\}}|g| }ztj|f||W   S  tk
rX   |t| d krT Y qX 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)commandsZcommand_argsargskwargsicommandcmdr   r   r   popen_multipleP   s    	
r1   c                  C   sJ   zt tdgtjtjtd} W n tk
r2   Y dS X |   | jdkS dS )zBDetect whether the FFmpeg backend can be used on this system.
    z-version)stdoutstderrcreationflagsFr   N)r1   COMMANDSr'   PIPE
PROC_FLAGSr)   wait
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   s   t jd}|rDt  d}dd l}|jj|}|jj||B  zJz*t
td|dddgtjtjtjtd| _W n tk
r   t Y nX W 5 |rzdd l}|jj| W 5 t	  X X t| jj|| _| j  |   t| jj| _| j  d S )	Nwin   r   z-iz-fZs16le-)r2   r3   stdinr4   )sysplatform
startswithwindows_error_mode_lockacquirectypeswindllkernel32ZSetErrorModereleaser1   r5   r'   r6   DEVNULLr7   r:   r)   r   r   r2   stdout_readerstart	_get_infor3   stderr_reader)r   filename
block_sizeZwindowsZSEM_NOGPFAULTERRORBOXrF   Zprevious_error_moder   r   r   r   |   s>    	
zFFmpegAudioFile.__init__      $@c              	   c   s   t   }d}z$| jjj|d}|r*|V  nW qW q tjk
r   t   }|s~|| |krvtdd| jjjn|}Y qY qX qdS )z*Read blocks of raw PCM data from the file.N)timeoutzffmpeg output: {}    )	timerK   r   getEmptyr   formatjoinrN   )r   rR   Z
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|krPt	dqd|kr`t
 qd|krt|| qd|kr|| | d	| qq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:   r3   readliner   
isinstancebytesdecodestriplowerr)   r   append_parse_inforX   )r   Z	out_partsliner   r   r   rM      s"    


zFFmpegAudioFile._get_infoc                 C   s   t d|}|r"t|d| _nd| _t d|}|r|d}|dkrRd| _qt d|}|r~ttt| 	d| _qd| _nd| _t d	|}|rt
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   srn   modeZcmatchZdurpartsru   r   r   r   rd      s<    
 
zFFmpegAudioFile._parse_infoc                 C   sx   t | drt| j  | jjdk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:   NrN   rK   )hasattrr:   pollr9   killr8   rN   rX   rK   r2   closer3   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    )rY   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_typeZexc_valZexc_tbr   r   r   __exit__>  s    zFFmpegAudioFile.__exit__N)rQ   )r   r	   r
   r   r   r   rY   rM   rd   r{   r~   r   r   r   r   r   r   r   r<   z   s   7
+r<   )r   r   rj   r'   rA   	threadingrT   ior   
exceptionsr   baser   r5   rB   r7   r   r   r   r   r   Threadr   r1   r;   LockrD   r<   r   r   r   r   <module>   s.   
