
    g$^                         d Z ddlZ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ZddlZe
rddlmZ ddlmZmZmZmZmZmZ  G d	 d
      Zy)zImplements the central object of MoviePy, the Clip, and all the methods that
are common to the two subclasses of Clip, VideoClip and AudioClip.
    N)reduce)Real)add)TYPE_CHECKINGList)Effect)apply_to_audioapply_to_maskconvert_parameter_to_secondsoutplacerequires_durationuse_clip_fps_by_defaultc                   0   e Zd ZdZdZd Zd Z edg      d        Zd'dZ	d(d	Z
d
ed   fdZee edg      ed)d                            Zee edg      ed                             Zee edg      ed)d                            Zed        Zd*dZed        Zed        Z eddg      eed+d                     Z eddg      d        Zd,dedefdZd,defdZeed-d              Z edg      d        Zd Z d  Z!d! Z"d" Z#d# Z$d$ Z%d% Z&d& Z'y).Clipa  Base class of all clips (VideoClips and AudioClips).

    Attributes
    ----------

    start : float
      When the clip is included in a composition, time of the
      composition at which the clip starts playing (in seconds).

    end : float
      When the clip is included in a composition, time of the
      composition at which the clip stops playing (in seconds).

    duration : float
      Duration of the clip (in seconds). Some clips are infinite, in
      this case their duration will be ``None``.
    	TEMP_MPY_c                 X    d| _         d | _        d | _        d| _        d | _        d | _        y )Nr   F)startenddurationmemoize
memoized_tmemoized_frameselfs    U/var/www/it7/html/youtubeDownloader/venv/lib/python3.12/site-packages/moviepy/Clip.py__init__zClip.__init__5   s-    
"    c                 ,    t        j                  |       S )zGAllows the usage of ``.copy()`` in clips as chained methods invocation.)_copycopyr   s    r   r    z	Clip.copy>   s    zz$r   tc                     | j                   r<|| j                  k(  r| j                  S | j                  |      }|| _        || _        |S | j                  |      S )a  Gets a numpy array representing the RGB picture of the clip,
        or (mono or stereo) value for a sound clip, at time ``t``.

        Parameters
        ----------

        t : float or tuple or str
          Moment of the clip whose frame will be returned.
        )r   r   r   frame_function)r   r!   frames      r   	get_framezClip.get_frameB   sX     <<DOO#***++A."#&+#&&q))r   Nc                      |g } j                   fd      }|sd|_        d|_        t        |t              r|g}|D ]2  }t        ||d      }||j                  |      }t        |||       4 |S )a>  General processing of a clip.

        Returns a new Clip whose frames are a transformation
        (through function ``func``) of the frames of the current clip.

        Parameters
        ----------

        func : function
          A function with signature (gf,t -> frame) where ``gf`` will
          represent the current clip's ``get_frame`` method,
          i.e. ``gf`` is a function (t->image). Parameter `t` is a time
          in seconds, `frame` is a picture (=Numpy array) which will be
          returned by the transformed clip (see examples below).

        apply_to : {"mask", "audio", ["mask", "audio"]}, optional
          Can be either ``'mask'``, or ``'audio'``, or
          ``['mask','audio']``.
          Specifies if the filter should also be applied to the
          audio or the mask of the clip, if any.

        keep_duration : bool, optional
          Set to True if the transformation does not change the
          ``duration`` of the clip.

        Examples
        --------

        In the following ``new_clip`` a 100 pixels-high clip whose video
        content scrolls from the top to the bottom of the frames of
        ``clip`` at 50 pixels per second.

        >>> filter = lambda get_frame,t : get_frame(t)[int(t):int(t)+50, :]
        >>> new_clip = clip.transform(filter, apply_to='mask')

        Nc                 *     j                   |       S N)r%   )r!   funcr   s    r   <lambda>z Clip.transform.<locals>.<lambda>   s    d4>>ST>U r   keep_duration)with_updated_frame_functionr   r   
isinstancestrgetattr	transformsetattr)r   r)   apply_tor,   new_clip	attributeattribute_valuenew_attribute_values   ``      r   r1   zClip.transformY   s    J H 334UV $HHLh$ zH! 	BI%h	4@O*&5&?&? '@ '# )-@A	B r   c                 :    |g }| j                  fd||      S )a  
        Returns a Clip instance playing the content of the current clip
        but with a modified timeline, time ``t`` being replaced by the return
        of `time_func(t)`.

        Parameters
        ----------

        time_func : function
          A function ``t -> new_t``.

        apply_to : {"mask", "audio", ["mask", "audio"]}, optional
          Can be either 'mask', or 'audio', or ['mask','audio'].
          Specifies if the filter ``transform`` should also be applied to the
          audio or the mask of the clip, if any.

        keep_duration : bool, optional
          ``False`` (default) if the transformation modifies the
          ``duration`` of the clip.

        Examples
        --------

        .. code:: python

            # plays the clip (and its mask and sound) twice faster
            new_clip = clip.time_transform(lambda t: 2*t, apply_to=['mask', 'audio'])

            # plays the clip starting at t=3, and backwards:
            new_clip = clip.time_transform(lambda t: 3-t)

        c                       |  |            S r(    )r%   r!   	time_funcs     r   r*   z%Clip.time_transform.<locals>.<lambda>   s    9Q<!8 r   r+   )r1   )r   r;   r3   r,   s    `  r   time_transformzClip.time_transform   s0    B H~~8'  
 	
r   effectsr   c                 v    | j                         }|D ]#  }|j                         }|j                  |      }% |S )a  Return a copy of the current clip with the effects applied

        >>> new_clip = clip.with_effects([vfx.Resize(0.2, method="bilinear")])

        You can also pass multiple effect as a list

        >>> clip.with_effects([afx.VolumeX(0.5), vfx.Resize(0.3), vfx.Mirrorx()])
        )r    apply)r   r=   r4   effecteffect_copys        r   with_effectszClip.with_effects   sB     99; 	3F !++-K"((2H		3 r   c                     || _         | j                  |r|| j                  z   | _        y| j                  | j                  | j                   z
  | _        yy)a  Returns a copy of the clip, with the ``start`` attribute set
        to ``t``, which can be expressed in seconds (15.35), in (min, sec),
        in (hour, min, sec), or as a string: '01:03:05.35'.

        These changes are also applied to the ``audio`` and ``mask``
        clips of the current clip, if they exist.

        Parameters
        ----------

        t : float or tuple or str
          New ``start`` attribute value for the clip.

        change_end : bool optional
          Indicates if the ``end`` attribute value must be changed accordingly,
          if possible. If ``change_end=True`` and the clip has a ``duration``
          attribute, the ``end`` attribute of the clip will be updated to
          ``start + duration``. If ``change_end=False`` and the clip has a
          ``end`` attribute, the ``duration`` attribute of the clip will be
          updated to ``end - start``.
        N)r   r   r   )r   r!   
change_ends      r   
with_startzClip.with_start   sJ    4 
MM%:4==(DHXX! HHtzz1DM "r   c                     || _         | j                   y| j                  ,| j                  t        d|| j                  z
        | _        yy| j                   | j                  z
  | _        y)a  Returns a copy of the clip, with the ``end`` attribute set to ``t``,
        which can be expressed in seconds (15.35), in (min, sec), in
        (hour, min, sec), or as a string: '01:03:05.35'. Also sets the duration
        of the mask and audio, if any, of the returned clip.

        Parameters
        ----------

        t : float or tuple or str
          New ``end`` attribute value for the clip.
        Nr   )r   r   r   max)r   r!   s     r   with_endzClip.with_end   s^      88::}}( A$56
 ) !HHtzz1DMr   r   c                     || _         |r|d| _        y| j                  |z   | _        y| j                   t        d      | j                  |z
  | _        y)a  Returns a copy of the clip, with the  ``duration`` attribute set to
        ``t``, which can be expressed in seconds (15.35), in (min, sec), in
        (hour, min, sec), or as a string: '01:03:05.35'. Also sets the duration
        of the mask and audio, if any, of the returned clip.

        If ``change_end is False``, the start attribute of the clip will be
        modified in function of the duration and the preset end of the clip.

        Parameters
        ----------

        duration : float
          New duration attribute value for the clip.

        change_end : bool, optional
          If ``True``, the ``end`` attribute value of the clip will be adjusted
          accordingly to the new duration using ``clip.start + duration``.
        Nz2Cannot change clip start when new duration is None)r   r   r   
ValueError)r   r   rD   s      r   with_durationzClip.with_duration
  sO    . ! ( 0tDH

X8MDH}}$ !UVVH,DJr   c                     || _         y)zSets a ``frame_function`` attribute for the clip. Useful for setting
        arbitrary/complicated videoclips.

        Parameters
        ----------

        frame_function : function
          New frame creator function for the clip.
        N)r#   )r   r#   s     r   r-   z Clip.with_updated_frame_function*  s     -r   c                     |r,ddl m} | j                   ||| j                  z        g      }n| j	                         }||_        |S )a  Returns a copy of the clip with a new default fps for functions like
        write_videofile, iterframe, etc.

        Parameters
        ----------

        fps : int
          New ``fps`` attribute value for the clip.

        change_duration : bool, optional
          If ``change_duration=True``, then the video speed will change to
          match the new fps (conserving all frames 1:1). For example, if the
          fps is halved in this mode, the duration will be doubled.
        r   MultiplySpeed)moviepy.video.fx.MultiplySpeedrO   rB   fpsr    )r   rQ   change_durationrO   newclips        r   with_fpszClip.with_fps7  sA     D''sTXX~)F(GHGiikGr   c                     || _         y)zSays whether the clip is a mask or not.

        Parameters
        ----------

        is_mask : bool
          New ``is_mask`` attribute value for the clip.
        N)is_mask)r   rV   s     r   with_is_maskzClip.with_is_maskP       r   c                     || _         y)zSets whether the clip should keep the last frame read in memory.

        Parameters
        ----------

        memoize : bool
          Indicates if the clip should keep the last frame read in memory.
        N)r   )r   r   s     r   with_memoizezClip.with_memoize\  rX   r   
start_timeend_timec                    dk  r| j                   z   | j                   0| j                   k\  r!t        dz  dz   d| j                   z  z         | j                  fdg       }|| j                   | j                   }n;|9|dk  r4| j                   t        dt        |f      z        | j                   |z   }|(|z
  |_         |j                  |j                   z   |_        |S )a
  Returns a clip playing the content of the current clip between times
        ``start_time`` and ``end_time``, which can be expressed in seconds
        (15.35), in (min, sec), in (hour, min, sec), or as a string:
        '01:03:05.35'.

        The ``mask`` and ``audio`` of the resulting subclip will be subclips of
        ``mask`` and ``audio`` the original clip, if they exist.

        It's equivalent to slice the clip as a sequence, like
        ``clip[t_start:t_end]``.

        Parameters
        ----------

        start_time : float or tuple or str, optional
          Moment that will be chosen as the beginning of the produced clip. If
          is negative, it is reset to ``clip.duration + start_time``.

        end_time : float or tuple or str, optional
          Moment that will be chosen as the end of the produced clip. If not
          provided, it is assumed to be the duration of the clip (potentially
          infinite). If is negative, it is reset to ``clip.duration + end_time``.
          For instance:

          >>> # cut the last two seconds of the clip:
          >>> new_clip = clip.subclipped(0, -2)

          If ``end_time`` is provided or if the clip has a duration attribute,
          the duration of the returned clip is set automatically.
        r   zstart_time (%.02f) z"should be smaller than the clip's zduration (%.02f).c                     | z   S r(   r:   )r!   r[   s    r   r*   z!Clip.subclipped.<locals>.<lambda>  s    Z r   r3   zZSubclip with negative times (here %s) can only be extracted from clips with a ``duration``)r   rJ   r<   r/   r   r   r   r[   r\   r4   s    `  r   
subclippedzClip.subclippedh  s   D > 3JMM%J$--,G%
267%56  &&'?"&M4==#<}}H"A}}$ P J12	4   ==83 (: 5H#>>H,=,==HLr   c                     | j                  fdddg      }| j                  !|j                  | j                  z
  z
        S |S )a<  
        Returns a clip playing the content of the current clip but
        skips the extract between ``start_time`` and ``end_time``, which can be
        expressed in seconds (15.35), in (min, sec), in (hour, min, sec),
        or as a string: '01:03:05.35'.

        If the original clip has a ``duration`` attribute set,
        the duration of the returned clip  is automatically computed as
        `` duration - (end_time - start_time)``.

        The resulting clip's ``audio`` and ``mask`` will also be cutout
        if they exist.

        Parameters
        ----------

        start_time : float or tuple or str
          Moment from which frames will be ignored in the resulting output.

        end_time : float or tuple or str
          Moment until which frames will be ignored in the resulting output.
        c                      | | k\  z
  z  z   S r(   r:   )r!   r\   r[   s    r   r*   z+Clip.with_section_cut_out.<locals>.<lambda>  s    a1
?x*/DEE r   audiomaskr_   )r<   r   rK   r`   s    `` r   with_section_cut_outzClip.with_section_cut_out  sU    0 &&Ev& ' 

 ==$))$--8j;P*QRROr   factorfinal_durationc                 B    ddl m} | j                   |||      g      S )zReturns a clip playing the current clip but at a speed multiplied
        by ``factor``. For info on the parameters, please see ``vfx.MultiplySpeed``.
        r   rN   )rg   rh   )rP   rO   rB   )r   rg   rh   rO   s       r   with_speed_scaledzClip.with_speed_scaled  s(     	A  &HI
 	
r   c                 D    ddl m} | j                   ||||      g      S )zReturns a new clip with audio volume multiplied by the value `factor`.
        For info on the parameters, please see ``afx.MultiplyVolume``
        r   )MultiplyVolume)rg   r[   r\   )moviepy.audio.fx.MultiplyVolumerl   rB   )r   rg   r[   r\   rl   s        r   with_volume_scaledzClip.with_volume_scaled  s*     	C  6j8TU
 	
r   c           	   #   B  K   t        j                  |      }|j                  t        j                  dt        | j                  |z                    D ]G  }||z  }| j                  |      }| |j                  |k7  r|j                  |      }|r||f D| I yw)aO  Iterates over all the frames of the clip.

        Returns each frame of the clip as a HxWxN Numpy array,
        where N=1 for mask clips and N=3 for RGB clips.

        This function is not really meant for video editing. It provides an
        easy way to do frame-by-frame treatment of a video, for fields like
        science, computer vision...

        Parameters
        ----------

        fps : int, optional
          Frames per second for clip iteration. Is optional if the clip already
          has a ``fps`` attribute.

        with_times : bool, optional
          Ff ``True`` yield tuples of ``(t, frame)`` where ``t`` is the current
          time for the frame, otherwise only a ``frame`` object.

        logger : str, optional
          Either ``"bar"`` for progress bar or ``None`` or any Proglog logger.

        dtype : type, optional
          Type to cast Numpy array frames. Use ``dtype="uint8"`` when using the
          pictures to write video, images..

        Examples
        --------


        .. code:: python

            # prints the maximum of red that is contained
            # on the first line of each frame of the clip.
            from moviepy import VideoFileClip
            myclip = VideoFileClip('myvideo.mp4')
            print([frame[0,:,0].max()
                  for frame in myclip.iter_frames()])
        r   )frame_indexN)
proglogdefault_bar_loggeriter_barnparangeintr   r%   dtypeastype)r   rQ   
with_timesloggerrw   rp   r!   r$   s           r   iter_frameszClip.iter_frames  s     V ++F3!??		!S)<%=> + 
 	K
 c!ANN1%E!u(<U+h	s   BBc                    t        |t        j                        r~|j                         |j	                         }}| j
                  || j
                  k\  ry|| j                  k  ryd|| j                  k\  z  }| j
                  ||| j
                  k  z  }|S || j                  k\  xr | j
                  du xs || j
                  k  S )a  If ``t`` is a time, returns true if t is between the start and the end
        of the clip. ``t`` can be expressed in seconds (15.35), in (min, sec), in
        (hour, min, sec), or as a string: '01:03:05.35'. If ``t`` is a numpy
        array, returns False if none of the ``t`` is in the clip, else returns a
        vector [b_1, b_2, b_3...] where b_i is true if tti is in the clip.
        NF   )r.   rt   ndarrayminrG   r   r   )r   r!   tmintmaxresults        r   
is_playingzClip.is_playing  s     a$!%%'$D$4488+;djj  !tzz/*Fxx#!txx-'M OO488t+;*NTXXOr   c                      y)z&Release any resources that are in use.Nr:   r   s    r   closez
Clip.close:  s     	r   c                 0   t        |t              st        S | j                  | j                  z  }|j                  |j                  z  }||k7  ryt        | j                         |j                               D ]  \  }}t        j                  ||      r y y)NFT)	r.   r   NotImplementedr   rQ   zipr{   rt   array_equal)r   otherself_lengthother_lengthframe1frame2s         r   __eq__zClip.__eq__F  s    %&!! mmdhh.~~		1,& "$"2"2"4e6G6G6IJ 	NFF>>&&1	 r   c                     | S )zh
        Support the Context Manager protocol,
        to ensure that resources are cleaned up.
        r:   r   s    r   	__enter__zClip.__enter__W  s	    
 r   c                 $    | j                          y r(   )r   )r   exc_type	exc_value	tracebacks       r   __exit__zClip.__exit__^  s    

r   c                      ddg}t        |t              r j                  |j                  xs d|j                  xs  j
                        |j                  rxt        |j                        dk7  r8j                  fd|d      j                  dj
                  z  z        |j                  dk  rj                  fd	d|
      S t        |t              rt        t         fd|D              S  j                  |      S )az  
        Support extended slice and index operations over
        a clip object.

        Simple slicing is implemented via `subclip`.
        So, ``clip[t_start:t_end]`` is equivalent to
        ``clip.subclipped(t_start, t_end)``. If ``t_start`` is not
        given, default to ``0``, if ``t_end`` is not given,
        default to ``self.duration``.

        The slice object optionally support a third argument as
        a ``speed`` coefficient (that could be negative),
        ``clip[t_start:t_end:speed]``.

        For example ``clip[::-1]`` returns a reversed (a time_mirror fx)
        the video and ``clip[:5:2]`` returns the segment from 0 to 5s
        accelerated to 2x (ie. resulted duration would be 2.5s)

        In addition, a tuple of slices is supported, resulting in the concatenation
        of each segment. For example ``clip[(:1, 2:)]`` return a clip
        with the segment from 1 to 2s removed.

        If ``key`` is not a slice or tuple, we assume it's a time
        value (expressed in any format supported by `cvsec`)
        and return the frame at that time, passing the key
        to ``get_frame``.
        re   rd   r   r}   c                     | z  S r(   r:   )r!   rg   s    r   r*   z"Clip.__getitem__.<locals>.<lambda>  s    &1* r   T)r3   r,   g      ?c                 (    j                   | z
  dz
  S )Nr}   )r   )r!   clips    r   r*   z"Clip.__getitem__.<locals>.<lambda>  s    $--!"3a"7 r   )r,   r3   c              3   (   K   | ]	  }|     y wr(   r:   ).0kr   s     r   	<genexpr>z#Clip.__getitem__.<locals>.<genexpr>  s     5AQ5s   )r.   slicera   r   stopr   stepabsr<   rK   tupler   r   r%   )r   keyr3   r   rg   s   `  @@r   __getitem__zClip.__getitem__a  s    8 G$c5! ??399>3883Lt}}MDxxSXXQ;..,xt / D  --cDMM.AF.JKD88a<..7&*!) / D
 KU##5566>>#&&r   c                      y r(   r:   r   s    r   __del__zClip.__del__  s    
 	r   c                     t         S r(   )r   )r   r   s     r   __add__zClip.__add__  s    r   c                 j    t        |t              st        S ddlm} | j                   ||      g      S )Nr   )Loop)r.   r   r   moviepy.video.fx.Loopr   rB   )r   nr   s      r   __mul__zClip.__mul__  s,    !T"!!.  $q'++r   )NT)NF)T)F)r   N)NN)NFNN)(__name__
__module____qualname____doc___TEMP_FILES_PREFIXr   r    r   r%   r1   r<   r   rB   r
   r	   r   rE   rH   rK   r-   rT   rW   rZ   ra   rf   floatrj   rn   r   r   r{   r   r   r   r   r   r   r   r   r   r:   r   r   r   r      s   , %#  "3%(* )*,:x(
TDN $ !3%(2  )  28 !3%(2  )  2* !:,/-  0  -8 
- 
-2 	 	 	 	 "<"<=A   >AF "<"<= >B
 
e 

 
 7  7r "3%(P )P4
"7'r,r   r   )r   r    r   	functoolsr   numbersr   operatorr   typingr   r   numpyrt   rq   moviepy.Effectr   moviepy.decoratorsr	   r
   r   r   r   r   r   r:   r   r   <module>r      s?        &   % P
, P
,r   