
    W|h%                     N   S r SSKrSSKrSSKrSSKrSSKr\R                  rS r	S"S jr
S rS rS rS/ S	QS
.S/ S	QS
.SS/S
.SS/S
.SS0SSS/S
.SS/S
.SS/S
.S/ SQS
.SS/S
.SS/S
.S.rS H
  rSS0\\'   M     S rS#S jrS\4S jr S$S\S\S\S \S\\\4   4
S! jjrg)%zFMisc. useful functions that can be used at many places in the program.    Nc                 $    [         S:X  a  SU S'   U $ )aD  Wrap with this function a dictionary of ``subprocess.Popen`` kwargs and
will be ready to work without unexpected behaviours in any platform.
Currently, the implementation will add to them:

- ``creationflags=0x08000000``: no extra unwanted window opens on Windows
  when the child process is created. Only added on Windows.
nti   creationflags)OS_NAME)popen_paramss    G/home/james-whalen/.local/lib/python3.13/site-packages/moviepy/tools.pycross_platform_popen_paramsr	      s     $(2_%    c                    [         R                  " U5      nU" SSR                  U 5      -   S9  [        [        R
                  [        R                  [        R
                  S.5      n[        R                  " U 40 UD6nUR                  5       u  pEUR                  R                  5         UR                  (       a   U" SS9  [        UR                  S5      5      eU" SS9  Ag)	zjExecutes the given subprocess command.

Set logger to None or a custom Proglog logger to avoid printings.
zMoviePy - Running:
>>>  )message)stdoutstderrstdinz#MoviePy - Command returned an errorutf8zMoviePy - Command successfulN)proglogdefault_bar_loggerjoinr	   spDEVNULLPIPEPopencommunicater   close
returncodeIOErrordecode)cmdloggerr   procouterrs         r   subprocess_callr#      s    
 ''/F
-=>.::2::FL 88C(<(D!HCKK<=cjj())56r
   c                 <    U R                  S5      (       a  SU -   n U $ )zEscape a filename that we want to pass to the ffmpeg command line

That will ensure the filename doesn't start with a '-' (which would raise an error)
-z./)
startswith)filenames    r   ffmpeg_escape_filenamer(   5   s#    
 3(?Or
   c           	      2   Sn[        U [        5      (       a:  U R                  S5       Vs/ s H  n[        UR	                  SS5      5      PM      n n[        U [
        [        45      (       d  U $ [        S [        U[        U 5      5       5       5      $ s  snf )a0  Will convert any time into seconds.

If the type of `time` is not valid,
it's returned as is.

Here are the accepted formats:

.. code:: python

    convert_to_seconds(15.4)   # seconds
    15.4
    convert_to_seconds((1, 21.5))   # (min,sec)
    81.5
    convert_to_seconds((1, 1, 2))   # (hr, min, sec)
    3662
    convert_to_seconds('01:01:33.045')
    3693.045
    convert_to_seconds('01:01:33,5')    # coma works too
    3693.5
    convert_to_seconds('1:33,5')    # only minutes and secs
    99.5
    convert_to_seconds('33.5')      # only secs
    33.5
)   <   i  :,.c              3   .   #    U  H  u  pX-  v   M     g 7fN ).0multparts      r   	<genexpr>%convert_to_seconds.<locals>.<genexpr>a   s     J-Iztt{-Is   )

isinstancestrsplitfloatreplacetuplelistsumzipreversed)timefactorsr4   s      r   convert_to_secondsrC   @   sz    2 G$:>**S/J/$dll3,-/JdUDM**JS(4.-IJJJ Ks   %Bc                 T   ^ ^ T R                   nSU< SU< S3mU U4S jnTUl        U$ )aj  Indicates that a function is deprecated and has a new name.

`func` is the new function and `old_name` is the name of the deprecated
function.

Returns
-------

deprecated_func
  A function that does the same thing as `func`, but with a docstring
  and a printed message on call which say that the function is
  deprecated and that you should use `func` instead.

Examples
--------

.. code:: python

    # The badly named method 'to_file' is replaced by 'write_file'
    class Clip:
        def write_file(self, some args):
            # blablabla
    Clip.to_file = deprecated_version_of(Clip.write_file, 'to_file')
zThe function ``za`` is deprecated and is kept temporarily for backwards compatibility.
Please use the new name, ``z``, instead.c                  P   > [         R                  " ST-   [        5        T" U 0 UD6$ )Nz	MoviePy: )warningswarnPendingDeprecationWarning)argskwargsfuncwarnings     r   deprecated_func.deprecated_version_of.<locals>.deprecated_func   s'    kG+-FGT$V$$r
   )__name____doc__)rK   old_namenew_namerM   rL   s   `   @r   deprecated_version_ofrS   d   s1    4 }}H 
8	G% &Or
   video)libx264libmpeg4aac)typecodec	libtheoralibvpxrX   rU   proresaudio	libvorbis
libmp3lame)	pcm_s16le	pcm_s24le	pcm_s32le
libfdk_aacflac)mp4mkvogvwebmavimovoggmp3wavm4ard   )jpgjpegpngbmptiffimagec                     U [         ;   a  U $ [         R                  5        H  u  pXR                  S/ 5      ;   d  M  Us  $    [        S5      e)zwReturns the correspondent file extension for a codec.

Parameters
----------

codec : str
  Video or audio codec name.
rY   zThe audio_codec you chose is unknown by MoviePy. You should report this. In the meantime, you can specify a temp_audiofile with the right extension in write_videofile.)extensions_dictitemsget
ValueError)rY   extinfoss      r   find_extensionr|      sP     %++-
IIgr**J . 	 r
   c                   ^ SSK Jn  SSKJn  SSKJn  UUUS.mU S:X  a
  [        5       n [        U S5      (       a  U R                  5       n [        U4S jU 5       5      nU  H%  n[        Xe5      (       d  M  UR                  5         M'     g	)
a  Closes all clips in a context.

Follows different strategies retrieving the namespace from which the clips
to close will be retrieved depending on the ``objects`` argument, and filtering
by type of clips depending on the ``types`` argument.

Parameters
----------

objects : str or dict, optional
  - If is a string an the value is ``"globals"``, will close all the clips
    contained by the ``globals()`` namespace.
  - If is a dictionary, the values of the dictionary could be clips to close,
    useful if you want to use ``locals()``.

types : Iterable, optional
  Set of types of clips to close, being "audio", "video" or "image" the supported
  values.
r   )AudioFileClip)VideoFileClip)	ImageClipr]   rT   rt   globalsvaluesc              3   .   >#    U  H
  nTU   v   M     g 7fr0   r1   )r2   key
CLIP_TYPESs     r   r5   "close_all_clips.<locals>.<genexpr>   s     95C
35s   N)moviepy.audio.io.AudioFileClipr~   moviepy.video.io.VideoFileClipr   moviepy.video.VideoClipr   r   hasattrr   r<   r7   r   )objectstypesr~   r   r   types_tupleobjr   s          @r   close_all_clipsr      sx    ( =<1 J ))w!!.."9599Kc''IIK r
   returnc                      [         R                  " 5       n U S;   a)  S[        R                  ;  a  S[        R                  ;  a  gSU ;   a)  S[        R                  ;  a  S[        R                  ;  a  gg)a  Return True if we determine the host system has no graphical environment.
This is usefull to remove tests requiring display, like preview

..info::
    Currently this only works for Linux/BSD systems with X11 or wayland.
    It probably works for SunOS, AIX and CYGWIN
)LinuxFreeBSDNetBSDOpenBSDSunOSAIXDISPLAYWAYLAND_DISPLAYT	CYGWIN_NTF)platformsystemosenviron)r   s    r   no_display_availabler      sZ     __FJJRZZ'.?rzz.QfRZZ'.?rzz.Qr
   
clip1_size
clip2_sizeposrelativec                    Uc  Sn[        U[        5      (       a  SS/SS/SS/SS/SS/S.U   nO[        U5      nU(       a6  [        U5       H'  u  pE[        X$   [        5      (       a  M  XRU   -  X$'   M)     [        US   [        5      (       a%  SUS   U S   -
  S	-  US   U S   -
  S
.nXbS      US'   [        US   [        5      (       a%  SUS   U S   -
  S	-  US   U S   -
  S.nXbS      US'   [	        US   5      [	        US   5      4$ )a  Return the position to put clip 1 on clip 2 based on both clip size
and the position of clip 1, as return by clip1.pos() method

Parameters
----------
clip1_size : tuple
    The width and height of clip1 (e.g., (width, height)).
clip2_size : tuple
    The width and height of clip2 (e.g., (width, height)).
pos : Any
    The position of clip1 as returned by the `clip1.pos()` method.
relative: bool
    Is the position relative (% of clip size), default False.

Returns
-------
tuple[int, int]
    A tuple (x, y) representing the top-left corner of clip1 relative to clip2.

Notes
-----
For more information on `pos`, see the documentation for `VideoClip.with_position`.
)r   r   centerleftrighttopbottom)r   r   r   r   r   r      )r   r   r   r*   )r   r   r   )r7   r8   r=   	enumerateint)r   r   r   r   idimDs          r   compute_positionr      sT   4 { #s*X&x(e$*
  3i 
+FAcfc**1v , #a&#!!}z!}49]Z]2

 q6A#a&#!!}z!}49 mjm3

 q6A AKSV%%r
   )bar)r   r   )F)rP   r   r   
subprocessr   rF   r   namer   r	   r#   r(   rC   rS   rv   rz   r|   r   boolr   r<   anyr   r   r1   r
   r   <module>r      s'   L 	     ''
4!KH(b &DE&DE{m4z2Gy(&;<{m4|n5&MN|n5x0 1C"G,OC 10%Pd * FK@&@&#(@&/2@&>B@&
38_@&r
   