o
    i7                  
   @   s2  d Z ddlZddlZddlmZ ddlmZ ddlZddl	m
Z
 ddlmZ ddlmZmZmZmZmZmZmZmZmZ ddlmZ dd	lmZ dd
lmZ zddlmZ ddlm Z  ddl!m"Z"m#Z# W n  e$y Z% ze
&de%  e
&d e'de% dZ%[%ww eG dd deZ(G dd deZ)dS )z4Simli video service for real-time avatar generation.    N)	dataclass)Optional)logger)	BaseModel)	CancelFrameEndFrameFrameInterruptionFrameOutputImageRawFrame
StartFrameTTSAudioRawFrameTTSStoppedFrameUserStartedSpeakingFrame)FrameDirection)	AIService)ServiceSettings)
AudioFrame)AudioResampler)SimliClientSimliConfigzException: zCIn order to use Simli, you need to `pip install pipecat-ai[simli]`.zMissing module: c                   @   s   e Zd ZdZdS )SimliVideoSettingsz%Settings for the Simli video service.N)__name__
__module____qualname____doc__ r   r   P/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/services/simli/video.pyr   +   s    r   c                       s  e Zd ZU dZeZeed< G dd deZddddddddddddd	e	e
 d
e	e
 de	e dede
dede	e de	e de	e de	e de	e f fddZdef fddZdef fddZdef fddZdd Zdd  Zd!d" Zded#ef fd$d%Zd&d' Z  ZS )(SimliVideoServicea  Simli video service for real-time avatar generation.

    Provides real-time avatar video generation by processing audio frames
    and producing synchronized video output using the Simli API. Handles
    audio resampling, video frame processing, and connection management.
    	_settingsc                   @   sB   e Zd ZU dZdZee ed< dZee	 ed< dZ
ee	 ed< dS )zSimliVideoService.InputParamsa  Input parameters for Simli video configuration.

        .. deprecated:: 0.0.106
            Use ``SimliVideoService.Settings(...)`` instead.

        Parameters:
            enable_logging: Whether to enable Simli logging.
            max_session_length: Absolute maximum session duration in seconds.
                Avatar will disconnect after this time even if it's speaking.
            max_idle_time: Maximum duration in seconds the avatar is not speaking
                before the avatar disconnects.
        Nenable_loggingmax_session_lengthmax_idle_time)r   r   r   r   r   r   bool__annotations__r    intr!   r   r   r   r   InputParams=   s
   
 r%   NFzhttps://api.simli.ai)api_keyface_idsimli_configuse_turn_server	simli_urlis_trinity_avatarparamsr    r!   r   settingsr&   r'   r(   r)   r*   r+   r,   r    r!   r   r-   c                   s  t dd}|dur2| d |du rt|dr|j}|	du r&t|dr&|j}	|
du r2t|dr2|j}
|dur;|| t jdd|i| |dura|dusR|durVt	dt
jd	td
d |}n+|du rit	d|du rqt	dd|i}|dur}||d< |	dur|	|d< tdi |}|rt
jdtd
d d| _| jd7  _| jd7  _t|||dd| _d| _t | _tddd| _d| _d| _|| _|| _t | _dS )a  Initialize the Simli video service.

        Args:
            api_key: Simli API key for authentication.
            face_id: Simli Face ID. For Trinity avatars, specify "faceId/emotionId"
                to use a different emotion than the default.
            simli_config: Configuration object for Simli client settings.
                Use api_key and face_id instead.

                .. deprecated:: 0.0.92
                    The 'simli_config' parameter is deprecated and will be removed in a future version.
                    Please use 'api_key' and 'face_id' parameters instead.

            use_turn_server: Whether to use TURN server for connection. Defaults to False.

                .. deprecated:: 0.0.95
                    The 'use_turn_server' parameter is deprecated and will be removed in a future version.

            simli_url: URL of the simli servers. Can be changed for custom deployments
                of enterprise users.
            is_trinity_avatar: Boolean to tell simli client that this is a Trinity avatar
                which reduces latency when using Trinity.
            params: Additional input parameters for session configuration.

                .. deprecated:: 0.0.106
                    Use ``settings=SimliVideoService.Settings(...)`` instead.

            max_session_length: Absolute maximum session duration in seconds.
                Avatar will disconnect after this time even if it's speaking.
            max_idle_time: Maximum duration in seconds the avatar is not speaking
                before the avatar disconnects.
            enable_logging: Whether to enable Simli logging.
            settings: Service settings.
            **kwargs: Additional arguments passed to the parent AIService.
        N)modelr,   r    r!   r   r-   zrCannot specify both simli_config and api_key/face_id. Please use api_key and face_id (simli_config is deprecated).zThe 'simli_config' parameter is deprecated and will be removed in a future version. Please use 'api_key' and 'face_id' parameters instead, with optional 'params' for max_session_length and max_idle_time configuration.   )
stacklevelzapi_key is requiredzface_id is requiredfaceIdmaxSessionLengthmaxIdleTimezVThe 'use_turn_server' parameter is deprecated and will be removed in a future version.F   T)r&   configsimliURL	enableSFUs16monoi>  r   )r   "_warn_init_param_moved_to_settingshasattrr    r!   r   apply_updatesuper__init__
ValueErrorwarningswarnDeprecationWarningr   _initializedr3   r2   r   _simli_client_pipecat_resamplerasyncioEvent_pipecat_resampler_eventr   _simli_resampler_audio_task_video_task_is_trinity_avatar_previously_interrupted	bytearray_audio_buffer)selfr&   r'   r(   r)   r*   r+   r,   r    r!   r   r-   kwargsdefault_settingsr5   config_kwargs	__class__r   r   r>   O   sr   
4

	
zSimliVideoService.__init__framec                    &   t  |I dH  |  I dH  dS )zStart the Simli video service.

        Args:
            frame: The start frame containing initialization parameters.
        N)r=   start_start_connectionrP   rV   rT   r   r   rX         zSimliVideoService.startc                    rW   )zWStop the Simli video service.

        Args:
            frame: The end frame.
        N)r=   stop_stop_connectionrZ   rT   r   r   r\      r[   zSimliVideoService.stopc                    rW   )z\Cancel the Simli video service.

        Args:
            frame: The cancel frame.
        N)r=   cancelr]   rZ   rT   r   r   r^      r[   zSimliVideoService.cancelc              
      s   z)| j s| j I dH  d| _ | j I dH  | |  | _| |  | _W dS  t	yJ } z| j
d| |dI dH  W Y d}~dS d}~ww )zAStart the connection to Simli service and begin processing tasks.NTzUnable to start connection: 	error_msg	exception)rC   rD   rX   sendSilencecreate_task_consume_and_process_audiorJ   _consume_and_process_videorK   	Exception
push_error)rP   er   r   r   rY      s   (z#SimliVideoService._start_connectionc              	      s|   | j  I dH  | j }|2 z*3 dH W }| j|}|D ]}| }| r9| t	|
 | jjddI dH  qq6 dS )z9Consume audio frames from Simli and push them downstream.N   )audiosample_ratenum_channels)rH   waitrD   getAudioStreamIteratorrE   resample
to_ndarrayany
push_framer   tobytesrate)rP   audio_iteratoraudio_frameresampled_framesresampled_frameaudio_arrayr   r   r   rd      s$   

z,SimliVideoService._consume_and_process_audioc                    sr   | j  I dH  | jjdd}|2 z#3 dH W }t|   |j|j	fdd}|j
|_
| |I dH  q6 dS )zBConsume video frames from Simli and convert them to output frames.Nrgb24)targetFormatRGB)imagesizeformat)rH   rm   rD   getVideoStreamIteratorr
   to_rgbto_imagers   widthheightptsrr   )rP   video_iteratorvideo_frameconvertedFramer   r   r   re     s   
z,SimliVideoService._consume_and_process_video	directionc           	   
      s  t  ||I dH  t|trztjtj|jtj	ddddf |j
dkr(dndd}|j|_| jdu rCtd|j|j| _| j  | j|}|D ]c}| tj	 }| jr| j| t| jdkrz*| jdD ]}| j| tj	  qnW | j| jI dH  d	| _t | _qK| j| jI dH  d	| _t | _w qK| j|I dH  qKW dS  ty } z| jd
| |dI dH  W Y d}~nid}~ww t|t rz$| jrt| jdkr| j| jI dH  d	| _t | _W dS W dS W dS  ty } z| jd| |dI dH  W Y d}~dS d}~ww t|t!t"fr5| js1| j# I dH  | j$| _| %||I dH  dS )zProcess incoming frames and handle Simli video generation.

        Args:
            frame: The frame to process.
            direction: The direction of frame processing.
        N)dtyperi   r9   stereo)layoutr8   i  FzError sending audio: r_   r   zError stopping TTS: )&r=   process_frame
isinstancer   r   from_ndarraynp
frombufferrj   int16rl   rk   rE   r   r   rH   setrI   ro   rp   astypers   rM   rO   extendlenrD   playImmediaterN   sendrf   rg   r   r	   r   clearBufferrL   rr   )	rP   rV   r   	old_framerw   rx   
audioBytes
flushFramerh   rT   r   r   r      sx   





&
$zSimliVideoService.process_framec                    sV   | j  I dH  | jr| | jI dH  d| _| jr)| | jI dH  d| _dS dS )z2Stop the Simli client and cancel processing tasks.N)rD   r\   rJ   cancel_taskrK   )rP   r   r   r   r]   [  s   
z"SimliVideoService._stop_connection)r   r   r   r   r   Settingsr#   r   r%   r   strr   r"   r$   r>   r   rX   r   r\   r   r^   rY   rd   re   r   r   r   r]   __classcell__r   r   rT   r   r   2   s`   
 	
 				;r   )*r   rF   r@   dataclassesr   typingr   numpyr   logurur   pydanticr   pipecat.frames.framesr   r   r   r	   r
   r   r   r   r   "pipecat.processors.frame_processorr   pipecat.services.ai_servicer   pipecat.services.settingsr   av.audio.framer   av.audio.resamplerr   simlir   r   ModuleNotFoundErrorrh   errorrf   r   r   r   r   r   r   <module>   s2   ,
