U
    a+d4                     @   s   d Z ddlm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mZ ddlmZ ddlmZ ed G dd	 d	Zdd
dZdddZdS )z
This module implements all the functions to read a video or a picture
using ffmpeg. It is quite ugly, as there are many pitfalls to avoid
    )divisionN)DEVNULLPY3)get_setting)cvsecsTc                   @   sJ   e Zd ZdddZdd
dZdddZdd Zdd Zdd Zdd Z	dS )FFMPEG_VideoReaderFNrgb24Tbicubictbrc	                 C   s4  || _ d | _t||||}	|	d | _|	d | _|	d | _|r|d |d f}d |krd}
t|D ]\}}|r`|| j|  }
q`t| jd |
 t| jd |
 f| _n|| _|| _|	d | _	|	d | _
|	d | _|	| _|| _|d	krd
nd| _|d kr| j\}}| j| | d }|| _|   d| _|  | _d S )N	video_fps
video_sizevideo_rotation   r   video_durationdurationvideo_nframesrgba      d   )filenameprocffmpeg_parse_infosfpssizeZrotation	enumerateintresize_algor   Zffmpeg_durationnframesinfospix_fmtdepthbufsize
initializepos
read_framelastread)selfr   print_infosr"   r    check_durationZtarget_resolutionr   
fps_sourcer   Zratioidxtargetwh r/   B/tmp/pip-unpacked-wheel-0yp4gafk/moviepy/video/io/ffmpeg_reader.py__init__   s>    


(




zFFMPEG_VideoReader.__init__r   c                 C   s   |    |dkr:td|}dd||  d| jdd| g}n
d| jg}tdg| ddd	d
ddt| j d| jd| jdddg }| jt	j
t	j
td}tjdkrd|d< t	j|f|| _dS )z"Opens the file, creates the pipe. r   r   z-ssz%.06f-iFFMPEG_BINARYz	-loglevelerror-fZ
image2pipez-vfzscale=%d:%dz
-sws_flagsz-pix_fmtz-vcodecZrawvideo-r"   stdoutstderrstdinnt   creationflagsN)closeminr   r   tupler   r   r    r"   spPIPEr   osnamePopenr   )r'   Z	starttimeoffsetZi_argcmdpopen_paramsr/   r/   r0   r#   L   sB    
  
      
zFFMPEG_VideoReader.initializer   c                 C   sB   | j \}}t|D ]}| jj| j| |  q|  j|7  _dS )zReads and throws away n frames N)r   ranger   r8   readr!   r$   )r'   nr-   r.   ir/   r/   r0   skip_framesk   s    
zFFMPEG_VideoReader.skip_framesc                 C   s   | j \}}| j| | }| jj|}t||krtd| j d|t|f  d| j	| j
d| j	 | j | jf  d t t| dstd| j | j}nFttdrtj|d	d
}ntj|d	d
}||t|||  f|_|| _|S )NzWarning: in file %s, z"%d bytes wanted but %d bytes read,z)at frame %d/%d, at time %.02f/%.02f sec. g      ?z#Using the last valid frame instead.r&   a+  MoviePy error: failed to read the first frame of video file %s. That might mean that the file is corrupted. That may also mean that you are using a deprecated version of FFMPEG. On Ubuntu/Debian for instance the version in the repos is deprecated. Please update to a recent version from the website.
frombufferZuint8)Zdtype)r   r!   r   r8   rJ   lenwarningswarnr   r$   r   r   r   UserWarninghasattrIOErrorr&   nprN   
fromstringshape)r'   r-   r.   nbytessresultr/   r/   r0   r%   t   s:    
 	

zFFMPEG_VideoReader.read_framec                 C   s   t | j| d d }| js6| | || _|  | _|| jkrF| jS || jk s^|| jd krp| | || _n| || j d  |  }|| _|S )a6   Read a file video frame at time t.

        Note for coders: getting an arbitrary frame in the video with
        ffmpeg can be painfully slow if some decoding has to be done.
        This function tries to avoid fetching arbitrary frames
        whenever possible, by moving between adjacent frames.
        gh㈵>r   r   )r   r   r   r#   r$   r%   r&   rM   )r'   tr$   rZ   r/   r/   r0   	get_frame   s    



zFFMPEG_VideoReader.get_framec                 C   sJ   | j r8| j   | j j  | j j  | j   d | _ t| drF| `d S )Nr&   )r   	terminater8   r>   r9   waitrS   r&   r'   r/   r/   r0   r>      s    


zFFMPEG_VideoReader.closec                 C   s   |    d S )N)r>   r_   r/   r/   r0   __del__   s    zFFMPEG_VideoReader.__del__)FNr   TNr	   r
   )r   )r   )
__name__
__module____qualname__r1   r#   rM   r%   r\   r>   r`   r/   r/   r/   r0   r      s           
0

	%#
r   c                 C   s&   |rdnd}t | |dd}|j}~|S )a    Read an image file (PNG, BMP, JPEG...).

    Wraps FFMPEG_Videoreader to read just one image.
    Returns an ImageClip.

    This function is not meant to be used directly in MoviePy,
    use ImageClip instead to make clips out of image files.

    Parameters
    -----------

    filename
      Name of the image file. Can be of any format supported by ffmpeg.

    with_mask
      If the image has a transparency layer, ``with_mask=true`` will save
      this layer as the mask of the returned ImageClip

    r   r   F)r    r)   )r   r&   )r   Z	with_maskr    readerZimr/   r/   r0   ffmpeg_read_image   s
    re   Fr
   c                    s  |  d}tdd| g}|r*|dddg7 }dtjtjtd}tjd	krNd
|d< tj|f|}| \}}	|		d}
~|rt
|
 |
 }d|d krtd|  t }d|d< |r zN|rdnd |rdnd} fdd|D | tdd }t||d< W n   td| |
f Y nX dd |D }|g k|d< |d rzH|d td}ttt| | d  d}||d< W n   td| |
f Y nX fd d!}fd"d#}|d$krz| |d%< W n   | |d%< Y nX n0|d&kr$z| |d%< W n   | |d%< Y nX d'}|d% }d(D ]2}||kr4t|||  d)k r4|| |d%< q4|rt|d |d%  d |d*< |d |d+< nd|d*< d|d+< zVd,d |D }t|r|d }td-|}t|| |  |d.< nd|d.< W n   td/| |
f Y nX d0d |D }|g k|d1< |d1 r|d z8td2}| d | d3  }t||d4< W n   d5|d4< Y nX |S )6aE  Get file infos using ffmpeg.

    Returns a dictionnary with the fields:
    "video_found", "video_fps", "duration", "video_nframes",
    "video_duration", "audio_found", "audio_fps"

    "video_duration" is slightly smaller than "duration" to avoid
    fetching the uncomplete frames at the end, which raises an error.

    z.gifr3   r2   r5   nullz	/dev/nulli r7   r;   r<   r=   utf8zNo such file or directoryz^MoviePy error: the file %s could not be found!
Please check that you entered the correct path.Nr   zframe=z
Duration: r   c                    s   g | ]} |kr|qS r/   r/   .0l)keywordr/   r0   
<listcomp>  s      z&ffmpeg_parse_infos.<locals>.<listcomp>z-([0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9])zfMoviePy error: failed to read the duration of file %s.
Here are the file infos returned by ffmpeg:

%sc                 S   s$   g | ]}d |krt d|r|qS )z Video: z\d+x\d+researchri   r/   r/   r0   rm   &  s       Zvideo_foundz [0-9]*x[0-9]*(,| )r   xr   zjMoviePy error: failed to read video dimensions in file %s.
Here are the file infos returned by ffmpeg:

%sc                     sT   t d }  |  |   dd }d|krHt|ddd }nt|}|S )Nz( [0-9]*.| )[0-9]* tbr r   k i  )ro   rp   startendsplitfloatreplace)matchZs_tbrr
   liner/   r0   get_tbr?  s    z#ffmpeg_parse_infos.<locals>.get_tbrc                     s2   t d } t |  |   dd }|S )Nz( [0-9]*.| )[0-9]* fpsrr   r   )ro   rp   rx   ru   rv   rw   )rz   r   r{   r/   r0   get_fpsJ  s    "z#ffmpeg_parse_infos.<locals>.get_fpsr
   r   r   g	.l?)            2   g{Gz?r   r   c                 S   s$   g | ]}d |krt d|r|qS )zrotate          :\d+$rn   ri   r/   r/   r0   rm   o  s       r   r   zhMoviePy error: failed to read video rotation in file %s.
Here are the file infos returned by ffmpeg:

%sc                 S   s   g | ]}d |kr|qS )z Audio: r/   ri   r/   r/   r0   rm   |  s      Zaudio_foundz
 [0-9]* Hzr   Z	audio_fpsunknown)endswithr   rA   rB   r   rC   rD   rE   communicatedecodeprint
splitlinesrT   dictro   findallr   rp   listmapr   ru   rv   rw   absrO   )r   r(   r)   r*   Zis_GIFrG   rH   r   outputr4   r   linesrZ   indexrz   Zlines_videorY   r}   r~   Zcoefr   rq   Zrotation_linesZrotation_lineZlines_audioZ	hz_stringr/   )rl   r|   r0   r      s    


 
( 

 
 
r   )T)FTr
   )__doc__
__future__r   loggingrC   ro   
subprocessrA   rP   ZnumpyrU   Zmoviepy.compatr   r   Zmoviepy.configr   Zmoviepy.toolsr   captureWarningsr   re   r   r/   r/   r/   r0   <module>   s"   
 1
  