
    ^jX                       d Z ddlmZ ddlZddlmZ ddlmZmZm	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 e
j        d
         ZerddlmZ  G d d          Z G d d          Z G d de
j        j                  Ze                    d           e                    d           e                    d           e                    d           ddZ G d d          Z dS )"High-level sound and video player.    )annotationsN)deque)TYPE_CHECKINGIterable	Generator)GL_TEXTURE_2D)buffered_logger)get_audio_driver)SourceSourceGroupdebug_media)Texturec                  B    e Zd ZdZddZddZddZddZdd	ZddZ	dS )PlaybackTimerzvPlayback Timer.

    This is a simple timer object which tracks the time elapsed. It can be
    paused and reset.
    returnNonec                "    d| _         d | _        d S )N        )_elapsed_started_atselfs    N/home/agentuser/manim-venv/lib/python3.11/site-packages/pyglet/media/player.py__init__zPlaybackTimer.__init__   s        c                H    | j         t          j                    | _         dS dS )zStart the timer.N)r   timeperf_counterr   s    r   startzPlaybackTimer.start!   s*    ##022D $#r   c                F    |                                  | _        d| _        dS )zPause the timer.N)get_timer   r   r   s    r   pausezPlaybackTimer.pause&   s    r   c                V    d| _         | j        t          j                    | _        dS dS )zReset the timer to 0.r   N)r   r   r   r   r   s    r   resetzPlaybackTimer.reset+   s1    '#022D ('r   floatc                d    | j         | j        S t          j                    | j         z
  | j        z   S )zGet the elapsed time.)r   r   r   r   r   s    r   r"   zPlaybackTimer.get_time1   s1    #=  ""T%55EEr   valuec                <    |                                   || _        dS )zu
        Manually set the elapsed time.

        Args:
            value (float): the new elapsed time value
        N)r%   r   )r   r(   s     r   set_timezPlaybackTimer.set_time8   s     	

r   Nr   r   r   r&   )r(   r&   r   r   )
__name__
__module____qualname____doc__r   r    r#   r%   r"   r*    r   r   r   r      s                3 3 3 3
       
3 3 3 3F F F F     r   r   c                  (    e Zd ZdZddZddZd ZdS )_PlayerPropertya  Descriptor for Player attributes to forward to the AudioPlayer.

    We want the Player to have attributes like volume, pitch, etc. These are
    actually implemented by the AudioPlayer. So this descriptor will forward
    an assignment to one of the attributes to the AudioPlayer. For example
    `player.volume = 0.5` will call `player._audio_player.set_volume(0.5)`.

    The Player class has default values at the class level which are retrieved
    if not found on the instance.
    Nc                @    d|z   | _         d|z   | _        |pd| _        d S )N_set_ )private_namesetter_namer0   )r   	attributedocs      r   r   z_PlayerProperty.__init__O   s*    )O!I-ybr   c                t    || S | j         |j        v r|j        | j                  S t          || j                   S N)r8   __dict__getattr)r   objobjtypes      r   __get__z_PlayerProperty.__get__T   s?    ;K,,< 122w 1222r   c                |    ||j         | j        <   |j        r% t          |j        | j                  |           d S d S r=   )r>   r8   _audio_playerr?   r9   )r   r@   r(   s      r   __set__z_PlayerProperty.__set__[   sO    */T&' 	@8GC%t'788?????	@ 	@r   r=   )r-   r.   r/   r0   r   rB   rE   r1   r   r   r3   r3   C   sZ        	 	! ! ! !
3 3 3 3@ @ @ @ @r   r3   c                     e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZd@d	Zd@d
ZdAdZdBdZdCdZedDd            Zd@dZd@dZd@dZd@dZdEdZd@dZedFd            ZedGd            Zd@dZedHd!            Zd@d"ZdIdJd&ZdKd(Z  e!d)d*+          Z" e!d,d-+          Z# e!d.d/+          Z$ e!d0d1+          Z% e!d2d3+          Z& e!d4d5+          Z' e!d6d7+          Z( e!d8d9+          Z) e!d:d;+          Z*d< Z+d= Z,d> Z-d? Z.d#S )LPlayerr   g      ?g    חA)r   r   r   )r   r      g     v@r   r   c                    d| _         t                      | _        d| _        t          j        j        | _        d| _        d| _	        d| _
        t                      | _        d| _        dS )z)Initialize the Player with a MasterClock.NFr   )_sourcer   
_playlistsrD   pygletglcurrent_context_context_texture_playinglast_seek_timer   _timerloopr   s    r   r   zPlayer.__init__q   sX    ''!	1 !#oo 			r   c                .    |                                   dS )zRelease the Player resources.N)deleter   s    r   __del__zPlayer.__del__   s    r   sourceSource | Iterable[Source]c                   t          |t          t          f          rt          |          }nN	 t	          |          }n=# t
          $ r0 t          d                    t          |                              w xY w| j        	                    |           | j
        -|                     t          | j        d                              |                     | j                   dS )zQueue the source on this player.

        If the player has no source, the player will start to play immediately
        or pause depending on its :attr:`.playing` attribute.
        z@source must be either a Source or an iterable. Received type {0}Nr   )
isinstancer   r   _one_item_playlistiter	TypeErrorformattyperK   appendrX   _set_sourcenext_set_playingrQ   )r   rX   s     r   queuezPlayer.queue   s     fv{344 	K'//FFKf K K K !55;VDLL5I5IK K KK 	v&&&;T$/!"455666$-(((((s	   > :A8
new_sourceSource | Nonec                N    |	d | _         d S |                                | _         d S r=   )rJ   get_queue_source)r   rf   s     r   rb   zPlayer._set_source   s*    DLLL%6688DLLLr   playingboolc                     j          o|}| _          j        }|rZ|rW|j        C j        d u x}r                                   j        |s|r j                                         t          j        >t          j                                         t          j        	                    dd           |j
         j                                           j         j                                         |j
        %t          j                             j        d            j                                          j        1|j
        ,t          j                             fd|j                   d S d S d S  j         j                                         t          j                             j                    j                                         d S )Nzp.P._spr   r   c                .                         d          S Non_eos)dispatch_event)dtr   s    r   <lambda>z%Player._set_playing.<locals>.<lambda>   s    d6I6I(6S6S r   )rQ   rX   audio_formatrD   _create_audio_playerprefill_audioblloggerinit_wall_timelogvideo_formatrP   _create_textureplayrL   clockschedule_onceupdate_texturerS   r    durationstop
unscheduler#   )r   rj   startingrX   was_createds   `    r   rd   zPlayer._set_playing   s   }$0  	 v  	 ".#'#5#==K 0--///%1{1h1&44666y$	((***	i---".=(((***!-"'')))".**4+>BBB
 K!)f.A.I**+S+S+S+SU[Udeeeee *).I.I !-"'')))L##D$7888Kr   c                    | j         S )ac  The current playing state.

        The *playing* property is irrespective of whether or not there is
        actually a source to play. If *playing* is ``True`` and a source is
        queued, it will begin to play immediately. If *playing* is ``False``,
        it is implied that the player is paused. There is no other possible
        state.
        )rQ   r   s    r   rj   zPlayer.playing   s     }r   c                0    |                      d           dS )zhBegin playing the current source.

        This has no effect if the player is already playing.
        TNrd   r   s    r   r|   zPlayer.play   s    
 	$r   c                0    |                      d           dS )zkPause playback of the current source.

        This has no effect if the player is already paused.
        FNr   r   s    r   r#   zPlayer.pause   s    
 	%     r   c                    | j         rd| j        _        | j         | j                                         d| _        | j        	d| _        dS dS )z{Release the resources acquired by this player.

        The internal audio player and the texture will be deleted.
        FN)rJ   rX   is_player_sourcerD   rV   rP   r   s    r   rV   zPlayer.delete   sY    
 < 	1+0DK()%%'''!%D=$ DMMM %$r   c                   | j         }|                                  | j                                         d| _        | j        r!|                     d           d| j        _        | j	        }|sdS 	 t          |d                   }n># t          $ r1 |                                 |sd}nt          |d                   }Y nw xY w|2d| _        |                                  |                     d           dS | j        }|                     |           | j        U| j        j        |j        k    r | j                            | j                   n | j                                         d| _        | j        j        |j        k    r+d| _        t*          j                            | j                   ~|                     |           |                     d           dS )zMove immediately to the next source in the current playlist.

        If the playlist is empty, discard it and check if another playlist
        is queued. There may be a gap in playback while the audio buffer
        is refilled.
        r   FNr   on_player_eoson_player_next_source)rQ   r#   rS   r%   rR   rJ   seekrX   r   rK   rc   StopIterationpopleftrV   rp   rb   rD   rs   
set_sourcerz   rP   rL   r}   r   r   rd   )r   was_playing	playlistsrf   
old_sources        r   next_sourcezPlayer.next_source   s    m

!< 	1IIcNNN+0DK(O	 	F	0il++JJ 	0 	0 	0 0!

 ")A,//
	0 DLKKMMM00000 JZ(((!-<,
0GGG&11$,????&--///)-D&|(J,CCC $''(;<<<k*** 788888s   0B 8C C	timestampr&   c                ~   | j         }|r|                                  | j        dS t          j         t          j                            d|           t          |d          }| j        j        t          || j        j                  }| j
                            |           | j                            |           || _        | j        | j                                         | j        j        8|                                  t$          j                            | j                   |                     |           dS )zSeek for playback to the indicated timestamp on the current source.

        Timestamp is expressed in seconds. If the timestamp is outside the
        duration of the source, it will be clamped to the end.
        Nzp.P.skr   )rQ   r#   rX   rv   rw   ry   maxrJ   r   minrS   r*   r   rR   rD   clearrz   r   rL   r}   r   rd   )r   r   rj   s      r   r   zPlayer.seek/  s    - 	JJLLL;F9 IMM(I...	3''	< , It|'<==IY''')$$$') $$&&&;#/!!!L##D$7888'"""""r   c                    | j         rJ | j        sJ | j        }t                      }|d S |                    ||           | _         dD ]#}t	          | |          }t          | ||           $d S )N	volumemin_distancemax_distancepositionpitchcone_orientationcone_inner_anglecone_outer_anglecone_outer_gain)rD   rX   r   create_audio_playerr?   setattr)r   rX   audio_driverattrr(   s        r   rt   zPlayer._create_audio_playerR  s    %%%%{{'))F)==fdKK< 	' 	'D D$''ED$&&&&		' 	'r   c                    | j         S )z4Read-only. The current :class:`Source`, or ``None``.)rJ   r   s    r   rX   zPlayer.sourcee  s     |r   c                4    | j                                         S )a=  Read-only. Current playback time of the current source.

        The playback time is a float expressed in seconds, with 0.0 being the
        beginning of the media. The playback time returned represents the
        player master clock time which is used to synchronize both the audio
        and the video.
        )rS   r"   r   s    r   r   zPlayer.timej  s     {##%%%r   c                    | j         j        }t          j        j                            |j        |j        t                    | _	        | j	        
                    d          | _	        d| j	        _        | j	        S )NT)flip_yr   )rX   rz   rL   imager   createwidthheightr	   rP   get_transformanchor_y)r   rz   s     r   r{   zPlayer._create_textureu  s_    {/,33L4FH[]jkk3343@@ "#}r   Texture | Nonec                    | j         S )a  Get the texture for the current video frame, if any.

        You should query this property every time you display a frame of video,
        as multiple textures might be used. This property will be ``None`` if
        the current Source does not contain video.
        )rP   r   s    r   texturezPlayer.texture~  s     }r   c                j    | j                                         }|dS |                     |           dS )z4Step forwards one video frame in the current source.N)rX   get_next_video_timestampr   )r   r   s     r   seek_next_framezPlayer.seek_next_frame  s2    {3355<F		$r   Nrq   float | Nonec                   | j         }| j        }t          j        _t          j                            d||| j        r| j                                        ndt          j                                                   |j        j	        }d|z  }|
                                }|h||z   |k     r_|                                 t          j         t          j                            d|           |
                                }|	||z   |k     _t          j         t          j                            d|           |St          j         t          j                            d|           t          j                            | j        d           dS ||k    r*t          j                            | j        ||z
             dS |                                }|X| j        5  | j        |                                  | j                            |ddd           ddd           n# 1 swxY w Y   n+t          j        t          j                            d           |
                                }||}n||z
  }t+          d	|          }t          j        !t          j                            d
||           t          j                            | j        |           dS )zManually update the texture from the current source.

        This happens automatically, so you shouldn't need to call this method.

        Args:
            dt:
                The time elapsed since the last call to ``update_texture``.
        Nz
p.P.ut.1.0r   rH   z
p.P.ut.1.5z
p.P.ut.1.6z
p.P.ut.1.7z
p.P.ut.1.8r   z
p.P.ut.1.9)rX   r   rv   rw   ry   rD   r"   rebased_wall_timerz   
frame_rater   get_next_video_framerL   r}   r~   _video_finishedr   rO   rP   r{   	blit_intor   )	r   rq   rX   r   r   frame_durationtsr   delays	            r   r   zPlayer.update_texture  s    y9 IMMb$151CJ"++---	++--   (3
Z,,..nn!4t!;!;'')))y$	lB///0022B	 nn!4t!;!; 9 IMM,+++:y$	lN;;;L&&t';Q???F$YYL&&t':BIFFFF ++-- 8 8=(((***''q!Q7778 8 8 8 8 8 8 8 8 8 8 8 8 8 8 Y"IMM,''',,..:"EEIEC9 IMM,r222""4#6>>>>>s   9HH #H _dtc                B    | j         |                     d           d S d S rn   )rD   rp   )r   r   s     r   r   zPlayer._video_finished  s-    %))))) &%r   r   z
    The volume level of sound playback.

    The nominal level is 1.0, and 0.0 is silence.

    The volume level is affected by the distance from the listener (if
    positioned).
    )r;   r   a  
    The distance beyond which the sound volume drops by half, and within
    which no attenuation is applied.

    The minimum distance controls how quickly a sound is attenuated as it
    moves away from the listener. The gain is clamped at the nominal value
    within the min distance. By default the value is 1.0.

    The unit defaults to meters, but can be modified with the listener
    properties. r   a[  
    The distance at which no further attenuation is applied.

    When the distance from the listener to the player is greater than this
    value, attenuation is calculated as if the distance were value. By
    default the maximum distance is infinity.

    The unit defaults to meters, but can be modified with the listener
    properties.
    r   z
    The position of the sound in 3D space.

    The position is given as a tuple of floats (x, y, z). The unit
    defaults to meters, but can be modified with the listener properties.
    r   a  
    The pitch shift to apply to the sound.

    The nominal pitch is 1.0. A pitch of 2.0 will sound one octave higher,
    and play twice as fast. A pitch of 0.5 will sound one octave lower, and
    play twice as slow. A pitch of 0.0 is not permitted.
    r   a  
    The direction of the sound in 3D space.

    The direction is specified as a tuple of floats (x, y, z), and has no
    unit. The default direction is (0, 0, -1). Directional effects are only
    noticeable if the other cone properties are changed from their default
    values.
    r   z
    The interior angle of the inner cone.

    The angle is given in degrees, and defaults to 360. When the listener
    is positioned within the volume defined by the inner cone, the sound is
    played at normal gain (see :attr:`volume`).
    r   aR  
    The interior angle of the outer cone.

    The angle is given in degrees, and defaults to 360. When the listener
    is positioned within the volume defined by the outer cone, but outside
    the volume defined by the inner cone, the gain applied is a smooth
    interpolation between :attr:`volume` and :attr:`cone_outer_gain`.
    r   z
    The gain applied outside the cone.

    When the listener is positioned outside the volume defined by the outer
    cone, this gain is applied instead of :attr:`volume`.
    c                6    t           rt          d           dS dS )z5The player ran out of sources. The playlist is empty.zPlayer.on_player_eosN)_debugprintr   s    r   r   zPlayer.on_player_eos#  s)     	*()))))	* 	*r   c                   t           rt          d           t          j        =t          j                            d           t          j                                         | j        rg| j        }|                                  | j	        
                                 | j        |                     d           |                     |           dS |                                  dS )au  The current source ran out of data.

        The default behaviour is to advance to the next source in the
        playlist if the :attr:`.loop` attribute is set to ``False``.
        If :attr:`.loop` attribute is set to ``True``, the current source
        will start to play again until :meth:`next_source` is called or
        :attr:`.loop` is set to ``False``.
        zPlayer.on_eosNzp.P.oer   )r   r   rv   rw   ry   closerT   rQ   r#   rS   r%   rX   r   rd   r   )r   r   s     r   ro   zPlayer.on_eos(  s      	#/"""9 IMM(###IOO9 	-KJJLLLK{&		#k***** r   c                    dS )zThe player starts to play the next queued source in the playlist.

        This is a useful event for adjusting the window size to the new
        source :class:`VideoFormat` for example.
        Nr1   r   s    r   r   zPlayer.on_player_next_sourceD  s      r   c                    | j         dS | j                                          dD ]#}t          | |          }t          | ||           $| j        r| j                                          dS dS )aX  The audio driver has been reset.

        By default this will kill the current audio player, create a new one,
        and requeue the buffers. Any buffers that may have been queued in a
        player will be resubmitted. It will continue from the last buffers
        submitted, not played, and may cause sync issues if using video.
        Nr   )rD   on_driver_resetr?   r   rQ   r|   )r   r   r(   s      r   r   zPlayer.on_driver_resetK  s     %F**,,,d 	' 	'DD$''ED$&&&&= 	&##%%%%%	& 	&r   r+   )rX   rY   r   r   )rf   rg   r   r   )rj   rk   r   r   )r   rk   )r   r&   r   r   )r   rg   r,   )r   r   r=   )rq   r   r   r   )r   r&   r   r   )/r-   r.   r/   r0   _volume_min_distance_max_distance	_position_pitch_cone_orientation_cone_inner_angle_cone_outer_angle_cone_outer_gainr   rW   re   rb   rd   propertyrj   r|   r#   rV   r   r   rt   rX   r   r{   r   r   r   r   r3   r   r   r   r   r   r   r   r   r   r   ro   r   r   r1   r   r   rG   rG   a   sd       ,, GMMIF!   .   ) ) ) )*9 9 9 9'  '  '  ' R 	 	 	 X	       ! ! ! !! ! ! !69 69 69 69p!# !# !# !#F' ' ' '&    X & & & X&       X   D? D? D? D? D?N* * * * _X , 	 	 	F #?> 	8 	 	 	L #?> 	8 		 		 		L z 0 	 	 	H OG * 	 	 	E ''9 @ 	 	 	 ''9 @ 	 	 	 ''9 @ 	 	 	 &o&7 > 	 	 	O* * *
  8  & & & & &r   rG   ro   r   r   r   rX   r   r   r   c              #     K   | V  d S r=   r1   )rX   s    r   r\   r\   h  s      
LLLLLr   c                  *    e Zd ZdZd
dZddZddZd	S )PlayerGroupzGroup of players that can be played and paused simultaneously.

    Create a player group for the given list of players.

    All players in the group must currently not belong to any other group.
    playersIterable[Player]r   r   c                .    t          |          | _        dS )z,Initialize the PlayerGroup with the players.N)listr   )r   r   s     r   r   zPlayerGroup.__init__t  s    G}}r   c                    d | j         D             }|r|d                             |           | j         D ]}|                                 dS )z6Begin playing all players in the group simultaneously.c                *    g | ]}|j         	|j         S r1   rD   .0ps     r   
<listcomp>z$PlayerGroup.play.<locals>.<listcomp>z  7     C C C!/C C C Cr   r   N)r   _play_groupr|   r   audio_playersplayers      r   r|   zPlayerGroup.playx  sr    C C"&,C C C 	8!((777l 	 	FKKMMMM	 	r   c                    d | j         D             }|r|d                             |           | j         D ]}|                                 dS )z.Pause all players in the group simultaneously.c                *    g | ]}|j         	|j         S r1   r   r   s     r   r   z%PlayerGroup.pause.<locals>.<listcomp>  r   r   r   N)r   _stop_groupr#   r   s      r   r#   zPlayerGroup.pause  sr    C C"&,C C C 	8!((777l 	 	FLLNNNN	 	r   N)r   r   r   r   r+   )r-   r.   r/   r0   r   r|   r#   r1   r   r   r   r   l  sZ         % % % %        r   r   )rX   r   r   r   )!r0   
__future__r   r   collectionsr   typingr   r   r   rL   	pyglet.glr	   pyglet.mediar
   rv   pyglet.media.driversr   pyglet.media.codecs.baser   r   optionsr   pyglet.imager   r   r3   eventEventDispatcherrG   register_event_typer\   r   r1   r   r   <module>r      s   ( ( " " " " " "        5 5 5 5 5 5 5 5 5 5  # # # # # # . . . . . . 1 1 1 1 1 1 8 8 8 8 8 8 8 8		& %$$$$$$* * * * * * * *Z@ @ @ @ @ @ @ @<~& ~& ~& ~& ~&V\) ~& ~& ~&B   8 $ $ $   ? + + +   2 3 3 3   , - - -            r   