
    qi                     D   d Z ddlZddlZddlZddlmZ ddlmZmZ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mZmZmZmZ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& ddl'm(Z(m)Z) ddl*m+Z+ 	 ddl,Z,ddl-m.Z. ddl/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5 dZ:dZ;dZ< G d de      Z= G d de0      Z> G d de.      Z? G d d      Z@ G d de$      ZA G d  d!e&      ZB G d" d#e(      ZCy# e6$ r7Z7 ejp                  de7         ejp                  d        e9de7       dZ7[7ww xY w)$a	  Small WebRTC transport implementation for Pipecat.

This module provides a WebRTC transport implementation using aiortc for
real-time audio and video communication. It supports bidirectional media
streaming, application messaging, and client connection management.
    N)deque)Any	AwaitableCallableListOptional)logger)	BaseModel)CancelFrameClientConnectedFrameEndFrameFrameInputAudioRawFrameInputTransportMessageFrameOutputAudioRawFrameOutputImageRawFrameOutputTransportMessageFrame!OutputTransportMessageUrgentFrameSpriteFrame
StartFrameUserImageRawFrameUserImageRequestFrame)FrameDirection)BaseInputTransport)BaseOutputTransport)BaseTransportTransportParams)SmallWebRTCConnection)VideoStreamTrack)AudioStreamTrackMediaStreamError)
AudioFrameAudioResampler
VideoFramezException: zNIn order to use the SmallWebRTC, you need to `pip install pipecat-ai[webrtc]`.zMissing module: camerascreenVideo
microphonec                   h    e Zd ZU dZeeeged   f   ed<   ee	ged   f   ed<   ee	ged   f   ed<   y)SmallWebRTCCallbacksa  Callback handlers for SmallWebRTC events.

    Parameters:
        on_app_message: Called when an application message is received.
        on_client_connected: Called when a client establishes connection.
        on_client_disconnected: Called when a client disconnects.
    Non_app_messageon_client_connectedon_client_disconnected)
__name__
__module____qualname____doc__r   r   strr   __annotations__r        Z/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/transports/smallwebrtc/transport.pyr)   r)   =   sQ     c3Z4899!#8"99T?"JKK$&;%<io%MNNr4   r)   c                   4     e Zd ZdZ fdZdefdZd Z xZS )RawAudioTrackzCustom audio stream track for WebRTC output.

    Handles audio frame generation and timing for WebRTC transmission,
    supporting queued audio data with proper synchronization.
    c                     t         |           || _        |dz  dz  | _        | j                  dz  | _        d| _        t        j                         | _        t               | _	        y)zmInitialize the raw audio track.

        Args:
            sample_rate: The audio sample rate in Hz.
        
   i     r   N)
super__init___sample_rate_samples_per_10ms_bytes_per_10ms
_timestamptime_startr   _chunk_queue)selfsample_rate	__class__s     r5   r<   zRawAudioTrack.__init__R   s[     	'!,r!1T!9#559iik!Gr4   audio_bytesc                 |   t        |      | j                  z  dk7  rt        d      t        j                         j                         }t        dt        |      | j                        D ]P  }|||| j                  z    }|| j                  z   t        |      k\  r|nd}| j                  j                  ||f       R |S )a5  Add audio bytes to the buffer for transmission.

        Args:
            audio_bytes: Raw audio data to queue for transmission.

        Returns:
            A Future that completes when the data is processed.

        Raises:
            ValueError: If audio bytes are not a multiple of 10ms size.
        r   z,Audio bytes must be a multiple of 10ms size.N)	lenr?   
ValueErrorasyncioget_running_loopcreate_futurerangerC   append)rD   rG   futureichunkfuts         r5   add_audio_byteszRawAudioTrack.add_audio_bytesa   s     {d222a7KLL))+99; q#k*D,@,@A 	3AA(<(<$<=E 4 44K8HH&dC$$eS\2		3 r4   c                   K   | j                   dkD  r]| j                  | j                   | j                  z  z   t        j                         z
  }|dkD  rt	        j
                  |       d{    | j                  rA| j                  j                         \  }}|r7|j                         s'|j                  d       nt        | j                        }t        j                  |t        j                        }t        j                   |dddf   d      }| j                  |_        | j                   |_        t'        j(                  d| j                        |_        | xj                   | j,                  z  c_         |S 7 w)zReturn the next audio frame for WebRTC transmission.

        Returns:
            An AudioFrame containing the next audio data or silence.
        r   NTdtypemono)layout   )r@   rB   r=   rA   rK   sleeprC   popleftdone
set_resultbytesr?   np
frombufferint16r"   from_ndarrayrE   pts	fractionsFraction	time_baser>   )rD   waitrR   rP   samplesframes         r5   recvzRawAudioTrack.recvz   s#     ??Q;;$//D4E4E"EFTDaxmmD))) --557ME6fkkm!!$'$../E --RXX6 ''a(8H --OO	#,,Q0A0AB4111% *s   A(E?*E<+DE?)	r-   r.   r/   r0   r<   r_   rT   rk   __classcell__rF   s   @r5   r7   r7   K   s    $5 2r4   r7   c                   .     e Zd ZdZ fdZd Zd Z xZS )RawVideoTrackzzCustom video stream track for WebRTC output.

    Handles video frame queuing and conversion for WebRTC transmission.
    c                 p    t         |           || _        || _        t	        j
                         | _        y)zInitialize the raw video track.

        Args:
            width: Video frame width in pixels.
            height: Video frame height in pixels.
        N)r;   r<   _width_heightrK   Queue_video_buffer)rD   widthheightrF   s      r5   r<   zRawVideoTrack.__init__   s,     	$]]_r4   c                 :    | j                   j                  |       y)zAdd a video frame to the transmission buffer.

        Args:
            frame: The video frame to queue for transmission.
        N)rt   
put_nowaitrD   rj   s     r5   add_video_framezRawVideoTrack.add_video_frame   s     	%%e,r4   c                 |  K   | j                   j                          d{   }t        j                  |j                  t        j
                        j                  | j                  | j                  df      }t        j                  |d      }| j                          d{   \  |_        |_        |S 7 7 w)zReturn the next video frame for WebRTC transmission.

        Returns:
            A VideoFrame ready for WebRTC transmission.
        NrV      rgb24format)rt   getr`   ra   imageuint8reshaperr   rq   r$   rc   next_timestamprd   rg   )rD   	raw_frame
frame_datarj   s       r5   rk   zRawVideoTrack.recv   s      ,,0022	 ]]9??"((CKK\\4;;*

 ''
7C ,0+>+>+@%@"	5? 3 &As"   B<B8BB<$B:%B<:B<)r-   r.   r/   r0   r<   rz   rk   rl   rm   s   @r5   ro   ro      s    

--r4   ro   c                   j   e Zd ZdZej
                  ej
                  ej                  ej                  dZde	de
fdZdej                  dedej                  fd	Zd
efdZd ZdedefdZdedefdZdefdZd Zd Zdeez  fdZd Zd Zd Z de!defdZ"d Z#e$defd       Z%e$defd       Z&y)SmallWebRTCClientzWebRTC client implementation for handling connections and media streams.

    Manages WebRTC peer connections, audio/video streaming, and application
    messaging through the SmallWebRTCConnection interface.
    )yuv420pyuvj420pnv12graywebrtc_connection	callbacksc                 &    | _         d _        | _        d _        d _        d _        d _        d _        d _        d _	        d _
        d _        d _        d _         j                   j                  d      dt        f fd       } j                   j                  d      dt        f fd       } j                   j                  d	      dt        f fd
       } j                   j                  d      dt        dt         f fd       }y)zInitialize the WebRTC client.

        Args:
            webrtc_connection: The underlying WebRTC connection handler.
            callbacks: Event callbacks for connection and message handling.
        FNr   	connected
connectionc                 l   K   t        j                  d       j                          d {    y 7 w)NzPeer connection established.)r	   debug_handle_client_connectedr   rD   s    r5   on_connectedz0SmallWebRTCClient.__init__.<locals>.on_connected   s&     LL78//111   )424disconnectedc                 l   K   t        j                  d       j                          d {    y 7 w)NzPeer connection lost.)r	   r   _handle_peer_disconnectedr   s    r5   on_disconnectedz3SmallWebRTCClient.__init__.<locals>.on_disconnected   s&     LL0100222r   closedc                 l   K   t        j                  d       j                          d {    y 7 w)NzClient connection closed.)r	   r   _handle_client_closedr   s    r5   	on_closedz-SmallWebRTCClient.__init__.<locals>.on_closed   s&     LL45,,...r   zapp-messagemessagec                 Z   K   j                  || j                         d {    y 7 w)N)_handle_app_messagepc_id)r   r   rD   s     r5   r*   z2SmallWebRTCClient.__init__.<locals>.on_app_message   s#     **7J4D4DEEEs    +)+)_webrtc_connection_closing
_callbacks_audio_output_track_video_output_track_audio_input_track_video_input_track_screen_video_track_params_audio_in_channels_in_sample_rate_out_sample_rate_leave_counter_audio_in_resamplerevent_handlerr   r   )rD   r   r   r   r   r   r*   s   `      r5   r<   zSmallWebRTCClient.__init__   s1    #4##' #' >B>B?C "&# $ $( 		 	 	.	.{	;	2+@ 	2 
<	2 
	 	 	.	.~	>	3.C 	3 
?	3 
	 	 	.	.x	8	/(= 	/ 
9	/ 
	 	 	.	.}	=	F-B 	FS 	F 
>	Fr4   frame_arrayformat_namereturnc                     |j                  d      r|S t        j                  j                  |      }|t	        d|       t        j                  ||      S )aX  Convert a video frame to RGB format based on the input format.

        Args:
            frame_array: The input frame as a NumPy array.
            format_name: The format of the input frame.

        Returns:
            The converted RGB frame as a NumPy array.

        Raises:
            ValueError: If the format is unsupported.
        rgbzUnsupported format: )
startswithr   FORMAT_CONVERSIONSr   rJ   cv2cvtColor)rD   r   r   conversion_codes       r5   _convert_framez SmallWebRTCClient._convert_frame  sX     !!%(+>>BB;O"3K=ABB||K99r4   video_sourcec                  K   	 |t         k(  r| j                  n| j                  }|t        j                  d       d{    B	 t        j
                  |j                         d       d{   }|t        |t              st        j                  d       d{    |j                   j"                  }|j%                  |      }| j'                  ||      }~|j)                         }~t+        | j                  j,                  ||j.                  |j0                  fd	      }||_        |j4                  |_        ~~| E7 
7 # t        j                  $ rG | j                  j                         r'|r%|j                         rt        j                  d       d}Y 4t        $ r t        j                  d       d}Y Vw xY w7 0w)
am  Read video frames from the WebRTC connection.

        Reads a video frame from the given MediaStreamTrack, converts it to RGB,
        and creates an InputImageRawFrame.

        Args:
            video_source: Video source to capture ("camera" or "screenVideo").

        Yields:
            UserImageRawFrame objects containing video data from the peer.
        N{Gz?       @timeoutz;Timeout: No video frame received within the specified time.zBReceived an unexpected media stream error while reading the video.r~   RGB)user_idr   sizer   )CAM_VIDEO_SOURCEr   r   rK   r[   wait_forrk   TimeoutErrorr   is_connected
is_enabledr	   warningr!   
isinstancer$   r   name
to_ndarrayr   tobytesr   r   ru   rv   transport_sourcerd   )	rD   r   video_trackrj   r   r   	frame_rgbimage_bytesimage_frames	            r5   read_video_framez"SmallWebRTCClient.read_video_frame  s       #33 ''-- 
 "mmD)))%..{/?/?/A3OO }Juj$AmmD))),,++K**+*>K++KEI#++-K+//55!kk5<<0	K ,8K(#iiKOe  * P'' ++88:##..0NN#`a# cd *s`   =GE	 G(E .E/E 3*GGB,GE AG
$G'G
G	G

Gc                  K   	 | j                   t        j                  d       d{    +	 t        j                  | j                   j	                         d       d{   }|t        |t              st        j                  d       d{    |j                  | j                  k7  r| j                   j#                  |      n|g}|D ]y  }|j%                         j'                  t(        j*                        }|j-                         }~t/        || j                  | j0                        }|j2                  |_        ~| { ~J7 &7 # t        j
                  $ r[ | j                  j                         r;| j                   r/| j                   j                         rt        j                  d       d}Y Zt        $ r t        j                  d       d}Y |w xY w7 Vw)zRead audio frames from the WebRTC connection.

        Reads 20ms of audio from the given MediaStreamTrack and creates an InputAudioRawFrame.

        Yields:
            InputAudioRawFrame objects containing audio data from the peer.
        Nr   r   r   z;Timeout: No audio frame received within the specified time.zBReceived an unexpected media stream error while reading the audio.)audiorE   num_channels)r   rK   r[   r   rk   r   r   r   r   r	   r   r!   r   r"   rE   r   r   resampler   astyper`   rb   r   r   r   rd   )rD   rj   frames_to_processprocessed_frame	pcm_array	pcm_bytesaudio_frames          r5   read_audio_framez"SmallWebRTCClient.read_audio_frameZ  s     &&.mmD)))%..t/F/F/K/K/MWZ[[ }Juj$AmmD)))
 $$(<(<< ((11%8W  $5 "+668??I	%--/	0# $ 4 4!%!8!8
 #())!!"  _ ) \'' ++88:////::<NN#`a# cd *s^   &G)EG)2E !E"E &*G)G&B>G)E A*G#=G) G#G)"G##G)rj   c                    K   | j                         r:| j                  r.| j                  j                  |j                         d{    yy7 w)zWrite an audio frame to the WebRTC connection.

        Args:
            frame: The audio frame to transmit.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        NTF)	_can_sendr   rT   r   ry   s     r5   write_audio_framez#SmallWebRTCClient.write_audio_frame  sD      >> 8 8**::5;;GGG Hs   AAAAc                 |   K   | j                         r(| j                  r| j                  j                  |       yyw)zWrite a video frame to the WebRTC connection.

        Args:
            frame: The video frame to transmit.

        Returns:
            True if the video frame was written successfully, False otherwise.
        TF)r   r   rz   ry   s     r5   write_video_framez#SmallWebRTCClient.write_video_frame  s4      >> 8 8$$44U;s   :<r   c                   K   |j                   | _        |j                  xs |j                  | _        |j                  xs |j                  | _        || _        | xj                  dz  c_        t        dd| j                        | _	        yw)zSet up the client with transport parameters.

        Args:
            _params: Transport configuration parameters.
            frame: The initialization frame containing setup data.
        rZ   s16rX   N)
audio_in_channelsr   audio_in_sample_rater   audio_out_sample_rater   r   r   r#   r   )rD   r   rj   s      r5   setupzSmallWebRTCClient.setup  sw      #*";";&;;Yu?Y?Y ' = = \A\A\q #1%AUAU#V s   B	Bc                    K   | j                   j                         ryt        j                  d       | j                   j	                          d{    y7 w)z Establish the WebRTC connection.NzConnecting to Small WebRTC)r   r   r	   infoconnectrD   s    r5   r   zSmallWebRTCClient.connect  s@     ""//102%%--///s   AAAAc                 >  K   | xj                   dz  c_         | j                   dkD  ry| j                  rd| j                  sWt        j                  d       d| _        | j                  j                          d{    | j                          d{    yyy7 7 	w)z Disconnect from the WebRTC peer.rZ   r   NzDisconnecting to Small WebRTCT)	r   r   
is_closingr	   r   r   r   
disconnectr   r   s    r5   r   zSmallWebRTCClient.disconnect  s     q "T__KK79 DM))4466600222	 &5 72s$   A7B9B:BBBBc                 x   K   | j                         r&| j                  j                  |j                         yyw)zSend an application message through the WebRTC connection.

        Args:
            frame: The message frame to send.
        N)r   r   send_app_messager   ry   s     r5   send_messagezSmallWebRTCClient.send_message  s/      >>##44U]]C s   8:c                   K   | j                   sy| j                  j                         | _        | j                  j	                         | _        | j                  j                         | _        | j                   j                  r@t        | j                        | _        | j                  j                  | j                         | j                   j                  r_t        | j                   j                  | j                   j                         | _        | j                  j%                  | j"                         | j&                  j)                  | j                         d{    y7 w)z'Handle client connection establishment.N)rE   )ru   rv   )r   r   audio_input_trackr   video_input_trackr   screen_video_input_trackr   audio_out_enabledr7   r   r   replace_audio_trackvideo_out_enabledro   video_out_widthvideo_out_heightr   replace_video_trackr   r+   r   s    r5   r   z*SmallWebRTCClient._handle_client_connected  s      ||"&"9"9"K"K"M"&"9"9"K"K"M#'#:#:#S#S#U <<))'4AVAV'WD$##778P8PQ<<))'4ll224<<;X;X(D$ ##778P8PQoo11$2I2IJJJs   EE( E&!E(c                 R   K   d| _         d| _        d| _        d| _        d| _        yw)z"Handle peer disconnection cleanup.N)r   r   r   r   r   r   s    r5   r   z+SmallWebRTCClient._handle_peer_disconnected  s.     "&"&#' #' #' s   %'c                    K   d| _         d| _        d| _        d| _        d| _        | j
                  s.| j                  j                  | j                         d{    yy7 w)z!Handle client connection closure.N)	r   r   r   r   r   r   r   r,   r   r   s    r5   r   z'SmallWebRTCClient._handle_client_closed  s]     "&"&#' #' #'  }}//889P9PQQQ Qs   AA#A!A#r   senderc                 X   K   | j                   j                  ||       d{    y7 w)%Handle incoming application messages.N)r   r*   rD   r   r  s      r5   r   z%SmallWebRTCClient._handle_app_message  s      oo,,Wf===s    *(*c                 8    | j                   xr | j                   S )z2Check if the connection is ready for sending data.)r   r   r   s    r5   r   zSmallWebRTCClient._can_send  s      8%88r4   c                 6    | j                   j                         S )ztCheck if the WebRTC connection is established.

        Returns:
            True if connected to the peer.
        )r   r   r   s    r5   r   zSmallWebRTCClient.is_connected  s     &&3355r4   c                     | j                   S )zCheck if the connection is in the process of closing.

        Returns:
            True if the connection is closing.
        )r   r   s    r5   r   zSmallWebRTCClient.is_closing  s     }}r4   N)'r-   r.   r/   r0   r   COLOR_YUV2RGB_I420COLOR_YUV2RGB_NV12COLOR_GRAY2RGBr   r   r)   r<   r`   ndarrayr1   r   r   r   r   boolr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   propertyr   r   r3   r4   r5   r   r      s7    ))**&&""	+F*? +FL` +FZ:"** :3 :2:: :.>3 >@7r-@ T -@ T W? W0
3	D03TT	DK*(R> >c >9 6d 6 6 D  r4   r   c                        e Zd ZdZdedef fdZdedef fdZ	de
f fdZd	 Zdef fd
Zdef fdZd ZdefdZdefdZdefdZefdefdZ xZS )SmallWebRTCInputTransportzInput transport implementation for SmallWebRTC.

    Handles incoming audio and video streams from WebRTC peers,
    including user image requests and application message handling.
    clientparamsc                     t        |   |fi | || _        || _        d| _        d| _        d| _        g | _        d| _        y)zInitialize the WebRTC input transport.

        Args:
            client: The WebRTC client instance.
            params: Transport configuration parameters.
            **kwargs: Additional arguments passed to parent class.
        NF)	r;   r<   _clientr   _receive_audio_task_receive_video_task_receive_screen_video_task_image_requests_initializedrD   r  r  kwargsrF   s       r5   r<   z"SmallWebRTCInputTransport.__init__)  sO     	*6*#' #' *.'<> "r4   rj   	directionc                    K   t         |   ||       d{    t        |t              r| j	                  |       d{    yy7 /7 w)zProcess incoming frames including user image requests.

        Args:
            frame: The frame to process.
            direction: The direction of frame flow in the pipeline.
        N)r;   process_framer   r   request_participant_image)rD   rj   r  rF   s      r5   r  z'SmallWebRTCInputTransport.process_frameA  sM      g#E9555e2300777 4 	6 8s!   AA(A A	A	Ac                 n  K   t         |   |       d{    | j                  ryd| _        | j                  j	                  | j
                  |       d{    | j                  j                          d{    | j                  |       d{    | j                  s:| j
                  j                  r$| j                  | j                               | _        | j                  sA| j
                  j                  r*| j                  | j                  t                    | _        yyy7 7 7 7 w)zStart the input transport and establish WebRTC connection.

        Args:
            frame: The start frame containing initialization parameters.
        NT)r;   startr  r  r   r   r   set_transport_readyr  audio_in_enabledcreate_task_receive_audior  video_in_enabled_receive_videor   rD   rj   rF   s     r5   r"  zSmallWebRTCInputTransport.startM  s      gmE""" ll  u555ll""$$$&&u---''DLL,I,I'+'7'78K8K8M'ND$''DLL,I,I'+'7'78K8KL\8]'^D$ -J' 	# 	6$-sG   D5D,AD5D/!D5:D1;D5D3BD5/D51D53D5c                    K   | j                   r*| j                  | j                          d{    d| _         | j                  r+| j                  | j                         d{    d| _        yy7 C7 w)zStop all background tasks.N)r  cancel_taskr  r   s    r5   _stop_tasksz%SmallWebRTCInputTransport._stop_tasksb  sl     ##""4#;#;<<<'+D$##""4#;#;<<<'+D$ $ = =s!   +A5A15A5#A3$A53A5c                    K   t         |   |       d{    | j                          d{    | j                  j	                          d{    y7 ?7 )7 	w)zStop the input transport and disconnect from WebRTC.

        Args:
            frame: The end frame signaling transport shutdown.
        N)r;   stopr,  r  r   r)  s     r5   r.  zSmallWebRTCInputTransport.stopk  sP      gl5!!!   ll%%''' 	" '1   AAAA!AAAAAc                    K   t         |   |       d{    | j                          d{    | j                  j	                          d{    y7 ?7 )7 	w)zCancel the input transport and disconnect immediately.

        Args:
            frame: The cancel frame signaling immediate cancellation.
        N)r;   cancelr,  r  r   r)  s     r5   r1  z SmallWebRTCInputTransport.cancelu  sP      gnU###   ll%%''' 	$ 'r/  c           	      ,  K   	 | j                   j                         }|2 3 d{   }|s| j                  |       d{    &7 !7 6 y# t        $ r<}t	        j
                  |  d|j                  j                   d| d       Y d}~yd}~ww xY ww)z7Background task for receiving audio frames from WebRTC.N exception receiving data:  ())r  r   push_audio_frame	Exceptionr	   errorrF   r-   )rD   audio_iteratorr   es       r5   r&  z(SmallWebRTCInputTransport._receive_audio  s     	[!\\::<N%3 = =k//<<<=< &4  	[LLD6!<Q[[=Q=Q<RRTUVTWWXYZZ	[se   BA A
AA
A A  AA A
A 
A B	B2BBBBr   c                   K   	 | j                   j                  |      }|2 3 d{   }|s| j                  |       d{    | j                  dd D ]  }|r|j                  nd}|r|j
                  nd}|j                  |k(  s3t        |j                  |j                  |j                  |j                  |||      }||_        | j                  |       d{    | j                  j                  |        7 7 7 &6 y# t        $ r<}t        j                   |  d|j"                  j$                   d| d       Y d}~yd}~ww xY ww)zBackground task for receiving video frames from WebRTC.

        Args:
            video_source: Video source to capture ("camera" or "screenVideo").
        N)r   r   r   r   textappend_to_contextrequestr3  r4  r5  )r  r   push_video_framer  r<  r=  r   r   r   r   r   r   r   remover7  r	   r8  rF   r-   )	rD   r   video_iteratorvideo_framerequest_framerequest_textadd_to_contextr   r:  s	            r5   r(  z(SmallWebRTCInputTransport._receive_video  sZ    	[!\\::<HN%3 G Gk//<<<
 *.)=)=a)@ G=J}'9'9PTLY)H)H_c(55E*;(5(=(=&1&7&7%0%5%5'2'9'9%12@(5+K <HK8"&"7"7"DDD 0077F%GG<* E/ &46  	[LLD6!<Q[[=Q=Q<RRTUVTWWXYZZ	[s   ED DD DD D DAD AD D"D  DD D D E	E2EEEEr   c                 ~   K   t        j                  d|        | j                  t        |       d{    y7 w)zPush an application message into the pipeline.

        Args:
            message: The application message to process.
        z7Received app message inside SmallWebRTCInputTransport  )r   N)r	   r   broadcast_framer   )rD   r   s     r5   push_app_messagez*SmallWebRTCInputTransport.push_app_message  s6      	NwiXY""#=w"OOOs   3=;=c                 4  K   t        j                  d|j                          | j                  j	                  |       |j
                  t        |_        |j
                  t        k(  rL| j                  s@| j                  j                  r*| j                  | j                  t                    | _        y|j
                  t        k(  rN| j                  sA| j                  j                  r*| j                  | j                  t                    | _        yyyyw)a.  Request an image frame from the participant's video stream.

        When a UserImageRequestFrame is received, this method will store the request
        and the next video frame received will be converted to a UserImageRawFrame.

        Args:
            frame: The user image request frame.
        z#Requesting image from participant: N)r	   r   r   r  rO   r   r   r  r   r'  r%  r(  SCREEN_VIDEO_SOURCEr  ry   s     r5   r   z3SmallWebRTCInputTransport.request_participant_image  s      	:5==/JK 	##E* %!1E "22,,-- (,'7'78K8KL\8]'^D$"5533-- /3.>.>##$78/D+ . 4 6s   DDsourcec                   K   |t         k(  rG| j                  s;| j                  j                  r%| j	                  | j                               | _        y|t        k(  rL| j                  s@| j                  j                  r*| j	                  | j                  t                    | _        y|t        k(  rN| j                  sA| j                  j                  r*| j	                  | j                  t                    | _        yyyyw)zCapture media from a specific participant.

        Args:
            source: Media source to capture from. ("camera", "microphone", or "screenVideo")
        N)MIC_AUDIO_SOURCEr  r   r$  r%  r&  r   r  r'  r(  rJ  r  )rD   rK  s     r5   capture_participant_mediaz3SmallWebRTCInputTransport.capture_participant_media  s      &&,,-- (,'7'78K8K8M'ND$&&,,-- (,'7'78K8KL\8]'^D$))33-- /3.>.>##$78/D+ . 4 *s   C>D )r-   r.   r/   r0   r   r   r<   r   r   r  r   r"  r,  r   r.  r   r1  r&  r1   r(  r   rH  r   r   r   rN  rl   rm   s   @r5   r  r  "  s    "!"  "0
8 
8> 
8_ _*,( ((+ (	[$[ $[LPc P!5J !J '  r4   r  c                        e Zd ZdZdedef fdZdef fdZde	f fdZ
def fdZdeez  fd	Zded
efdZded
efdZ xZS )SmallWebRTCOutputTransportzOutput transport implementation for SmallWebRTC.

    Handles outgoing audio and video streams to WebRTC peers,
    including transport message sending.
    r  r  c                 P    t        |   |fi | || _        || _        d| _        y)zInitialize the WebRTC output transport.

        Args:
            client: The WebRTC client instance.
            params: Transport configuration parameters.
            **kwargs: Additional arguments passed to parent class.
        FN)r;   r<   r  r   r  r  s       r5   r<   z#SmallWebRTCOutputTransport.__init__  s/     	*6* "r4   rj   c                 F  K   t         |   |       d{    | j                  ryd| _        | j                  j	                  | j
                  |       d{    | j                  j                          d{    | j                  |       d{    y7 7 B7 "7 w)zStart the output transport and establish WebRTC connection.

        Args:
            frame: The start frame containing initialization parameters.
        NT)r;   r"  r  r  r   r   r   r#  r)  s     r5   r"  z SmallWebRTCOutputTransport.start  s      gmE""" ll  u555ll""$$$&&u--- 	# 	6$-sF   B!BAB!B!B!:B;B!BB!B!B!B!c                    K   t         |   |       d{    | j                  j                          d{    y7 '7 w)zStop the output transport and disconnect from WebRTC.

        Args:
            frame: The end frame signaling transport shutdown.
        N)r;   r.  r  r   r)  s     r5   r.  zSmallWebRTCOutputTransport.stop,  s:      gl5!!!ll%%''' 	"'   A>!AA A Ac                    K   t         |   |       d{    | j                  j                          d{    y7 '7 w)zCancel the output transport and disconnect immediately.

        Args:
            frame: The cancel frame signaling immediate cancellation.
        N)r;   r1  r  r   r)  s     r5   r1  z!SmallWebRTCOutputTransport.cancel5  s:      gnU###ll%%''' 	$'rT  c                 V   K   | j                   j                  |       d{    y7 w)zSend a transport message through the WebRTC connection.

        Args:
            frame: The transport message frame to send.
        N)r  r   ry   s     r5   r   z'SmallWebRTCOutputTransport.send_message>  s       ll''...s   )')r   c                 T   K   | j                   j                  |       d{   S 7 w)zWrite an audio frame to the WebRTC connection.

        Args:
            frame: The output audio frame to transmit.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        N)r  r   ry   s     r5   r   z,SmallWebRTCOutputTransport.write_audio_frameH  #      \\33E::::   (&(c                 T   K   | j                   j                  |       d{   S 7 w)zWrite a video frame to the WebRTC connection.

        Args:
            frame: The output video frame to transmit.

        Returns:
            True if the video frame was written successfully, False otherwise.
        N)r  r   ry   s     r5   r   z,SmallWebRTCOutputTransport.write_video_frameS  rX  rY  )r-   r.   r/   r0   r   r   r<   r   r"  r   r.  r   r1  r   r   r   r   r  r   r   r   rl   rm   s   @r5   rP  rP     s~    "!"  "(. ."( ((+ (/03TT/	;-@ 	;T 	;	;-@ 	;T 	;r4   rP  c            
            e Zd ZdZ	 	 ddededee   dee   f fdZde	fdZ
defd	Zd
eez  fdZd
efdZdedefdZd Zd ZefdefdZefdefdZ xZS )SmallWebRTCTransporta  WebRTC transport implementation for real-time communication.

    Provides bidirectional audio and video streaming over WebRTC connections
    with support for application messaging and connection event handling.

    Event handlers available:

    - on_client_connected(transport, client): Client connected to WebRTC session
    - on_client_disconnected(transport, client): Client disconnected from WebRTC session
    - on_client_message(transport, message, client): Received a data channel message

    Example::

        @transport.event_handler("on_client_connected")
        async def on_client_connected(transport, client):
            ...
    r   r  
input_nameoutput_namec                 P   t         |   ||       || _        t        | j                  | j
                  | j                        | _        t        || j                        | _	        d| _
        d| _        | j                  d       | j                  d       | j                  d       y)a9  Initialize the WebRTC transport.

        Args:
            webrtc_connection: The underlying WebRTC connection handler.
            params: Transport configuration parameters.
            input_name: Optional name for the input processor.
            output_name: Optional name for the output processor.
        )r]  r^  )r*   r+   r,   Nr*   r+   r,   )r;   r<   r   r)   _on_app_message_on_client_connected_on_client_disconnectedr   r   r  _input_output_register_event_handler)rD   r   r  r]  r^  rF   s        r5   r<   zSmallWebRTCTransport.__init__r  s     	JKH.// $ 9 9#'#?#?
 )):DOOL;?=A 	$$%56$$%:;$$%=>r4   r   c                     | j                   s1t        | j                  | j                  | j                        | _         | j                   S )zGet the input transport processor.

        Returns:
            The input transport for handling incoming media streams.
        r   )rc  r  r  r   _input_namer   s    r5   inputzSmallWebRTCTransport.input  s8     {{3dll1A1ADK {{r4   c                     | j                   s1t        | j                  | j                  | j                        | _         | j                   S )zGet the output transport processor.

        Returns:
            The output transport for handling outgoing media streams.
        rg  )rd  rP  r  r   rh  r   s    r5   outputzSmallWebRTCTransport.output  s8     ||5dll1A1ADL ||r4   rj   c                    K   | j                   r3| j                   j                  |t        j                         d{    yy7 w)znSend an image frame through the transport.

        Args:
            frame: The image frame to send.
        Nrd  queue_framer   
DOWNSTREAMry   s     r5   
send_imagezSmallWebRTCTransport.send_image  7      <<,,**5.2K2KLLL L   :AAAc                    K   | j                   r3| j                   j                  |t        j                         d{    yy7 w)znSend an audio frame through the transport.

        Args:
            frame: The audio frame to send.
        Nrm  ry   s     r5   
send_audiozSmallWebRTCTransport.send_audio  rq  rr  r   r  c                    K   | j                   r#| j                   j                  |       d{    | j                  d||       d{    y7  7 w)r  Nr*   )rc  rH  _call_event_handlerr  s      r5   r`  z$SmallWebRTCTransport._on_app_message  sG     ;;++..w777&&'7&III 8Is!   +AAAA	AAc                    K   | j                  d|       d{    | j                  r,| j                  j                  t                      d{    yy7 =7 w)z Handle client connection events.r+   N)rv  rc  
push_framer   rD   r   s     r5   ra  z)SmallWebRTCTransport._on_client_connected  sP     &&'<>OPPP;;++(()=)?@@@  	Q@s!   AA6AAAAc                 D   K   | j                  d|       d{    y7 w)z#Handle client disconnection events.r,   N)rv  ry  s     r5   rb  z,SmallWebRTCTransport._on_client_disconnected  s     &&'?ARSSSs     r   c                 r   K   | j                   r%| j                   j                  |       d{    yy7 w)zCapture video from a specific participant.

        Args:
            video_source: Video source to capture from ("camera" or "screenVideo").
        rK  Nrc  rN  )rD   r   s     r5   capture_participant_videoz.SmallWebRTCTransport.capture_participant_video  2      ;;++77|7LLL L   ,757audio_sourcec                 r   K   | j                   r%| j                   j                  |       d{    yy7 w)zCapture audio from a specific participant.

        Args:
            audio_source: Audio source to capture from. (currently, "microphone" is the only supported option)
        r|  Nr}  )rD   r  s     r5   capture_participant_audioz.SmallWebRTCTransport.capture_participant_audio  r  r  )NN)r-   r.   r/   r0   r   r   r   r1   r<   r  ri  rP  rk  r   r   rp  r   rt  r   r`  ra  rb  r   r~  rM  r  rl   rm   s   @r5   r\  r\  _  s    , %)%)!?0!?  !? SM	!?
 c]!?F
0 

2 
M&9K&G MM&9 MJS J# JAT -
M
M -
M
Mr4   r\  )Dr0   rK   re   rA   collectionsr   typingr   r   r   r   r   numpyr`   logurur	   pydanticr
   pipecat.frames.framesr   r   r   r   r   r   r   r   r   r   r   r   r   r   "pipecat.processors.frame_processorr   pipecat.transports.base_inputr   pipecat.transports.base_outputr   !pipecat.transports.base_transportr   r   )pipecat.transports.smallwebrtc.connectionr   r   aiortcr   aiortc.mediastreamsr    r!   avr"   r#   r$   ModuleNotFoundErrorr:  r8  r7  r   rJ  rM  r)   r7   ro   r   r  rP  r\  r3   r4   r5   <module>r     s'       ; ;        > < > L K,'F99  #  O9 OK$ K\,$ ,^W Wt
[ 2 [|\;!4 \;~FM= FMY  ,FLL;qc"#FLLab
&qc*
++,s   4C# #D(2DD