3
๐i\1  ใ               @   s.  d dl mZ d dlmZ ddlmZ ddlmZmZ d dl	m
Z
 d dlZdd	 Zd
d ZG dd de
Zdd Zdd Zd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ZG d d! d!eZG d"d# d#eZehdfd$d%Zd*d&d'Zd+d(d)ZdgZdS ),้    )ฺunicode_literals)ฺ
basestring้   )ฺKwargReprNode)ฺescape_charsฺget_hash_int)ฺobjectNc             C   s&   d}x|D ]}t | |r
d}P q
W |S )NFT)ฺ
isinstance)ฺobjฺtypesZvalidZstream_typeฉ r   ๚5/tmp/pip-build-6m2fasei/ffmpeg-python/ffmpeg/nodes.pyฺ_is_of_types
   s    

r   c             C   s   dj dd | D S )Nz, c             S   s   g | ]}d j |j|jqS )z{}.{})ฺformatฺ
__module__ฺ__name__)ฺ.0ฺxr   r   r   ๚
<listcomp>   s    z"_get_types_str.<locals>.<listcomp>)ฺjoin)r   r   r   r   ฺ_get_types_str   s    r   c               @   sR   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Ze	dd Z
e	dd ZdS )ฺStreamz^Represents the outgoing edge of an upstream node; may be used to create more downstream nodes.Nc             C   s8   t ||s"tdjt|t||| _|| _|| _d S )NzHExpected upstream node to be of one of the following type(s): {}; got {})r   ฺ	TypeErrorr   r   ฺtypeฺnodeฺlabelฺselector)ฺselfฺupstream_nodeฺupstream_labelZ
node_typesฺupstream_selectorr   r   r   ฺ__init__   s    
zStream.__init__c             C   s   t t| jt| jgS )N)r   ฺhashr   r   )r   r   r   r   ฺ__hash__'   s    zStream.__hash__c             C   s   t | t |kS )N)r"   )r   ฺotherr   r   r   ฺ__eq__*   s    zStream.__eq__c             C   s>   | j jdd}d}| jr$dj| j}dj|| j|| j j}|S )NF)Zinclude_hashฺ z:{}z{}[{!r}{}] <{}>)r   Z	long_reprr   r   r   Z
short_hash)r   Z	node_reprr   ฺoutr   r   r   ฺ__repr__-   s    zStream.__repr__c             C   sD   | j dk	rtdj| nt|ts2tdj|| jj| j|dS )a  
        Select a component (audio, video) of the stream.

        Example:
            Process the audio and video portions of a stream independently::

                input = ffmpeg.input('in.mp4')
                audio = input['a'].filter("aecho", 0.8, 0.9, 1000, 0.3)
                video = input['v'].hflip()
                out = ffmpeg.output(audio, video, 'out.mp4')
        Nz!Stream already has a selector: {}z*Expected string index (e.g. 'a'); got {!r})r   r   )	r   ฺ
ValueErrorr   r	   r   r   r   ฺstreamr   )r   ฺindexr   r   r   ฺ__getitem__7   s
    

zStream.__getitem__c             C   s   | d S )aส  Select the audio-portion of a stream.

        Some ffmpeg filters drop audio streams, and care must be taken
        to preserve the audio in the final output.  The ``.audio`` and
        ``.video`` operators can be used to reference the audio/video
        portions of a stream so that they can be processed separately
        and then re-combined later in the pipeline.  This dilemma is
        intrinsic to ffmpeg, and ffmpeg-python tries to stay out of the
        way while users may refer to the official ffmpeg documentation
        as to why certain filters drop audio.

        ``stream.audio`` is a shorthand for ``stream['a']``.

        Example:
            Process the audio and video portions of a stream independently::

                input = ffmpeg.input('in.mp4')
                audio = input.audio.filter("aecho", 0.8, 0.9, 1000, 0.3)
                video = input.video.hflip()
                out = ffmpeg.output(audio, video, 'out.mp4')
        ฺar   )r   r   r   r   ฺaudioI   s    zStream.audioc             C   s   | d S )aส  Select the video-portion of a stream.

        Some ffmpeg filters drop audio streams, and care must be taken
        to preserve the audio in the final output.  The ``.audio`` and
        ``.video`` operators can be used to reference the audio/video
        portions of a stream so that they can be processed separately
        and then re-combined later in the pipeline.  This dilemma is
        intrinsic to ffmpeg, and ffmpeg-python tries to stay out of the
        way while users may refer to the official ffmpeg documentation
        as to why certain filters drop audio.

        ``stream.video`` is a shorthand for ``stream['v']``.

        Example:
            Process the audio and video portions of a stream independently::

                input = ffmpeg.input('in.mp4')
                audio = input.audio.filter("aecho", 0.8, 0.9, 1000, 0.3)
                video = input.video.hflip()
                out = ffmpeg.output(audio, video, 'out.mp4')
        ฺvr   )r   r   r   r   ฺvideob   s    zStream.video)N)r   r   ฺ__qualname__ฺ__doc__r!   r#   r%   r(   r,   ฺpropertyr.   r0   r   r   r   r   r      s   

r   c             C   sP   | d kri }n>t | tr"d | i}n*t | ttfr>tt| }nt | trL| }|S )N)r	   r   ฺlistฺtupleฺdictฺ	enumerate)ฺstream_specฺ
stream_mapr   r   r   ฺget_stream_map|   s    


r:   c             C   sF   g }x<t | j D ],}t|ts2tdjt||j|j qW |S )NzExpected Stream; got {})	r4   ฺvaluesr	   r   r   r   r   ฺappendr   )r9   Znodesr*   r   r   r   ฺget_stream_map_nodes   s    
r=   c             C   s   t | }t|S )N)r:   r=   )r8   r9   r   r   r   ฺget_stream_spec_nodes   s    r>   c                   s\   e Zd ZdZedd Zedd Zedd Zg i f fdd		ZdddZ	dd Z
  ZS )ฺNodez	Node basec             C   sV   |d k	r*t ||k r*tdj|t |n(|d k	rRt ||krRtdj|t |d S )Nz,Expected at least {} input stream(s); got {}z+Expected at most {} input stream(s); got {})ฺlenr)   r   )ฺclsr9   ฺ
min_inputsฺ
max_inputsr   r   r   Z__check_input_len   s    zNode.__check_input_lenc             C   s<   x6t |j D ]&}t||stdjt|t|qW d S )NzKExpected incoming stream(s) to be of one of the following types: {}; got {})r4   r;   r   r   r   r   r   )rA   r9   ฺincoming_stream_typesr*   r   r   r   Z__check_input_typesจ   s
    
zNode.__check_input_typesc             C   s6   i }x,t |j D ]\}}|j|j|jf||< qW |S )N)r4   ฺitemsr   r   r   )rA   r9   ฺincoming_edge_mapZdownstream_labelZupstreamr   r   r   Z__get_incoming_edge_mapฒ   s    zNode.__get_incoming_edge_mapc	                sR   t |}	| j|	|| | j|	| | j|	}
tt| j|
||| || _|| _d S )N)	r:   ฺ_Node__check_input_lenฺ_Node__check_input_typesฺ_Node__get_incoming_edge_mapฺsuperr?   r!   ฺ_Node__outgoing_stream_typeZ_Node__incoming_stream_types)r   r8   ฺnamerD   ฺoutgoing_stream_typerB   rC   ฺargsฺkwargsr9   rF   )ฺ	__class__r   r   r!   ฝ   s    
zNode.__init__Nc             C   s   | j | ||dS )z|Create an outgoing stream originating from this node.

        More nodes may be attached onto the outgoing stream.
        )r    )rK   )r   r   r   r   r   r   r*   ั   s    zNode.streamc             C   s,   t |tr| j|j|jdS | j|dS dS )aj  Create an outgoing stream originating from this node; syntactic sugar for ``self.stream(label)``.
        It can also be used to apply a selector: e.g. ``node[0:'a']`` returns a stream with label 0 and
        selector ``'a'``, which is the same as ``node.stream(label=0, selector='a')``.

        Example:
            Process the audio and video portions of a stream independently::

                input = ffmpeg.input('in.mp4')
                audio = input[:'a'].filter("aecho", 0.8, 0.9, 1000, 0.3)
                video = input[:'v'].hflip()
                out = ffmpeg.output(audio, video, 'out.mp4')
        )r   r   )r   N)r	   ฺslicer*   ฺstartฺstop)r   ฺitemr   r   r   r,   ุ   s    
zNode.__getitem__)NN)r   r   r1   r2   ฺclassmethodrG   rH   rI   r!   r*   r,   ฺ__classcell__r   r   )rP   r   r?      s   

r?   c                   s   e Zd Zd fdd	Z  ZS )ฺFilterableStreamNc                s   t t| j||tth| d S )N)rJ   rW   r!   ฺ	InputNodeฺ
FilterNode)r   r   r   r    )rP   r   r   r!   ์   s    
zFilterableStream.__init__)N)r   r   r1   r!   rV   r   r   )rP   r   rW   ๋   s   rW   c                   s2   e Zd ZdZg i f fdd	Zedd Z  ZS )rX   zInputNode typec          
      s$   t t| jd |i tdd||d d S )Nr   )r8   rL   rD   rM   rB   rC   rN   rO   )rJ   rX   r!   rW   )r   rL   rN   rO   )rP   r   r   r!   ๖   s    
zInputNode.__init__c             C   s   t jj| jd S )Nฺfilename)ฺosฺpathฺbasenamerO   )r   r   r   r   ฺ
short_repr  s    zInputNode.short_repr)r   r   r1   r2   r!   r3   r^   rV   r   r   )rP   r   rX   ๓   s   rX   c                   s,   e Zd Zdg i f fdd	Zdd Z  ZS )rY   r   c          
      s&   t t| j||thtd|||d d S )Nr   )r8   rL   rD   rM   rB   rC   rN   rO   )rJ   rY   r!   rW   )r   r8   rL   rC   rN   rO   )rP   r   r   r!   	  s    
zFilterNode.__init__c                sย   | j }| j}| jdkr t|g}dd |D }i  x4t|j D ]$\}}t|d}t|d}| |< q@W dd |D } fddt D }|| }	t| jd}
|	rธ|
djd	j	|	7 }
t|
d
S )Nฺsplitฺasplitc             S   s   g | ]}t |d qS )z\'=:)r   )r   r   r   r   r   r     s    z*FilterNode._get_filter.<locals>.<listcomp>z\'=:c             S   s   g | ]}t |d qS )z\'=:)r   )r   r/   r   r   r   r   $  s    c                s   g | ]}d j | | qS )z{}={})r   )r   ฺk)ฺ
out_kwargsr   r   r   %  s    z={}๚:z\'[],;)r_   r`   )
rN   rO   rL   r@   r4   rE   r   ฺsortedr   r   )r   Zoutgoing_edgesrN   rO   Zout_argsra   r/   Z
arg_paramsZkwarg_paramsฺparamsZparams_textr   )rb   r   ฺ_get_filter  s"    



zFilterNode._get_filter)r   r   r1   r!   rf   rV   r   r   )rP   r   rY     s   rY   c                   s.   e Zd Zg i f fdd	Zedd Z  ZS )ฺ
OutputNodec          
      s&   t t| j||thtdd ||d d S )Nr   )r8   rL   rD   rM   rB   rC   rN   rO   )rJ   rg   r!   rW   ฺOutputStream)r   r*   rL   rN   rO   )rP   r   r   r!   1  s    
zOutputNode.__init__c             C   s   t jj| jd S )NrZ   )r[   r\   r]   rO   )r   r   r   r   r^   =  s    zOutputNode.short_repr)r   r   r1   r!   r3   r^   rV   r   r   )rP   r   rg   0  s   rg   c                   s   e Zd Zd fdd	Z  ZS )rh   Nc                s"   t t| j||ttth|d d S )N)r    )rJ   rh   r!   rg   ฺ
GlobalNodeฺMergeOutputsNode)r   r   r   r    )rP   r   r   r!   C  s
    
zOutputStream.__init__)N)r   r   r1   r!   rV   r   r   )rP   r   rh   B  s   rh   c                   s   e Zd Z fddZ  ZS )rj   c                s"   t t| j||thtdd d d S )Nr   )r8   rL   rD   rM   rB   rC   )rJ   rj   r!   rh   )r   ZstreamsrL   )rP   r   r   r!   N  s    
zMergeOutputsNode.__init__)r   r   r1   r!   rV   r   r   )rP   r   rj   M  s   rj   c                   s"   e Zd Zg i f fdd	Z  ZS )ri   c          
      s&   t t| j||thtdd||d d S )Nr   )r8   rL   rD   rM   rB   rC   rN   rO   )rJ   ri   r!   rh   )r   r*   rL   rN   rO   )rP   r   r   r!   [  s    
zGlobalNode.__init__)r   r   r1   r!   rV   r   r   )rP   r   ri   Z  s   ri   c                s    fdd}|S )Nc                s"   p j  fddD   S )Nc                s   g | ]}t | qS r   )ฺsetattr)r   Zstream_class)ฺfuncฺ	func_namer   r   r   k  s    z6stream_operator.<locals>.decorator.<locals>.<listcomp>)r   )rl   )rL   ฺstream_classes)rl   rm   r   ฺ	decoratori  s    
z"stream_operator.<locals>.decoratorr   )rn   rL   ro   r   )rL   rn   r   ฺstream_operatorh  s    rp   c             C   s   t th| dS )N)rn   rL   )rp   rW   )rL   r   r   r   ฺfilter_operatorq  s    rq   c             C   s   t th| dS )N)rn   rL   )rp   rh   )rL   r   r   r   ฺoutput_operatoru  s    rr   )N)N)ฺ
__future__r   Zpast.builtinsr   Zdagr   ฺ_utilsr   r   ฺbuiltinsr   r[   r   r   r   r:   r=   r>   r?   rW   rX   rY   rg   rh   rj   ri   rp   rq   rr   ฺ__all__r   r   r   r   ฺ<module>   s.   	e	U(	

