
    qi                    F   d Z ddlZddlZddlmZ ddlmZ ddlmZm	Z	 ddl
mZmZ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 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(m)Z)m*Z*m+Z+m,Z,m-Z- ddl.m/Z/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8m9Z9 ddl:m;Z; 	 ddl<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZF ddl<mGZH dZMe G d de&             ZNe G d de'             ZOe G d deN             ZPe G d deO             ZQe G d d e"             ZR G d! d"eR      ZSe G d# d$e             ZTe G d% d&e             ZUe G d' d(e             ZV G d) d*e      ZW G d+ d,e      ZX G d- d.e      ZY G d/ d0e      ZZ G d1 d2e      Z[ G d3 d4e9      Z\ G d5 d6e      Z]d7 Z^e G d8 d9             Z_e G d: d;             Z`eaZb G d< d=eD      Zc G d> d?e4      Zd G d@ dAe6      Ze G dB dCe8      Zfy# eI$ r7ZJ ej                  deJ         ej                  d        eLdeJ       dZJ[Jww xY w)DzDaily transport implementation for Pipecat.

This module provides comprehensive Daily video conferencing integration including
audio/video streaming, transcription, recording, dial-in/out functionality, and
real-time communication features.
    N)CancelledError)ThreadPoolExecutor)	dataclassfield)Any	AwaitableCallableDictMappingOptionalTuple)logger)	BaseModel)VADAnalyzer	VADParams)BotConnectedFrameCancelFrameClientConnectedFrame	DataFrameEndFrameFrameInputAudioRawFrameInputTransportMessageFrameInterimTranscriptionFrameOutputAudioRawFrameOutputImageRawFrameOutputTransportMessageFrame!OutputTransportMessageUrgentFrameSpriteFrame
StartFrameTranscriptionFrameUserAudioRawFrameUserImageRawFrameUserImageRequestFrame)FrameDirectionFrameProcessorSetup)Language)BaseInputTransport)BaseOutputTransport)BaseTransportTransportParams)BaseTaskManager)
	AudioData
CallClientCustomAudioSourceCustomAudioTrackCustomVideoSourceCustomVideoTrackDailyEventHandler
VideoFrameVirtualSpeakerDevice)LogLevelzException: zQIn order to use the Daily transport, you need to `pip install pipecat-ai[daily]`.zMissing module: i  c                   &    e Zd ZU dZdZee   ed<   y) DailyOutputTransportMessageFramezFrame for transport messages in Daily calls.

    Parameters:
        participant_id: Optional ID of the participant this message is for/from.
    Nparticipant_id__name__
__module____qualname____doc__r:   r   str__annotations__     T/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/transports/daily/transport.pyr9   r9   N        %)NHSM(rC   r9   c                   &    e Zd ZU dZdZee   ed<   y)&DailyOutputTransportMessageUrgentFramezFrame for urgent transport messages in Daily calls.

    Parameters:
        participant_id: Optional ID of the participant this message is for/from.
    Nr:   r;   rB   rC   rD   rG   rG   Y   rE   rC   rG   c                   "     e Zd ZdZ fdZ xZS )DailyTransportMessageFramea2  Frame for transport messages in Daily calls.

    .. deprecated:: 0.0.87
        This frame is deprecated and will be removed in a future version.
        Instead, use `DailyOutputTransportMessageFrame`.

    Parameters:
        participant_id: Optional ID of the participant this message is for/from.
    c                     t         |           dd l}|j                         5  |j	                  d       |j                  dt        d       d d d        y # 1 sw Y   y xY w)Nr   alwayszDailyTransportMessageFrame is deprecated and will be removed in a future version. Instead, use DailyOutputTransportMessageFrame.   
stacklevelsuper__post_init__warningscatch_warningssimplefilterwarnDeprecationWarningselfrR   	__class__s     rD   rQ   z(DailyTransportMessageFrame.__post_init__p   s]    $$& 	!!(+MMA"	  	 	 	   *AA r<   r=   r>   r?   rQ   __classcell__rY   s   @rD   rI   rI   d        rC   rI   c                   "     e Zd ZdZ fdZ xZS ) DailyTransportMessageUrgentFramea?  Frame for urgent transport messages in Daily calls.

    .. deprecated:: 0.0.87
        This frame is deprecated and will be removed in a future version.
        Instead, use `DailyOutputTransportMessageUrgentFrame`.

    Parameters:
        participant_id: Optional ID of the participant this message is for/from.
    c                     t         |           dd l}|j                         5  |j	                  d       |j                  dt        d       d d d        y # 1 sw Y   y xY w)Nr   rK   zDailyTransportMessageUrgentFrame is deprecated and will be removed in a future version. Instead, use DailyOutputTransportMessageUrgentFrame.rL   rM   rO   rW   s     rD   rQ   z.DailyTransportMessageUrgentFrame.__post_init__   s]    $$& 	!!(+MMG"	  	 	 	rZ   r[   r]   s   @rD   r`   r`   ~   r^   rC   r`   c                   &    e Zd ZU dZdZee   ed<   y)DailyInputTransportMessageFramezFrame for input urgent transport messages in Daily calls.

    Parameters:
        participant_id: Optional ID of the participant this message is for/from.
    Nr:   r;   rB   rC   rD   rc   rc      rE   rC   rc   c                   "     e Zd ZdZ fdZ xZS )%DailyInputTransportMessageUrgentFramea>  Frame for input urgent transport messages in Daily calls.

    .. deprecated:: 0.0.87
        This frame is deprecated and will be removed in a future version.
        Instead, use `DailyInputTransportMessageFrame`.

    Parameters:
        participant_id: Optional ID of the participant this message is for/from.
    c                     t         |           dd l}|j                         5  |j	                  d       |j                  dt        d       d d d        y # 1 sw Y   y xY w)Nr   rK   zDailyInputTransportMessageUrgentFrame is deprecated and will be removed in a future version. Instead, use DailyInputTransportMessageFrame.rL   rM   rO   rW   s     rD   rQ   z3DailyInputTransportMessageUrgentFrame.__post_init__   s]    $$& 	!!(+MM@"	  	 	 	rZ   r[   r]   s   @rD   re   re      s     rC   re   c                   8    e Zd ZU dZ ee      Zeee	f   e
d<   y)DailySIPTransferFramea<  SIP call transfer frame for transport queuing.

    A SIP call transfer that will be queued. The transfer will happen after any
    preceding audio finishes playing, allowing the bot to complete its current
    utterance before the transfer occurs.

    Parameters:
        settings: SIP call transfer settings.
    default_factorysettingsNr<   r=   r>   r?   r   dictrk   r   r@   r   rA   rB   rC   rD   rh   rh      !     #("=Hgc3h=rC   rh   c                   8    e Zd ZU dZ ee      Zeee	f   e
d<   y)DailySIPReferFramea  SIP REFER frame for transport queuing.

    A SIP REFER that will be queued. The REFER will happen after any preceding
    audio finishes playing, allowing the bot to complete its current utterance
    before the REFER occurs.

    Parameters:
        settings: SIP REFER settings.
    ri   rk   Nrl   rB   rC   rD   rp   rp      rn   rC   rp   c                   8    e Zd ZU dZ ee      Zeee	f   e
d<   y)"DailyUpdateRemoteParticipantsFramezFrame to update remote participants in Daily calls.

    Parameters:
        remote_participants: See https://reference-python.daily.co/api_reference.html#daily.CallClient.update_remote_participants.
    ri   remote_participantsN)r<   r=   r>   r?   r   rm   rs   r   r@   r   rA   rB   rC   rD   rr   rr      s"     .34-Hc*HrC   rr   c                   X     e Zd ZdZddddee   dee   f fdZdefdZde	fd	Z
 xZS )
WebRTCVADAnalyzerz~Voice Activity Detection analyzer using WebRTC.

    Implements voice activity detection using Daily's native WebRTC VAD.
    Nsample_rateparamsrw   rx   c                    t         |   ||       t        j                  t        | j
                  d      | _        t        j                  d       y)zInitialize the WebRTC VAD analyzer.

        Args:
            sample_rate: Audio sample rate in Hz.
            params: VAD configuration parameters.
        rv      )reset_period_msrw   channelszLoaded native WebRTC VADN)	rP   __init__r3   create_native_vadVAD_RESET_PERIOD_MSrw   _webrtc_vadr   debug)rX   rw   rx   rY   s      rD   r}   zWebRTCVADAnalyzer.__init__   sG     	[@ 22/T=M=MXY
 	/0rC   returnc                 2    t        | j                  dz        S )zGet the number of audio frames required for VAD analysis.

        Returns:
            The number of frames needed (equivalent to 10ms of audio).
        g      Y@)intrw   rX   s    rD   num_frames_requiredz%WebRTCVADAnalyzer.num_frames_required   s     4##e+,,rC   c                 \    d}t        |      dkD  r| j                  j                  |      }|S )zAnalyze audio buffer and return voice confidence score.

        Args:
            buffer: Audio buffer to analyze.

        Returns:
            Voice confidence score between 0.0 and 1.0.
        r   )lenr   analyze_frames)rX   buffer
confidences      rD   voice_confidencez"WebRTCVADAnalyzer.voice_confidence  s0     
v;?))88@JrC   )r<   r=   r>   r?   r   r   r   r}   r   floatr   r\   r]   s   @rD   ru   ru      sD    
 8<[_ 1x} 1XiEX 1-S -% rC   ru   c                   .    e Zd ZU dZdZeed<   dZeed<   y)DailyDialinSettingsa  Settings for Daily's dial-in functionality.

    Parameters:
        call_id: CallId is represented by UUID and represents the sessionId in the SIP Network.
        call_domain: Call Domain is represented by UUID and represents your Daily Domain on the SIP Network.
     call_idcall_domainN)r<   r=   r>   r?   r   r@   rA   r   rB   rC   rD   r   r     s     GSKrC   r   c                       e Zd ZU dZdZeed<   dZeed<   dZe	ed<   dZ
e	ed	<   dZe	ed
<   dZe	ed<   dZe	ed<   ddiZeeef   ed<   y)DailyTranscriptionSettingsaw  Configuration settings for Daily's transcription service.

    Parameters:
        language: ISO language code for transcription (e.g. "en").
        model: Transcription model to use (e.g. "nova-2-general").
        profanity_filter: Whether to filter profanity from transcripts.
        redact: Whether to redact sensitive information.
        endpointing: Whether to use endpointing to determine speech segments.
        punctuate: Whether to add punctuation to transcripts.
        includeRawResponse: Whether to include raw response data.
        extra: Additional parameters passed to the Deepgram transcription service.
    enlanguageznova-2-generalmodelTprofanity_filterFredactendpointing	punctuateincludeRawResponseinterim_resultsextraN)r<   r=   r>   r?   r   r@   rA   r   r   boolr   r   r   r   r   r   r   rB   rC   rD   r   r     si     Hc!E3!!d!FDKIt## 148E7388rC   r   c                   Z    e Zd ZU dZdZeed<   dZeed<   dZe	ed<   dZ
eee	ef      ed	<   y)
DailyCustomVideoTrackParamsa  Configuration for a custom video track.

    If ``send_settings`` is not provided, the track will use the default video
    publishing settings (framerate, bitrate, codec, etc.).

    Parameters:
        width: Video width in pixels.
        height: Video height in pixels.
        color_format: Video color format (e.g., "RGB", "RGBA", "BGRA").
        send_settings: Optional Daily sendSettings dict for this track.
            See https://reference-python.daily.co/types.html#videopublishingsettings
    i   widthi   heightRGBcolor_formatNsend_settings)r<   r=   r>   r?   r   r   rA   r   r   r@   r   r   r
   r   rB   rC   rD   r   r   4  s>     E3FCL#.2M8DcN+2rC   r   c                   R    e Zd ZU dZdZee   ed<   dZeed<   dZ	ee
eef      ed<   y)DailyCustomAudioTrackParamsa  Configuration for a custom audio track.

    If ``send_settings`` is not provided, the track will use the default audio
    publishing settings (bitrate, channel config, etc.).

    Parameters:
        sample_rate: Audio sample rate in Hz. Defaults to transport's output sample rate.
        channels: Number of audio channels.
        send_settings: Optional Daily sendSettings dict for this track.
            See https://reference-python.daily.co/types.html#audiopublishingsettings
    Nrw   rz   r|   r   )r<   r=   r>   r?   rw   r   r   rA   r|   r   r
   r@   r   rB   rC   rD   r   r   H  s8    
 "&K#%Hc.2M8DcN+2rC   r   c                       e Zd ZU dZdZeed<   dZeed<   dZe	ed<   dZ
e	ed<   d	Zeeeef      ed
<   d	Zeeeef      ed<   d	Zee   ed<   dZe	ed<   dZe	ed<    e       Zeed<   y	)DailyParamsa   Configuration parameters for Daily transport.

    Parameters:
        api_url: Daily API base URL.
        api_key: Daily API authentication key.
        audio_in_user_tracks: Receive users' audio in separate tracks
        camera_out_enabled: Whether to enable the main camera output track.
        custom_audio_track_params: Per-destination configuration for custom audio tracks.
        custom_video_track_params: Per-destination configuration for custom video tracks.
        dialin_settings: Optional settings for dial-in functionality.
        microphone_out_enabled: Whether to enable the main microphone track.
        transcription_enabled: Whether to enable speech transcription.
        transcription_settings: Configuration for transcription service.
    zhttps://api.daily.co/v1api_urlr   api_keyTaudio_in_user_trackscamera_out_enabledNcustom_audio_track_paramscustom_video_track_paramsdialin_settingsmicrophone_out_enabledFtranscription_enabledtranscription_settings)r<   r=   r>   r?   r   r@   rA   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rB   rC   rD   r   r   Z  s     -GS,GS!%$%##UYx5P0P(QRYUYx5P0P(QRY59OX129#'D'"'4'9S9U6UrC   r   c                      e Zd ZU dZeeeef   ged   f   e	d<   eeeef   ged   f   e	d<   eg ed   f   e	d<   eg ed   f   e	d<   eeged   f   e	d<   eeeged   f   e	d<   eeged   f   e	d	<   eeeef   ged   f   e	d
<   eeeef   ged   f   e	d<   eeged   f   e	d<   eeged   f   e	d<   eeged   f   e	d<   eeged   f   e	d<   eeged   f   e	d<   eeged   f   e	d<   eeged   f   e	d<   eeged   f   e	d<   eeged   f   e	d<   eeged   f   e	d<   eeeef   ged   f   e	d<   eeeef   eged   f   e	d<   eeeef   ged   f   e	d<   eeeef   ged   f   e	d<   eee
ged   f   e	d<   eeged   f   e	d<   eeeef   ged   f   e	d<   eeged   f   e	d<   eeeged   f   e	d<   y)DailyCallbacksab  Callback handlers for Daily events.

    Parameters:
        on_active_speaker_changed: Called when the active speaker of the call has changed.
        on_joined: Called when bot successfully joined a room.
        on_left: Called when bot left a room.
        on_before_leave: Called when bot is about to leave the room.
        on_error: Called when an error occurs.
        on_app_message: Called when receiving an app message.
        on_call_state_updated: Called when call state changes.
        on_client_connected: Called when a client (participant) connects.
        on_client_disconnected: Called when a client (participant) disconnects.
        on_dialin_connected: Called when dial-in is connected.
        on_dialin_ready: Called when dial-in is ready.
        on_dialin_stopped: Called when dial-in is stopped.
        on_dialin_error: Called when dial-in encounters an error.
        on_dialin_warning: Called when dial-in has a warning.
        on_dialout_answered: Called when dial-out is answered.
        on_dialout_connected: Called when dial-out is connected.
        on_dialout_stopped: Called when dial-out is stopped.
        on_dialout_error: Called when dial-out encounters an error.
        on_dialout_warning: Called when dial-out has a warning.
        on_participant_joined: Called when a participant joins.
        on_participant_left: Called when a participant leaves.
        on_participant_updated: Called when participant info is updated.
        on_transcription_message: Called when receiving transcription.
        on_transcription_stopped: Called when transcription is stopped.
        on_transcription_error: Called when transcription encounters an error.
        on_recording_started: Called when recording starts.
        on_recording_stopped: Called when recording stops.
        on_recording_error: Called when recording encounters an error.
    Non_active_speaker_changed	on_joinedon_lefton_before_leaveon_erroron_app_messageon_call_state_updatedon_client_connectedon_client_disconnectedon_dialin_connectedon_dialin_readyon_dialin_stoppedon_dialin_erroron_dialin_warningon_dialout_answeredon_dialout_connectedon_dialout_stoppedon_dialout_erroron_dialout_warningon_participant_joinedon_participant_lefton_participant_updatedon_transcription_messageon_transcription_stoppedon_transcription_erroron_recording_startedon_recording_stoppedon_recording_error)r<   r=   r>   r?   r	   r   r@   r   r   rA   r   rB   rC   rD   r   r   v  s   B  (c):(;Yt_(LMMc*+Yt_<==b)D/)**b)D/122uio-..c3Z4899#SE9T?$:;;!738#4"5y"FGG$gc3h&7%8)D/%IJJ!3%4"899seYt_455y 677seYt_455y 677!3%4"899"C5)D/#9:: #	$!788uio566 #	$!788#WS#X%6$74$HII!738#4c":IdO"KLL$gc3h&7%8)D/%IJJ&S(9':IdO'KLL&T{IdO'CDD$cUIdO%;<<"GCH$5#6	$#GHH"C5)D/#9:: #sYt_!<==rC   r   c                       fd}|S )zCreate a completion callback for Daily API calls.

    Args:
        future: The asyncio Future to set the result on.

    Returns:
        A callback function that sets the future result.
    c                  P    d } j                         j                  |g|   y )Nc                     	 t        |      dkD  r| j                  |       y  | j                  |  y # t        j                  $ r Y y w xY w)Nrz   )r   
set_resultasyncioInvalidStateError)futureargss     rD   r   z:completion_callback.<locals>._callback.<locals>.set_result  sH    t9q=%%d+%F%%t,,, s   2 2 AA)get_loopcall_soon_threadsafe)r   r   r   s     rD   	_callbackz&completion_callback.<locals>._callback  s(    	 	/..z6IDIrC   rB   )r   r   s   ` rD   completion_callbackr     s    
J rC   c                   &    e Zd ZU dZeed<   eed<   y)DailyAudioTrackzContainer for Daily audio track components.

    Parameters:
        source: The custom audio source for the track.
        track: The custom audio track instance.
    sourcetrackN)r<   r=   r>   r?   r/   rA   r0   rB   rC   rD   r   r          rC   r   c                   &    e Zd ZU dZeed<   eed<   y)DailyVideoTrackzContainer for Daily video track components.

    Parameters:
        source: The custom video source for the track.
        track: The custom video track instance.
    r   r   N)r<   r=   r>   r?   r1   rA   r2   rB   rC   rD   r   r     r   rC   r   c                       e Zd ZU dZdZeed<    fdZdede	e   dede
d	ed
ef fdZd Zedefd       Zedefd       Zedefd       Zedefd       Zdeez  de	e   fdZde	e   fdZdefdZdefdZdedefdZdedefdZde fdZ!d Z"de#fdZ$d Z%d Z&d  Z'd! Z(d" Z)de*ee+f   fd#Z,de*ee+f   fd$Z-de.ee	e   f   fd%Z/de	e   fd&Z0de	e   fd'Z1de	e   fd(Z2de	e   fd)Z3de.ee	e   f   fd*Z4de	e   fd+Z5de	e   fd,Z6de	e   fd-Z7	 dod.ed/e	e   de	e   fd0Z8d1efd2Z9	 	 	 dpd1ed3e:d4ed5ed6ef
d7Z;	 	 	 dqd1ed3e:d8ed9ed:ef
d;Z<	 dod<ede	e=   de>fd=Z?d<ede	e   fd>Z@	 dod<ede	eA   deBfd?ZCd<ede	e   fd@ZD	 drde	e   fdAZE	 drde	e   fdBZFdCe*ee+f   de	e   fdDZGdEe*ee+f   de	e   fdFZHdG ZId.e+dHefdIZJdJefdKZKdLe+fdMZLdNefdOZMdLe+fdPZNdLe+fdQZOdLe+fdRZPdLe+fdSZQdLe+fdTZRdLe+fdUZSdLe+fdVZTdLe+fdWZUdX ZVdY ZWdZ ZXd[ ZYd\ ZZd] Z[d^ Z\d_ Z]d` Z^da Z_d1edbe`d4efdcZad1eddebd9efdeZcdf Zddg Zedh Zfdiegj                  fdjZidiegj                  fdkZjdl Zkdegj                  fdmZmdn Zn xZoS )sDailyTransportClientzCore client for interacting with Daily's API.

    Manages the connection to Daily rooms and handles all low-level API interactions
    including room management, media streaming, transcription, and event handling.
    F_daily_initializedc                 "    t         |   |       S )zPOverride EventHandler's __new__ method to ensure Daily is initialized only once.)rP   __new__)clsr   kwargsrY   s      rD   r   zDailyTransportClient.__new__  s    ws##rC   room_urltokenbot_namerx   	callbackstransport_namec                 ~   t         |           t        j                  sdt        _        t	        j
                          || _        || _        || _        || _	        || _
        || _        d| _        i | _        i | _        g | _        d| _        d| _        d| _        d| _        d| _        t+        j,                         | _        d| _        d| _        t5        d      | _        t9        |       | _        d| _        d| _        d| _         g | _!        d| _"        d| _#        d| _$        d| _%        d| _&        i | _'        i | _(        y)	a  Initialize the Daily transport client.

        Args:
            room_url: URL of the Daily room to connect to.
            token: Optional authentication token for the room.
            bot_name: Display name for the bot in the call.
            params: Configuration parameters for the transport.
            callbacks: Event callback handlers.
            transport_name: Name identifier for the transport.
        Tr   NFr   rz   )max_workers)event_handler))rP   r}   r   r   r3   init	_room_url_token	_bot_name_params
_callbacks_transport_name_participant_id_audio_renderers_video_renderers_transcription_ids_transcription_status_dial_out_session_id_dial_in_session_id_joining_joinedr   Event_joined_event_leave_counter_task_managerr   	_executorr.   _client_event_task_audio_task_video_task_join_message_queue_in_sample_rate_out_sample_rate_speaker_camera_track_microphone_track_custom_audio_tracks_custom_video_tracks)rX   r   r   r   rx   r   r   rY   s          rD   r}   zDailyTransportClient.__init__  s/   & 	#666: 3JJL&%*&$*#-$& " ""$%)")+!(* $]]_8< ,:#-D#A  )+   ! !8<8<<@@B!@B!rC   c                     d|  S )z@Generate a unique virtual speaker name for this client instance.zspeaker-rB   r   s    rD   _speaker_namez"DailyTransportClient._speaker_nameH  s    $  rC   r   c                     | j                   S )zhGet the Daily room URL.

        Returns:
            The room URL this client is connected to.
        )r   r   s    rD   r   zDailyTransportClient.room_urlL  s     ~~rC   c                     | j                   S )ztGet the participant ID for this client.

        Returns:
            The participant ID assigned by Daily.
        )r   r   s    rD   r:   z#DailyTransportClient.participant_idU       ###rC   c                     | j                   S )zdGet the input audio sample rate.

        Returns:
            The input sample rate in Hz.
        )r  r   s    rD   in_sample_ratez#DailyTransportClient.in_sample_rate^  r  rC   c                     | j                   S )zfGet the output audio sample rate.

        Returns:
            The output sample rate in Hz.
        )r  r   s    rD   out_sample_ratez$DailyTransportClient.out_sample_rateg  s     $$$rC   framec                 X  K   | j                   s| j                  j                  |       yd}t        |t        t
        f      r|j                  }| j                         j                         }| j                  j                  |j                  |t        |             | d{   S 7 w)zSend an application message to participants.

        Args:
            frame: The message frame to send.

        Returns:
            error: An error description or None.
        N
completion)r  r  append
isinstancer9   rG   r:   _get_event_loopcreate_futurer
  send_app_messagemessager   )rX   r  r:   r   s       rD   send_messagez!DailyTransportClient.send_messagep  s      ||$$++E246\]
 #11N%%'557%%MM>6I&6Q 	& 	
 ||s   B!B*#B($B*c                   K   | j                   sy| j                  }| j                  j                  }t	        |dz        dz  }| j                         j                         }| j                   j                  |t        |             | d{   }t        |      dkD  rt        |||      S t        j                  d       d{    y7 >7 w)z9Reads the next 20ms audio frame from the virtual speaker.Nd   rL   r!  r   )audiorw   num_channelsg{Gz?)r  r  r   audio_in_channelsr   r%  r&  read_framesr   r   r   r   sleep)rX   rw   r-  
num_framesr   r,  s         rD   read_next_audio_framez*DailyTransportClient.read_next_audio_frame  s     }}**||55s*+a/
%%'557!!*9LV9T!Uu:>%<  --%%%  &s$   B
CC8CCCCdestinationc                 8  K   | j                   j                  xs i j                  |      }| j                  ||       d{   | j                  |<   d|dii}|r |j
                  rd|j
                  i|d   |<   | j                  j                  |       y7 Uw)zRegister a custom audio destination for multi-track output.

        Args:
            destination: The destination identifier to register.
        rx   NcustomAudioTsendSettings)r   r   getadd_custom_audio_trackr  r   r
  update_publishingrX   r3  rx   
publishings       rD   register_audio_destinationz/DailyTransportClient.register_audio_destination        ,,88>BCCKP7;7R7R 8S 8
 2
!!+. '4k45H%I
f**6DfFZFZ5[J}%k2&&z22
   A BBABc                 8  K   | j                   j                  xs i j                  |      }| j                  ||       d{   | j                  |<   d|dii}|r |j
                  rd|j
                  i|d   |<   | j                  j                  |       y7 Uw)zRegister a custom video destination for multi-track output.

        Args:
            destination: The destination identifier to register.
        r5  NcustomVideoTr7  )r   r   r8  add_custom_video_trackr  r   r
  r:  r;  s       rD   register_video_destinationz/DailyTransportClient.register_video_destination  r>  r?  c                   K   | j                         j                         }|j                  }d}|s#| j                  r| j                  j                  }n+|r)|| j
                  v r| j
                  |   }|j                  }|r'|j                  |j                  t        |             n,t        j                  |  d| d       |j                  d       | d{   }|dkD  S 7 	w)zWrite an audio frame to the appropriate audio track.

        Args:
            frame: The audio frame to write.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        Nr!  z. unable to write audio frames to destination []r   )r%  r&  transport_destinationr  r   r  write_framesr,  r   r   warningr   )rX   r  r   r3  audio_sourcer   r1  s          rD   write_audio_framez&DailyTransportClient.write_audio_frame  s      %%'5571148t551188L[D,E,EE--k:E <<L%%ekk>QRX>Y%ZNNdV#QR]Q^^_`aa !\
A~ "s   CC%C#
C%c                 :  K   |j                   }d}|s#| j                  r| j                  j                  }n+|r)|| j                  v r| j                  |   }|j                  }|r|j	                  |j
                         yt        j                  |  d| d       yw)zWrite a video frame to the appropriate video track.

        Args:
            frame: The image frame to write.

        Returns:
            True if the video frame was written successfully, False otherwise.
        NTz. unable to write video frames to destination [rE  F)rF  r  r   r  write_frameimager   rH  )rX   r  r3  video_sourcer   s        rD   write_video_framez&DailyTransportClient.write_video_frame  s      1148t11--44L[D,E,EE--k:E <<L$$U[[1NNdV#QR]Q^^_`as   BBsetupc                    K   | j                   ry|j                  | _         t        j                         | _        | j                   j                  | j                  | j                        |  d      | _        yw)zSetup the client with task manager and event queues.

        Args:
            setup: The frame processor setup configuration.
        Nz::event_callback_task)r  task_managerr   Queue_event_queuecreate_task_callback_task_handlerr  )rX   rP  s     rD   rP  zDailyTransportClient.setup  sh      "//#MMO--99''(9(9:f)*
s   A6A8c                 \  K   | j                   r@| j                  r4| j                  j                  | j                          d{    d| _         | j                  r@| j                  r4| j                  j                  | j                         d{    d| _        | j                  r@| j                  r4| j                  j                  | j                         d{    d| _        | j                         j                  | j                  | j                         d{    y7 7 7 L7 w)z*Cleanup client resources and cancel tasks.N)	r  r  cancel_taskr  r  r%  run_in_executorr	  _cleanupr   s    rD   cleanupzDailyTransportClient.cleanup  s      2 2$$001A1ABBB#D 2 2$$001A1ABBB#D 2 2$$001A1ABBB#D ""$44T^^T]]SSS C C C 	TsK   AD,D$AD,D&AD,D(AD,D*D,&D,(D,*D,c                   K   | j                   j                  xs |j                  | _        | j                   j                  xs |j                  | _        | j                   j
                  r| j                   j                  ro| j                  sc| j                  rWt        j                         | _        | j                  j                  | j                  | j                        |  d      | _        ny| j                  smt        j                   | j#                         | j                  | j                   j$                  d      | _        t        j&                  | j#                                | j                   j(                  rn| j*                  sb| j                  rVt        j                         | _        | j                  j                  | j                  | j,                        |  d      | _        | j                   j.                  rr| j0                  sft3        | j                   j4                  | j                   j6                  | j                   j8                        }t;        |      }t=        ||      | _        | j                   j>                  rU| j@                  sHtC        | j                  | j                   jD                        }tG        |      }tI        ||      | _         yyyw)zStart the client and initialize audio/video components.

        Args:
            frame: The start frame containing initialization parameters.
        z::audio_callback_taskT)rw   r|   non_blockingz::video_callback_taskr   r   N)%r   audio_in_sample_rater  audio_out_sample_rater  audio_in_enabledr   r  r  r   rS  _audio_queuerU  rV  r  r3   create_speaker_devicer  r.  select_speaker_devicevideo_in_enabledr  _video_queuevideo_out_enabledr  r1   video_out_widthvideo_out_heightvideo_out_color_formatr2   r   audio_out_enabledr  r/   audio_out_channelsr0   r   )rX   r  rN  video_trackrI  audio_tracks         rD   startzDailyTransportClient.start  s%      $||@@^ED^D^ $ B B aeFaFa<<((||009I9IdN`N`$+MMO!#'#5#5#A#A//0A0ABf12$  ]] % ; ;&&( $ 4 4!\\;;!%	! ++D,>,>,@A<<((1A1AdFXFX 'D#11==++D,=,=>&-. D <<))$2D2D,,,--33L
 +<8K!0K!XD<<))$2H2H,T-B-BDLLDcDcdL*<8K%4LP[%\D" 3I)s   KK!c                   K   | j                   s| j                  r| xj                  dz  c_        yt        j                  d| j
                          d| _        | j                  j                  ddddi       | j                  j                  | j                         | j                          d{   \  }}|sd| _         d| _        | xj                  dz  c_        |j                  d	i       j                  d
i       j                  d      }|j                  di       j                  d      }t        j                  d| j
                   d| d|        | j                  j                  |       d{    | j                  j                          | j!                          d{    yd| j
                   d| }t        j"                  |       | j                  j%                  |       d{    d| _        y7 O7 7 \7 w)z-Join the Daily room with configured settings.rz   NzJoining TbaseunsubscribedcamerascreenVideoFparticipantslocalidmeetingSessionzJoined z. Participant ID: z, Meeting ID: zError joining : )r  r  r  r   infor   r
  update_subscription_profilesset_user_namer   _joinr8  r   r   r  set_flush_join_messageserrorr   )rX   datar  r:   
meeting_id	error_msgs         rD   joinzDailyTransportClient.joinB  s     <<4==1$ht~~./0 	11~NO	
 	""4>>2"jjl*uDL!DM1$!XXnb9==grJNNtTN"2B7;;DAJKK$..));N;K>ZdYef //++D111""$++---((85'BILL#//**9555!DM/ + 2 . 6sJ   B0H
2H3CH
7H81H
)H*A
H
4H5H
H
H
H
c                   K   | j                   sy| j                         j                         }| j                  j                  xr | j                  j
                  }| j                  j                  xr | j                  j                  }| j                   j                  | j                  | j                  t        |      |dd| j                  r | j                  j                  j                  ndiid|dd| j                  r | j                  j                  j                  ndiidddd	d
i| j                  j                   rd| j                  j                   ini dd
| j                  j"                  | j                  j$                  diiid| j                  j&                  dk(  rdnd| j                  j(                  didd       | d{   S 7 w)z'Execute the actual room join operation.NcustomTrackrx  zno-camera-track)	isEnabledrk   zno-microphone-track)rt  
microphoner7  
maxQualitylowpreferredCodec	encodings)
maxBitratemaxFrameraterL   stereomono)channelConfigbitrate)inputsr<  )r"  client_settings)r
  r%  r&  r   rg  r   rk  r   r  r   r   r   r  r   rx  r  video_out_codecvideo_out_bitratevideo_out_frameraterl  audio_out_bitrate)rX   r   camera_enabledmicrophone_enableds       rD   r~  zDailyTransportClient._joinn  s    ||%%'55777[DLL<[<[!\\;;c@c@cNNKK*62 &4) $#'#5#5 '+&8&8&>&>&A&A%6,%	 &8) $#'#9#9 '+&<&<&B&B&E&E%:,%	#0 '(%) $(<<#?#? "24<<3O3O P%') ( %26,,2P2P48LL4T4T("*)" '#||>>!C .6!''+||'E'E	)##/1	 	 6	
p ||s   GGGGc                   K   | xj                   dz  c_         | j                  r| j                   dkD  ryd| _        | j                  j                          t	        j
                  d| j                          | j                  j                          d{    | j                  j                         D ]  \  }}| j                  |       d{      | j                  j                         D ]  \  }}| j                  |       d{      | j                          d{   }|sEt	        j
                  d| j                          | j                  j                          d{    yd| j                   d| }t	        j                   |       | j                  j#                  |       d{    y7 %7 7 7 7 Y7 w)	z+Leave the Daily room and cleanup resources.rz   r   NFzLeaving zLeft zError leaving rz  )r  r  r  clearr   r{  r   r   r   r  itemsremove_custom_audio_trackr  remove_custom_video_track_leaver   r  r   )rX   
track_name_r  r  s        rD   leavezDailyTransportClient.leave  s     	q  ||t22Q6  "ht~~./0 oo--/// "66<<> 	=MJ00<<<	=!66<<> 	=MJ00<<<	= kkm#KK%/01//))+++((85'BILL#//**9555 	0 =<# , 6sn   BGF98GF<:GF>	G"G #AG(G)A
G3G4G<G>G GGGc                    K   | j                   sy| j                         j                         }| j                   j                  t	        |             | d{   S 7 w)z(Execute the actual room leave operation.Nr!  )r
  r%  r&  r  r   rX   r   s     rD   r  zDailyTransportClient._leave  sL     ||%%'557&9&&AB||   AAAAc                 `    | j                   r"| j                   j                          d| _         yy)z"Cleanup the Daily client instance.N)r
  releaser   s    rD   rZ  zDailyTransportClient._cleanup  s%    <<LL  "DL rC   c                 6    | j                   j                         S zGet current participants in the room.

        Returns:
            Dictionary of participants keyed by participant ID.
        r
  rv  r   s    rD   rv  z!DailyTransportClient.participants       ||((**rC   c                 6    | j                   j                         S ztGet participant count information.

        Returns:
            Dictionary with participant count details.
        r
  participant_countsr   s    rD   r  z'DailyTransportClient.participant_counts       ||..00rC   c                    K   | j                         j                         }| j                  j                  |t	        |             | d{   S 7 w)Start a dial-out call to a phone number.

        Args:
            settings: Dial-out configuration settings.

        Returns:
            session_id: Dail-out session ID.
            error: An error description or None.
        r!  N)r%  r&  r
  start_dialoutr   rX   rk   r   s      rD   r  z"DailyTransportClient.start_dialout  sF      %%'557""88KF8S"T||   A
AAAc                    K   | j                         j                         }| j                  j                  |t	        |             | d{   S 7 w)Stop a dial-out call for a specific participant.

        Args:
            participant_id: ID of the participant to stop dial-out for.

        Returns:
            error: An error description or None.
        r!  N)r%  r&  r
  stop_dialoutr   )rX   r:   r   s      rD   r  z!DailyTransportClient.stop_dialout  sG      %%'557!!.=PQW=X!Y||r  c                    K   |j                  d      xs | j                  }|sy||d<   | j                         j                         }| j                  j                  |t        |             | d{   S 7 w)zSend DTMF tones during a call.

        Args:
            settings: DTMF settings including tones and target session.

        Returns:
            error: An error description or None.
        	sessionIdz)Can't send DTMF if 'sessionId' is not setr!  N)r8  r  r%  r&  r
  	send_dtmfr   rX   rk   
session_idr   s       rD   r  zDailyTransportClient.send_dtmf  sq      \\+.K$2K2K
> !+%%'557x4G4OP||s   A1A:3A84A:c                   K   |j                  d      xs | j                  xs | j                  }|sy||d<   | j                         j	                         }| j
                  j                  |t        |             | d{   S 7 w)Transfer a SIP call to another destination.

        Args:
            settings: SIP call transfer settings.

        Returns:
            error: An error description or None.
        r  z1Can't transfer SIP call if 'sessionId' is not setr!  N)r8  r  r  r%  r&  r
  sip_call_transferr   r  s       rD   r  z&DailyTransportClient.sip_call_transfer   s      LL%^)B)B^dF^F^ 	 F !+%%'557&&x<OPV<W&X||s   A?BBBc                    K   | j                         j                         }| j                  j                  |t	        |             | d{   S 7 w)Send a SIP REFER request.

        Args:
            settings: SIP REFER settings.

        Returns:
            error: An error description or None.
        r!  N)r%  r&  r
  	sip_referr   r  s      rD   r  zDailyTransportClient.sip_refer6  sF      %%'557x4G4OP||r  c                    K   | j                         j                         }| j                  j                  |||t	        |             | d{   S 7 w)}  Start recording the call.

        Args:
            streaming_settings: Recording configuration settings.
            stream_id: Unique identifier for the recording stream.
            force_new: Whether to force a new recording session.

        Returns:
            stream_id: Unique identifier for the recording stream.
            error: An error description or None.
        r!  N)r%  r&  r
  start_recordingr   )rX   streaming_settings	stream_id	force_newr   s        rD   r  z$DailyTransportClient.start_recordingC  sR      %%'557$$	9ATU[A\ 	% 	
 ||s   AAAAc                    K   | j                         j                         }| j                  j                  |t	        |             | d{   S 7 w)Stop recording the call.

        Args:
            stream_id: Unique identifier for the recording stream to stop.

        Returns:
            error: An error description or None.
        r!  N)r%  r&  r
  stop_recordingr   )rX   r  r   s      rD   r  z#DailyTransportClient.stop_recordingW  sF      %%'557##I:Mf:U#V||r  c                    K   | j                   sy| j                         j                         }| j                  j	                  |t        |             | d{   S 7 w)Start transcription for the call.

        Args:
            settings: Transcription configuration settings.

        Returns:
            error: An error description or None.
        z3Transcription can't be started without a room token)rk   r"  N)r   r%  r&  r
  start_transcriptionr   r  s      rD   r  z(DailyTransportClient.start_transcriptiond  sQ      {{H%%'557(((GZ[aGb(c||s   AA AA c                    K   | j                   sy| j                         j                         }| j                  j	                  t        |             | d{   S 7 w)lStop transcription for the call.

        Returns:
            error: An error description or None.
        z3Transcription can't be stopped without a room tokenr!  N)r   r%  r&  r
  stop_transcriptionr   r  s     rD   r  z'DailyTransportClient.stop_transcriptiont  sN      {{H%%'557''3Fv3N'O||r  r(  	user_namec                    K   | j                   sy| j                         j                         }| j                  j	                  ||t        |             | d{   S 7 w)  Send a chat message to Daily's Prebuilt main room.

        Args:
            message: The chat message to send.
            user_name: Optional user name that will appear as sender of the message.

        Returns:
            error: An error description or None.
        z Can't send message if not joined)r  r"  N)r  r%  r&  r
  send_prebuilt_chat_messager   )rX   r(  r  r   s       rD   r  z/DailyTransportClient.send_prebuilt_chat_message  sY      ||5%%'557//y5H5P 	0 	
 ||s   AA!AA!r:   c                    K   | j                   j                  sy| j                  j                  |       | j                  r1| j
                  r$| j                  | j                         d{    yyy7 wzEnable transcription capture for a specific participant.

        Args:
            participant_id: ID of the participant to capture transcription for.
        N)r   r   r   r#  r  r   update_transcriptionrX   r:   s     rD   !capture_participant_transcriptionz6DailyTransportClient.capture_participant_transcription  s_      ||11&&~6<<D66++D,C,CDDD 7<Ds   A)A5+A3,A5callbackrI  rw   callback_interval_msc                 6  K   |dv rd|dii}ndd|diii}| j                  ||i       d{    || j                  j                  |i       |<   t        j                  d| d|        | j
                  j                  || j                  |||	       y7 iw)
a  Capture audio from a specific participant.

        Args:
            participant_id: ID of the participant to capture audio from.
            callback: Callback function to handle audio data.
            audio_source: Audio source to capture (microphone, screenAudio, or custom).
            sample_rate: Desired sample rate for audio capture.
            callback_interval_ms: Interval between audio callbacks in milliseconds.
        )r  screenAudiomedia
subscribedr6  participant_settingsNStarting to capture [z] audio from participant )rI  rw   r  )update_subscriptionsr   
setdefaultr   r   r
  set_audio_renderer_audio_data_received)rX   r:   r  rI  rw   r  r  s          rD   capture_participant_audioz.DailyTransportClient.capture_participant_audio  s     $ 88|\:;E}|\.JKLE''ne=T'UUUMU((<\J#L>1J>JZ[	
 	''%%%#!5 	( 	
 	Vs   +BBA*B	frameraterN  r   c                 4  K   |dv rd|dii}ndd|diii}| j                  ||i       d{    || j                  j                  |i       |<   t        j                  d| d|        | j
                  j                  || j                  ||	       y7 hw)
a  Capture video from a specific participant.

        Args:
            participant_id: ID of the participant to capture video from.
            callback: Callback function to handle video frames.
            framerate: Desired framerate for video capture.
            video_source: Video source to capture (camera, screenVideo, or custom).
            color_format: Color format for video frames.
        rs  r  r  rA  r  Nr  z] video from participant )rN  r   )r  r   r  r   r   r
  set_video_renderer_video_frame_received)rX   r:   r  r  rN  r   r  s          rD   capture_participant_videoz.DailyTransportClient.capture_participant_video  s     $ 44|\:;E}|\.JKLE''ne=T'UUUMU((<\J#L>1J>JZ[	
 	''&&%%	 	( 	
 	Vs   +BBA)Br  c                 f  K   | j                         j                         }|r|j                  r|j                  n| j                  }|r|j                  nd}t        ||      }t        |      }| j                  j                  ||dt        |             | d{    t        ||      }|S 7 w)a(  Add a custom audio track for multi-stream output.

        Args:
            track_name: Name for the custom audio track.
            params: Optional per-track configuration for sample rate, channels, and sendSettings.

        Returns:
            The created DailyAudioTrack instance.
        rz   T)r  rn  ignore_audio_levelr"  Nr^  )r%  r&  rw   r  r|   r/   r0   r
  r9  r   r   )	rX   r  rx   r   rw   r|   rI  rn  r   s	            rD   r9  z+DailyTransportClient.add_custom_audio_track  s      %%'557,2v7I7If((tOdOd&,6??!(h?&|4++!##*62	 	, 	
 |;G	 	s   BB1B/B1c                    K   | j                         j                         }| j                  j                  |t	        |             | d{   S 7 w)zRemove a custom audio track.

        Args:
            track_name: Name of the custom audio track to remove.

        Returns:
            error: An error description or None.
        r  r"  N)r%  r&  r
  r  r   rX   r  r   s      rD   r  z.DailyTransportClient.remove_custom_audio_track  M      %%'557..!*62 	/ 	
 ||r  c                   K   | j                         j                         }|r|j                  n| j                  j                  }|r|j
                  n| j                  j                  }|r|j                  n| j                  j                  }t        |||      }t        |      }| j                  j                  ||t        |             | d{    t        ||      S 7 w)a+  Add a custom video track for multi-stream output.

        Args:
            track_name: Name for the custom video track.
            params: Optional per-track configuration for dimensions, color format, and sendSettings.

        Returns:
            The created DailyVideoTrack instance.
        )r  rm  r"  Nr^  )r%  r&  r   r   rh  r   ri  r   rj  r1   r2   r
  rB  r   r   )	rX   r  rx   r   r   r   r   rN  rm  s	            rD   rB  z+DailyTransportClient.add_custom_video_track$  s      %%'557 &DLL,H,H"(dll.K.K.4v**$,,:]:](E&|4++!#*62 	, 	
 l+FF 	s   CC%C#C%c                    K   | j                         j                         }| j                  j                  |t	        |             | d{   S 7 w)zRemove a custom video track.

        Args:
            track_name: Name of the custom video track to remove.

        Returns:
            error: An error description or None.
        r  N)r%  r&  r
  r  r   r  s      rD   r  z.DailyTransportClient.remove_custom_video_trackF  r  r  c                    K   | j                         j                         }| j                  j                  ||t	        |             | d{   S 7 w)a  Update transcription settings for specific participants.

        Args:
            participants: List of participant IDs to enable transcription for.
            instance_id: Optional transcription instance ID.

        Returns:
            error: An error description or None.
        r!  N)r%  r&  r
  r  r   )rX   rv  instance_idr   s       rD   r  z)DailyTransportClient.update_transcriptionV  sO      %%'557))+2Ef2M 	* 	
 ||   AAAAc                    K   | j                         j                         }| j                  j                  ||t	        |             | d{   S 7 w)  Update media subscription settings.

        Args:
            participant_settings: Per-participant subscription settings.
            profile_settings: Global subscription profile settings.

        Returns:
            error: An error description or None.
        )r  profile_settingsr"  N)r%  r&  r
  r  r   )rX   r  r  r   s       rD   r  z)DailyTransportClient.update_subscriptionsh  sP      %%'557))!5-*62 	* 	

 ||r  publishing_settingsc                    K   | j                         j                         }| j                  j                  |t	        |             | d{   S 7 w)Update media publishing settings.

        Args:
            publishing_settings: Publishing configuration settings.

        Returns:
            error: An error description or None.
        )r  r"  N)r%  r&  r
  r:  r   )rX   r  r   s      rD   r:  z&DailyTransportClient.update_publishing|  sM      %%'557&& 3*62 	' 	
 ||r  rs   c                    K   | j                         j                         }| j                  j                  |t	        |             | d{   S 7 w)Update settings for remote participants.

        Args:
            remote_participants: Remote participant configuration settings.

        Returns:
            error: An error description or None.
        )rs   r"  N)r%  r&  r
  update_remote_participantsr   )rX   rs   r   s      rD   r  z/DailyTransportClient.update_remote_participants  sN      %%'557// 3@STZ@[ 	0 	
 ||r  c                 P    | j                  | j                  j                  |       y)z~Handle active speaker change events.

        Args:
            participant: The new active speaker participant info.
        N)_call_event_callbackr   r   rX   participants     rD   r   z.DailyTransportClient.on_active_speaker_changed  s     	!!$//"K"K[YrC   senderc                 R    | j                  | j                  j                  ||       y)zHandle application message events.

        Args:
            message: The received message data.
            sender: ID of the message sender.
        N)r  r   r   rX   r(  r	  s      rD   r   z#DailyTransportClient.on_app_message  s      	!!$//"@"@'6RrC   statec                 P    | j                  | j                  j                  |       y)z_Handle call state update events.

        Args:
            state: The new call state.
        N)r  r   r   rX   r  s     rD   r   z*DailyTransportClient.on_call_state_updated  s     	!!$//"G"GOrC   r  c                 p    d|v r|d   nd| _         | j                  | j                  j                  |       y)zcHandle dial-in connected events.

        Args:
            data: Dial-in connection data.
        r  r   N)r  r  r   r   rX   r  s     rD   r   z(DailyTransportClient.on_dialin_connected  s6     9Dt8K4#4QS !!$//"E"EtLrC   sip_endpointc                 P    | j                  | j                  j                  |       y)zlHandle dial-in ready events.

        Args:
            sip_endpoint: The SIP endpoint for dial-in.
        N)r  r   r   rX   r  s     rD   r   z$DailyTransportClient.on_dialin_ready  s     	!!$//"A"A<PrC   c                     |j                  d      | j                  k(  rd| _        | j                  | j                  j                  |       y)z[Handle dial-in stopped events.

        Args:
            data: Dial-in stop data.
        r  r   N)r8  r  r  r   r   r  s     rD   r   z&DailyTransportClient.on_dialin_stopped  s=     88K D$<$<<')D$!!$//"C"CTJrC   c                     |j                  d      | j                  k(  rd| _        | j                  | j                  j                  |       y)zZHandle dial-in error events.

        Args:
            data: Dial-in error data.
        r  r   N)r8  r  r  r   r   r  s     rD   r   z$DailyTransportClient.on_dialin_error  s=     88K D$<$<<')D$!!$//"A"A4HrC   c                 P    | j                  | j                  j                  |       y)z^Handle dial-in warning events.

        Args:
            data: Dial-in warning data.
        N)r  r   r   r  s     rD   r   z&DailyTransportClient.on_dialin_warning  s     	!!$//"C"CTJrC   c                 P    | j                  | j                  j                  |       y)zbHandle dial-out answered events.

        Args:
            data: Dial-out answered data.
        N)r  r   r   r  s     rD   r   z(DailyTransportClient.on_dialout_answered  s     	!!$//"E"EtLrC   c                 p    d|v r|d   nd| _         | j                  | j                  j                  |       y)zeHandle dial-out connected events.

        Args:
            data: Dial-out connection data.
        r  r   N)r  r  r   r   r  s     rD   r   z)DailyTransportClient.on_dialout_connected  s6     :E9LD$5RT!!!$//"F"FMrC   c                     |j                  d      | j                  k(  rd| _        | j                  | j                  j                  |       y)z]Handle dial-out stopped events.

        Args:
            data: Dial-out stop data.
        r  r   N)r8  r  r  r   r   r  s     rD   r   z'DailyTransportClient.on_dialout_stopped  s=     88K D$=$==(*D%!!$//"D"DdKrC   c                     |j                  d      | j                  k(  rd| _        | j                  | j                  j                  |       y)z\Handle dial-out error events.

        Args:
            data: Dial-out error data.
        r  r   N)r8  r  r  r   r   r  s     rD   r   z%DailyTransportClient.on_dialout_error  s=     88K D$=$==(*D%!!$//"B"BDIrC   c                 P    | j                  | j                  j                  |       y)z`Handle dial-out warning events.

        Args:
            data: Dial-out warning data.
        N)r  r   r   r  s     rD   r   z'DailyTransportClient.on_dialout_warning  s     	!!$//"D"DdKrC   c                 P    | j                  | j                  j                  |       y)zoHandle participant joined events.

        Args:
            participant: The participant that joined.
        N)r  r   r   r  s     rD   r   z*DailyTransportClient.on_participant_joined  s     	!!$//"G"GUrC   c                 R    | j                  | j                  j                  ||       y)zHandle participant left events.

        Args:
            participant: The participant that left.
            reason: Reason for leaving.
        N)r  r   r   )rX   r  reasons      rD   r   z(DailyTransportClient.on_participant_left#  s!     	!!$//"E"E{TZ[rC   c                 P    | j                  | j                  j                  |       y)zqHandle participant updated events.

        Args:
            participant: The updated participant info.
        N)r  r   r   r  s     rD   r   z+DailyTransportClient.on_participant_updated,  s     	!!$//"H"H+VrC   c                     t        j                  d|        || _        | j                  | j                  | j
                         y)zlHandle transcription started events.

        Args:
            status: Transcription start status.
        zTranscription started: N)r   r   r   r  r  r   rX   statuss     rD   on_transcription_startedz-DailyTransportClient.on_transcription_started4  s<     	.vh78%+"!!$";";T=T=TUrC   c                 |    t        j                  d       | j                  | j                  j                  ||       y)zHandle transcription stopped events.

        Args:
            stopped_by: Who stopped the transcription.
            stopped_by_error: Whether stopped due to error.
        zTranscription stoppedN)r   r   r  r   r   rX   
stopped_bystopped_by_errors      rD   r   z-DailyTransportClient.on_transcription_stopped>  s1     	,-!!OO44jBR	
rC   c                 P    | j                  | j                  j                  |       y)z^Handle transcription error events.

        Args:
            message: Error message.
        N)r  r   r   rX   r(  s     rD   r   z+DailyTransportClient.on_transcription_errorJ  s     	!!$//"H"H'RrC   c                 P    | j                  | j                  j                  |       y)zqHandle transcription message events.

        Args:
            message: The transcription message data.
        N)r  r   r   r)  s     rD   r   z-DailyTransportClient.on_transcription_messageR  s     	!!$//"J"JGTrC   c                     t        j                  d|        | j                  | j                  j                  |       y)zdHandle recording started events.

        Args:
            status: Recording start status.
        zRecording started: N)r   r   r  r   r   r!  s     rD   r   z)DailyTransportClient.on_recording_startedZ  s2     	*6(34!!$//"F"FOrC   c                     t        j                  d|        | j                  | j                  j                  |       y)zsHandle recording stopped events.

        Args:
            stream_id: ID of the stopped recording stream.
        zRecording stopped: N)r   r   r  r   r   rX   r  s     rD   r   z)DailyTransportClient.on_recording_stoppedc  s2     	*9+67!!$//"F"F	RrC   c                     t        j                  d| d|        | j                  | j                  j                  ||       y)zHandle recording error events.

        Args:
            stream_id: ID of the recording stream with error.
            message: Error message.
        zRecording error for rz  N)r   r  r  r   r   rX   r  r(  s      rD   r   z'DailyTransportClient.on_recording_errorl  s;     	+I;b	BC!!$//"D"DiQXYrC   
audio_datac                 P    | j                   |   |   }| j                  ||||       y)z-Handle received audio data from participants.N)r   _call_audio_callback)rX   r:   r0  rI  r  s        rD   r  z)DailyTransportClient._audio_data_receivedz  s+    ((8F!!(NJUrC   video_framec                 P    | j                   |   |   }| j                  ||||       y)z/Handle received video frames from participants.N)r   _call_video_callback)rX   r:   r3  rN  r  s        rD   r  z*DailyTransportClient._video_frame_received  s-     ((8F!!(NKVrC   c                 @     | j                   | j                  |g|  y)z,Queue an audio callback for async execution.N)_call_async_callbackrb  rX   r  r   s      rD   r2  z)DailyTransportClient._call_audio_callback      !!!$"3"3XEErC   c                 @     | j                   | j                  |g|  y)z+Queue a video callback for async execution.N)r7  rf  r8  s      rD   r5  z)DailyTransportClient._call_video_callback  r9  rC   c                 @     | j                   | j                  |g|  y)z,Queue an event callback for async execution.N)r7  rT  r8  s      rD   r  z)DailyTransportClient._call_event_callback  r9  rC   queuec                     	 t        j                  |j                  |g|      | j                               }|j	                          y# t
        $ r Y yw xY w)z7Queue a callback for async execution on the event loop.N)r   run_coroutine_threadsafeputr%  resultFuturesCancelledError)rX   r<  r  r   r   s        rD   r7  z)DailyTransportClient._call_async_callback  sS    	55		8+d+,d.B.B.DF MMO$ 		s   AA
 
	AAc                    K   	 | j                   j                          d{    |j                          d{   ^}} ||  d{    |j                          Z7 <7 &7 w)z1Handle queued callbacks from the specified queue.N)r  waitr8  	task_done)rX   r<  r  r   s       rD   rV  z+DailyTransportClient._callback_task_handler  s[     $$))+++&+iik 1XD/!!OO + 1!s1   A$AA$A A$A"	A$ A$"A$c                    K   | j                   D ]  }| j                  |       d{     | j                   j                          y7 !w)z9Send any messages that were queued before join completed.N)r  r)  r  rX   r  s     rD   r  z)DailyTransportClient._flush_join_messages  sF     -- 	+E##E***	+  &&( +s   $A
A"A
c                 j    | j                   st        |  d      | j                   j                         S )z)Get the event loop from the task manager.z.: missing task manager (pipeline not started?))r  	Exceptionget_event_loopr   s    rD   r%  z$DailyTransportClient._get_event_loop  s3    !!tf$RSTT!!0022rC   c                      | j                    dS )z2String representation of the DailyTransportClient.z::DailyTransportClient)r   r   s    rD   __str__zDailyTransportClient.__str__  s    &&''=>>rC   N)r  >        rt  r   NN)pr<   r=   r>   r?   r   r   rA   r   r@   r   r   r   r}   r  propertyr   r:   r   r  r  r   r   CallClientErrorr)  r   r2  r=  rC  r   rJ  r   rO  r&   rP  r[  r    ro  r  r~  r  r  rZ  r   r   rv  r  r   r  r  r  r  r  r  r  r  r  r  r  r	   r  r  r   r   r9  r  r   r   rB  r  r  r  r:  r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r#  r   r   r   r   r   r   r-   r  r5   r  r2  r5  r  r   rS  r7  rV  r  AbstractEventLoopr%  rK  r\   r]   s   @rD   r   r     s     %$$KCKC }KC 	KC
 KC "KC KCZ! #   $ $ $ $ $ $ % % %03TT	/	"6X6H-I 03C 33C 3-@ T 8-@ T 0
!4 
"T+] +]Z*"XBH6@ +gc3h/ +1GCH$5 1uS(?:S5S/T H_4M 8O+D (8O3L ,8O+D 	sH_--	.(/1J Xo5N  (?*C  8<'/}	/	"*Ec E" ) $&%
%
 %
 	%

 %
 "%
V $!$
$
 $
 	$

 $
 $
R 9="" 45" 
	"H# (?B[ & 9= G G 45 G 
	 GD# (?B[ " .2	/	"& ;?	/	"(#*38#4	/	"$#*38#4	/	",ZSc S3 SP3 PM MQC Q	Kc 	K	IC 	IKc KM MN N	Ls 	L	JS 	JLs LV\WV

SUPSZV3 VI V]` V
W!W0:WJMWFFF'-- '-- )3!:!: 3?rC   r   c            	       F    e Zd ZdZdededef fdZede	e
   fd       Zd Zd	ef fd
Z fdZdef fdZdef fdZdef fdZdedef fdZdeez  fdZdedefdZ	 	 d$dededefdZ dede!defdZ"d Z#	 	 	 d%dedededefd Z$de%fd!Z&ded"e'defd#Z( xZ)S )&DailyInputTransportzHandles incoming media streams and events from Daily calls.

    Processes incoming audio, video, transcriptions and other events from Daily
    room participants, including participant media capture and event forwarding.
    	transportclientrx   c                     t        |   |fi | || _        || _        || _        i | _        d| _        d| _        g | _        d| _	        |j                  | _        y)a  Initialize the Daily input transport.

        Args:
            transport: The parent transport instance.
            client: DailyTransportClient instance.
            params: Configuration parameters.
            **kwargs: Additional arguments passed to parent class.
        FN)rP   r}   
_transportr
  r   r   _initialized_streaming_started_capture_participant_audio_audio_in_taskvad_analyzer_vad_analyzerrX   rW  rX  rx   r   rY   s        rD   r}   zDailyInputTransport.__init__  sj     	*6*# " " #( +-' 7;4:4G4GrC   r   c                     | j                   S )zzGet the Voice Activity Detection analyzer.

        Returns:
            The VAD analyzer instance if configured.
        )r`  r   s    rD   r_  z DailyInputTransport.vad_analyzer  s     !!!rC   c                   K   | j                   j                  syt        j                  d       | j                   j                  r| j                   j                  rM| j
                  D ]6  \  }}}| j                  j                  || j                  ||       d{    8 d| _        y| j                  s$| j                  | j                               | _	        d| _        y7 Fw)z(Start receiving audio from participants.NzStart receiving audioT)r   ra  r   r   r   r]  r
  r  _on_participant_audio_datar^  rU  _audio_in_task_handlerr\  rX   r:   rI  rw   s       rD   start_audio_in_streamingz,DailyInputTransport.start_audio_in_streaming  s     ||,,,.<<((||00AEA`A` =NL+,,@@&(G(GWb   #' (( '+&6&6t7R7R7T&U#"&s   BC"C AC"rP  c                    K   t         |   |       d{    | j                  j                  |       d{    y7 (7 w)zSetup the input transport with shared client setup.

        Args:
            setup: The frame processor setup configuration.
        NrP   rP  r
  rX   rP  rY   s     rD   rP  zDailyInputTransport.setup  <      gmE"""ll  ''' 	#'   A?"AAAAc                    K   t         |           d{    | j                  j                          d{    | j                  j                          d{    y7 I7 )7 	w)z-Cleanup input transport and shared resources.NrP   r[  r
  rZ  rX   rY   s    rD   r[  zDailyInputTransport.cleanup  P     goll""$$$oo%%''' 	 $'1   A%A!A%A!!A%A#A%!A%#A%r  c                   K   t         |   |       d{    | j                  ryd| _        | j                  j                  |       d{    | j                  j	                          d{    | j                  |       d{    | j                  j                  r| j                          d{    yy7 7 q7 Q7 :7 w)zStart the input transport and join the Daily room.

        Args:
            frame: The start frame containing initialization parameters.
        NT)	rP   ro  r[  r
  r  set_transport_readyr   audio_in_stream_on_startrg  rX   r  rY   s     rD   ro  zDailyInputTransport.start  s      gmE"""  ll  ''' ll!!! &&u---<<00//111 1! 	# 	( 	" 	. 2sW   CB=6CB?!C/C0CC	-C6C7C?CCCCc                    K   t         |   |       d{    | j                  j                          d{    | j                  r+| j                  | j                         d{    d| _        yy7 ^7 >7 w)zStop the input transport and leave the Daily room.

        Args:
            frame: The end frame signaling transport shutdown.
        N)rP   stopr
  r  r^  rX  ru  s     rD   rw  zDailyInputTransport.stop.  sp      gl5!!!ll  """""4#6#6777"&D 	 	"" 81   A;A5!A;A7.A;'A9(A;7A;9A;c                    K   t         |   |       d{    | j                  j                          d{    | j                  r+| j                  | j                         d{    d| _        yy7 ^7 >7 w)zCancel the input transport and leave the Daily room.

        Args:
            frame: The cancel frame signaling immediate cancellation.
        N)rP   cancelr
  r  r^  rX  ru  s     rD   rz  zDailyInputTransport.cancel=  sp      gnU###ll  """""4#6#6777"&D 	 	$" 8rx  	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)rP   process_framer$  r$   request_participant_image)rX   r  r{  rY   s      rD   r}  z!DailyInputTransport.process_frameP  sM      g#E9555e2300777 4 	6 8s!   AA(A A	A	Ac                 B   K   | j                  |       d{    y7 w)zrPush a transcription frame downstream.

        Args:
            frame: The transcription frame to push.
        N)
push_framerF  s     rD   push_transcription_framez,DailyInputTransport.push_transcription_frame`  s      ooe$$$   r(  r	  c                 P   K   | j                  t        ||       d{    y7 w)zPush an application message as an urgent transport frame.

        Args:
            message: The message data to send.
            sender: ID of the message sender.
        )r(  r:   N)broadcast_framerc   r  s      rD   push_app_messagez$DailyInputTransport.push_app_messageh  s,      ""+WV # 
 	
 	
s   &$&r:   rI  rw   c                    K   | j                   r1| j                  j                  || j                  ||       d{    y| j                  j                  |||f       y7 $wa  Capture audio from a specific participant.

        Args:
            participant_id: ID of the participant to capture audio from.
            audio_source: Audio source to capture from.
            sample_rate: Desired sample rate for audio capture.
        N)r\  r
  r  rd  r]  r#  rf  s       rD   r  z-DailyInputTransport.capture_participant_audiow  s_      "",,88 ? ?{   ++22NLR]3^_	s   8A!A%A!r,  c                    K   t        ||j                  |j                  |j                        }||_        | j                  |       d{    y7 w)z'Handle received participant audio data.)user_idr,  rw   r-  N)r"   audio_framesrw   r-  transport_sourcepush_audio_frame)rX   r:   r,  rI  r  s        rD   rd  z.DailyInputTransport._on_participant_audio_data  sN      ""$$))++	
 ".##E***s   A	AAAc                    K   	 | j                   j                          d {   }|r| j                  |       d {    >7  7 wrL  )r
  r2  r  rF  s     rD   re  z*DailyInputTransport._audio_in_task_handler  sA     ,,<<>>E++E222 >2s   AAAAAAr  rN  r   c                    K   || j                   vri | j                   |<   |dg d| j                   |   |<   | j                  j                  || j                  |||       d{    y7 w)8  Capture video from a specific participant.

        Args:
            participant_id: ID of the participant to capture video from.
            framerate: Desired framerate for video capture.
            video_source: Video source to capture from.
            color_format: Color format for video frames.
        r   )r  	timestamprender_next_frameN)r   r
  r  _on_participant_video_framerX   r:   r  rN  r   s        rD   r  z-DailyInputTransport.capture_participant_video  sx      !6!6646D!!.1 #!#?
n-l; ll44D<<iWc
 	
 	
s   A A*"A(#A*c                    K   |j                   | j                  v rI|j                  r|j                  nd}| j                  |j                      |   d   j                  |       yyw)z{Request a video frame from a specific participant.

        Args:
            frame: The user image request frame.
        rt  r  N)r  r   rN  r#  )rX   r  rN  s      rD   r~  z-DailyInputTransport.request_participant_image  s]      ==D111161C1C5--L!!%--0>?RSZZ[`a 2s   A#A%r3  c           	      T  K   d}t        j                          }| j                  |   |   d   }| j                  |   |   d   }d}|dkD  r|d|z  z   }	|	|z
  dk  }| j                  |   |   d   r&| j                  |   |   d   j                  d      }d	}|rt        ||j                  |j
                  |j                  f|j                  |r|j                  nd|r|j                  nd|
      }
||
_
        | j                  |
       d{    || j                  |   |   d<   yy7 w)z)Handle received participant video frames.Fr  r  Nr   rz   g?r  T)r  rM  sizeformattextappend_to_contextrequest)timer   popr#   r   r   r   r   r  r  r  push_video_frame)rX   r:   r3  rN  render_frame	curr_time	prev_timer  request_frame	next_timer  s              rD   r  z/DailyInputTransport._on_participant_video_frame  sV     IIK	)).9,GT	)).9,GT	 q=!A	M1I%	1S8L  0>?RS 11.A,O#c!f   L%&!((!''););<"//+8]''dER-"A"AX\%E &2E"''...OXD!!.1,?L  /s   DD(
D&D(r  rM  rO  )*r<   r=   r>   r?   r*   r   r   r}   rR  r   r   r_  rg  r&   rP  r[  r    ro  r   rw  r   rz  r   r%   r}  r!   r   r  r   r@   r  r   r  r-   rd  re  r  r$   r~  r5   r  r\   r]   s   @rD   rV  rV    sw   $H $H %$H 	$HL "h{3 " "'*(!4 ((2 24' ''+ '&
8 
8> 
8 %4FIb4b %	
c 	
3 	
$ ) 	`` ` 	`(+!+*3+CF+3 $!

 
 	

 
8b5J b#Y!#Y0:#YJM#YrC   rV  c                        e Zd ZdZdededef fdZdef fdZ	 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fdZdefdZd	edefdZd	edefdZd	efdZdefdZd Z xZ S )DailyOutputTransportzHandles outgoing media streams and events to Daily calls.

    Manages sending audio, video and other data to Daily calls,
    including audio destination registration and message transmission.
    rW  rX  rx   c                 P    t        |   |fi | || _        || _        d| _        y)a  Initialize the Daily output transport.

        Args:
            transport: The parent transport instance.
            client: DailyTransportClient instance.
            params: Configuration parameters.
            **kwargs: Additional arguments passed to parent class.
        FN)rP   r}   rZ  r
  r[  ra  s        rD   r}   zDailyOutputTransport.__init__  s/     	*6*# "rC   rP  c                    K   t         |   |       d{    | j                  j                  |       d{    y7 (7 w)zSetup the output transport with shared client setup.

        Args:
            setup: The frame processor setup configuration.
        Nri  rj  s     rD   rP  zDailyOutputTransport.setup  rk  rl  c                    K   t         |           d{    | j                  j                          d{    | j                  j                          d{    y7 I7 )7 	w)z.Cleanup output transport and shared resources.Nrn  ro  s    rD   r[  zDailyOutputTransport.cleanup  rp  rq  r  c                 0  K   t         |   |       d{    | j                  ryd| _        | j                  j                  |       d{    | j                  j	                          d{    | j                  |       d{    y7 w7 B7 "7 w)zStart the output transport and join the Daily room.

        Args:
            frame: The start frame containing initialization parameters.
        NT)rP   ro  r[  r
  r  rs  ru  s     rD   ro  zDailyOutputTransport.start  s      gmE"""  ll  ''' ll!!! &&u--- 	# 	( 	" 	.sE   BB6BB!B/B0BB	BBBBc                    K   t         |   |       d{    | j                  j                          d{    y7 '7 w)zStop the output transport and leave the Daily room.

        Args:
            frame: The end frame signaling transport shutdown.
        N)rP   rw  r
  r  ru  s     rD   rw  zDailyOutputTransport.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 leave the Daily room.

        Args:
            frame: The cancel frame signaling immediate cancellation.
        N)rP   rz  r
  r  ru  s     rD   rz  zDailyOutputTransport.cancel9  s:      gnU###ll  """ 	$"r  c                    K   | j                   j                  |       d{   }|r| j                  d|        d{    yy7 $7 w)zySend a transport message to participants.

        Args:
            frame: The transport message frame to send.
        NzUnable to send message: )r
  r)  
push_errorrX   r  r  s      rD   r)  z!DailyOutputTransport.send_messageD  sJ      ll//66//$<UG"DEEE  7Es    A
AA
A A
A
r3  c                 V   K   | j                   j                  |       d{    y7 w)z}Register a video output destination.

        Args:
            destination: The destination identifier to register.
        N)r
  rC  rX   r3  s     rD   rC  z/DailyOutputTransport.register_video_destinationP  s       ll55kBBB   )')c                 V   K   | j                   j                  |       d{    y7 w)zRegister an audio output destination.

        Args:
            destination: The destination identifier to register.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        N)r
  r=  r  s     rD   r=  z/DailyOutputTransport.register_audio_destinationX  s       ll55kBBBr  r   c                 T   K   | j                   j                  |       d{   S 7 w)zWrite an audio frame to the Daily call.

        Args:
            frame: The audio frame to write.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        N)r
  rJ  rF  s     rD   rJ  z&DailyOutputTransport.write_audio_framec  #      \\33E::::   (&(c                 T   K   | j                   j                  |       d{   S 7 w)zWrite a video frame to the Daily call.

        Args:
            frame: The video frame to write.

        Returns:
            True if the video frame was written successfully, False otherwise.
        N)r
  rO  rF  s     rD   rO  z&DailyOutputTransport.write_video_framen  r  r  c                 R  K   t        |t              rM| j                  j                  |j                         d{   }|r| j                  d|        d{    yyt        |t              rM| j                  j                  |j                         d{   }|r| j                  d|        d{    yyt        |t              rM| j                  j                  |j                         d{   }|r| j                  d|        d{    yyy7 7 7 7 j7 -7 w)z}Handle queued SIP frames after preceding audio has been sent.

        Args:
            frame: The frame to handle.
        NUnable to transfer SIP call: Unable to perform SIP REFER: &Unable to update remote participants: )r$  rh   r
  r  rk   r  rp   r  rr   r  rs   r  s      rD   write_transport_framez*DailyOutputTransport.write_transport_framey  s     e23,,88HHEoo(EeW&MNNN 12,,00@@Eoo(EeW&MNNN AB,,AA%B[B[\\Eoo(Nug&VWWW  C IN@N\Wsi   9D'DD'D>D'DD'6D!7>D'5D#6D'D%D'D'D'!D'#D'%D'c                      y)zDaily supports native DTMF via telephone events.

        Returns:
            True, as Daily supports native DTMF transmission.
        TrB   r   s    rD   _supports_native_dtmfz*DailyOutputTransport._supports_native_dtmf  s     rC   c                    K   | j                   j                  |j                  |j                  j                  d       d{    y7 w)z}Use Daily's native send_dtmf method for telephone events.

        Args:
            frame: The DTMF frame to write.
        )r  tonesN)r
  r  rF  buttonvaluerF  s     rD   _write_dtmf_nativez'DailyOutputTransport._write_dtmf_native  s?      ll$$"88++
 	
 	
s   A A
AA
)!r<   r=   r>   r?   r*   r   r   r}   r&   rP  r[  r    ro  r   rw  r   rz  r   r   r)  r@   rC  r=  r   r   rJ  r   rO  r   r  r  r  r\   r]   s   @rD   r  r    s    "&"0D"NY"&(!4 ((. ..	# 	#	#+ 	#
F03TT
FCC C	CC 	C	;-@ 	;T 	;	;-@ 	;T 	;X X&t 
rC   r  c                   N    e Zd ZdZ	 	 	 dPdedee   dedee   dee   dee   f fd	Zd
efdZ	d
e
fdZed
efd       Zed
efd       ZdefdZdeez  fdZdefdZd
eeef   fdZd
eeef   fdZdQd
eeee   f   fdZd
ee   fdZd
ee   fdZd
ee   fdZ	 dPd
eeee   f   fdZ dQd
ee   fdZ!dQd
ee   fdZ"d
ee   fdZ#	 dQdedee   d
ee   fd Z$d!efd"Z%	 	 dRd!ed#ed$e&fd%Z'	 	 	 dSd!ed&e&d'ed(efd)Z(d*eeef   d
ee   fd+Z)	 dTd
ee   fd,Z*d-eeef   d
ee   fd.Z+d/efd0Z,d1 Z-d2 Z.d3 Z/d4 Z0ded5efd6Z1d7efd8Z2d/efd9Z3d/efd:Z4d;efd<Z5d= Z6d> Z7d? Z8d@ Z9dA Z:dB Z;dC Z<dD Z=dE Z>dF Z?dG Z@dH ZAdI ZBdeeef   d
dfdJZCdK ZDdL ZEdM ZFdN ZGdO ZH xZIS )UDailyTransporta]  Transport implementation for Daily audio and video calls.

    Provides comprehensive Daily integration including audio/video streaming,
    transcription, recording, dial-in/out functionality, and real-time communication
    features for conversational AI applications.

    Event handlers available:

    - on_joined: Called when the bot joins the room. Args: (data: dict)
    - on_connected: Called when the bot connects to the room (alias for
      on_joined). Args: (data: dict)
    - on_left: Called when the bot leaves the room.
    - on_before_leave: [sync] Called just before the bot leaves the room.
    - on_error: Called when a transport error occurs. Args: (error: str)
    - on_call_state_updated: Called when the call state changes. Args: (state: str)
    - on_first_participant_joined: Called when the first participant joins.
      Args: (participant: dict)
    - on_participant_joined: Called when any participant joins.
      Args: (participant: dict)
    - on_participant_left: Called when a participant leaves.
      Args: (participant: dict, reason: str)
    - on_participant_updated: Called when a participant's state changes.
      Args: (participant: dict)
    - on_client_connected: Called when a participant connects (alias for
      on_participant_joined). Args: (participant: dict)
    - on_client_disconnected: Called when a participant disconnects (alias for
      on_participant_left). Args: (participant: dict)
    - on_active_speaker_changed: Called when the active speaker changes.
      Args: (participant: dict)
    - on_app_message: Called when an app message is received.
      Args: (message: Any, sender: str)
    - on_transcription_message: Called when a transcription message is received.
      Args: (message: dict)
    - on_recording_started: Called when recording starts. Args: (status: str)
    - on_recording_stopped: Called when recording stops. Args: (stream_id: str)
    - on_recording_error: Called when a recording error occurs.
      Args: (stream_id: str, message: str)
    - on_dialin_connected: Called when a dial-in call connects. Args: (data: dict)
    - on_dialin_ready: Called when the SIP endpoint is ready.
      Args: (sip_endpoint: str)
    - on_dialin_stopped: Called when a dial-in call stops. Args: (data: dict)
    - on_dialin_error: Called when a dial-in error occurs. Args: (data: dict)
    - on_dialin_warning: Called when a dial-in warning occurs. Args: (data: dict)
    - on_dialout_answered: Called when a dial-out call is answered. Args: (data: dict)
    - on_dialout_connected: Called when a dial-out call connects. Args: (data: dict)
    - on_dialout_stopped: Called when a dial-out call stops. Args: (data: dict)
    - on_dialout_error: Called when a dial-out error occurs. Args: (data: dict)
    - on_dialout_warning: Called when a dial-out warning occurs. Args: (data: dict)

    Example::

        @transport.event_handler("on_first_participant_joined")
        async def on_first_participant_joined(transport, participant):
            await task.queue_frame(TTSSpeakFrame("Hello!"))

        @transport.event_handler("on_participant_left")
        async def on_participant_left(transport, participant, reason):
            await task.queue_frame(EndFrame())

        @transport.event_handler("on_app_message")
        async def on_app_message(transport, message, sender):
            logger.info(f"Message from {sender}: {message}")
    Nr   r   r   rx   
input_nameoutput_namec                 p   t         |   ||       t        d$i d| j                  d| j                  d| j
                  d| j                  d| j                  d| j                  d| j                  d	| j                  d
| j                  d| j                  d| j                  d| j                  d| j                  d| j                   d| j"                  d| j$                  d| j&                  d| j(                  d| j*                  d| j,                  d| j.                  d| j0                  d| j2                  d| j4                  d| j6                  d| j8                  d| j:                  d| j<                  }|xs
 t?               | _         tC        |||| j@                  || jD                        | _#        d| _$        d| _%        d| _&        | jO                  d       | jO                  d        | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d	       | jO                  d
       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d!       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  d       | jO                  dd"#       y)%a  Initialize the Daily transport.

        Args:
            room_url: URL of the Daily room to connect to.
            token: Optional authentication token for the room.
            bot_name: Display name for the bot in the call.
            params: Configuration parameters for the transport.
            input_name: Optional name for the input transport.
            output_name: Optional name for the output transport.
        )r  r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   NFon_connectedon_first_participant_joinedT)syncrB   )(rP   r}   r   _on_active_speaker_changed
_on_joined_on_left_on_before_leave	_on_error_on_app_message_on_call_state_updated_on_client_connected_on_client_disconnected_on_dialin_connected_on_dialin_ready_on_dialin_stopped_on_dialin_error_on_dialin_warning_on_dialout_answered_on_dialout_connected_on_dialout_stopped_on_dialout_error_on_dialout_warning_on_participant_joined_on_participant_left_on_participant_updated_on_transcription_message_on_transcription_stopped_on_transcription_error_on_recording_started_on_recording_stopped_on_recording_errorr   r   r   namer
  _input_output_other_participant_has_joined_register_event_handler)	rX   r   r   r   rx   r  r  r   rY   s	           rD   r}   zDailyTransport.__init__  s   & 	JKH" 
&*&E&E
oo
 MM
 !11	

 ^^
  //
 #'"="=
 !% 9 9
 $(#?#?
 !% 9 9
 !11
 #55
 !11
 #55
 !% 9 9
  "&!;!;!
"  $77#
$ "33%
&  $77'
( #'"="=)
* !% 9 9+
, $(#?#?-
. &*%C%C/
0 &*%C%C1
2 $(#?#?3
4 "&!;!;5
6 "&!;!;7
8  $779
	< .+eXt||Y		
 6:7;-2* 	$$%@A$$^4$$[1$$Y/$$Z0$$%56$$%<=$$%:;$$%=>$$%:;$$%67$$%89$$%67$$%89$$%:;$$%;<$$%9:$$%78$$%9:$$%BC$$%<=$$%:;$$%=>$$%?@$$%;<$$%;<$$%9:$$%6T$BrC   r   c                     | j                   s2t        | | j                  | j                  | j                        | _         | j                   S )zGet the input transport for receiving media and events.

        Returns:
            The Daily input transport instance.
        r  )r  rV  r
  r   _input_namer   s    rD   inputzDailyTransport.inputC	  s:     {{-dllDLLt7G7GDK {{rC   c                     | j                   s2t        | | j                  | j                  | j                        | _         | j                   S )zGet the output transport for sending media and events.

        Returns:
            The Daily output transport instance.
        r  )r  r  r
  r   _output_namer   s    rD   outputzDailyTransport.outputO	  s:     ||/dllDLLt7H7HDL ||rC   c                 .    | j                   j                  S )zkGet the Daily room URL.

        Returns:
            The room URL this transport is connected to.
        )r
  r   r   s    rD   r   zDailyTransport.room_url_	  s     ||$$$rC   c                 .    | j                   j                  S )zwGet the participant ID for this transport.

        Returns:
            The participant ID assigned by Daily.
        )r
  r:   r   s    rD   r:   zDailyTransport.participant_idh	  s     ||***rC   levelc                 .    t        j                  |       y)a;  Set the logging level for Daily's internal logging system.

        Args:
            level: The log level to set. Should be a member of the DailyLogLevel enum,
                  such as DailyLogLevel.Info, DailyLogLevel.Debug, etc.

        Example:
            transport.set_log_level(DailyLogLevel.Info)
        N)r3   set_log_level)rX   r  s     rD   r  zDailyTransport.set_log_levelq	  s     	E"rC   r  c                    K   | j                   r3| j                   j                  |t        j                         d{    yy7 w)zjSend an image frame to the Daily call.

        Args:
            frame: The image frame to send.
        Nr  queue_framer%   
DOWNSTREAMrF  s     rD   
send_imagezDailyTransport.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)zjSend an audio frame to the Daily call.

        Args:
            frame: The audio frame to send.
        Nr  rF  s     rD   
send_audiozDailyTransport.send_audio	  r  r  c                 6    | j                   j                         S r  r  r   s    rD   rv  zDailyTransport.participants	  r  rC   c                 6    | j                   j                         S r  r  r   s    rD   r  z!DailyTransport.participant_counts	  r  rC   c                    K   t        j                  d|        | j                  j                  |       d{   \  }}|rt        j                  d|        ||fS 7 %w)r  zStarting dialout: settings=NzUnable to start dialout: )r   r   r
  r  r  )rX   rk   r  r  s       rD   r  zDailyTransport.start_dialout	  s`      	28*=>"&,,"<"<X"FF
ELL4UG<=5   Gs   7A!A&A!c                    K   t        j                  d|        | j                  j                  |       d{   }|rt        j                  d|        |S 7  w)r  z!Stopping dialout: participant_id=NzUnable to stop dialout: )r   r   r
  r  r  )rX   r:   r  s      rD   r  zDailyTransport.stop_dialout	  sV      	88HIJll//??LL3E7;< @   7AA!Ac                    K   t        j                  d|        | j                  j                  |       d{   }|rt        j                  d|        |S 7  w)r  z$Staring SIP call transfer: settings=Nr  )r   r   r
  r  r  rX   rk   r  s      rD   r  z DailyTransport.sip_call_transfer	  sT      	;H:FGll44X>>LL8@A ?r  c                    K   t        j                  d|        | j                  j                  |       d{   }|rt        j                  d|        |S 7  w)r  zStaring SIP REFER: settings=Nr  )r   r   r
  r  r  r  s      rD   r  zDailyTransport.sip_refer	  sT      	3H:>?ll,,X66LL8@A 7r  c                    K   t        j                  d| d| d|        | j                  j                  |||       d{   \  }}|rt        j                  d|        ||fS 7 %w)r  zStarting recording: stream_id=z force_new=z
 settings=NzUnable to start recording: )r   r   r
  r  r  )rX   r  r  r  r_idr  s         rD   r  zDailyTransport.start_recording	  sv      	,YK{9+ZXjWkl	
 !LL889KYXabbeLL6ug>?U{ cs   ?A)A'&A)c                    K   t        j                  d|        | j                  j                  |       d{   }|rt        j                  d|        |S 7  w)r  zStopping recording: stream_id=NzUnable to stop recording: )r   r   r
  r  r  )rX   r  r  s      rD   r  zDailyTransport.stop_recording	  sT      	5i[ABll11)<<LL5eW=> =r  c                    K   t        j                  d|        | j                  j                  |       d{   }|rt        j                  d|        |S 7  w)r  z!Starting transcription: settings=NUnable to start transcription: )r   r   r
  r  r  r  s      rD   r  z"DailyTransport.start_transcription
  sU      	8
CDll66x@@LL:5'BC Ar  c                    K   t        j                  d       | j                  j                          d{   }|rt        j                  d|        |S 7  w)r  zStopping transcriptionNUnable to stop transcription: )r   r   r
  r  r  rX   r  s     rD   r  z!DailyTransport.stop_transcription
  sK      	-/ll5577LL9%AB 8s   3AA!Ar(  r  c                    K   | j                   j                  ||       d{   }|rt        j                  d|        |S 7  w)r  Nz&Unable to send prebuilt chat message: )r
  r  r   r  )rX   r(  r  r  s       rD   r  z)DailyTransport.send_prebuilt_chat_message$
  sC      ll==gyQQLLA%IJ Rs    AA!Ar:   c                 V   K   | j                   j                  |       d{    y7 wr  )r
  r  r  s     rD   r  z0DailyTransport.capture_participant_transcription5
  s       ll<<^LLLr  rI  rw   c                 t   K   | j                   r&| j                   j                  |||       d{    yy7 wr  )r  r  rf  s       rD   r  z(DailyTransport.capture_participant_audio=
  s4      ;;++77Vabbb bs   -868r  rN  r   c                 v   K   | j                   r'| j                   j                  ||||       d{    yy7 w)r  N)r  r  r  s        rD   r  z(DailyTransport.capture_participant_videoM
  s>      ;;++77	<   s   .979r  c                    K   t        j                  d|        | j                  j                  |       d{   }|rt        j                  d|        |S 7  w)r  z'Updating publishing settings: settings=)r  Nz&Unable to update publishing settings: )r   r   r
  r:  r  )rX   r  r  s      rD   r:  z DailyTransport.update_publishinga
  s[      	>?R>STUll44I\4]]LLA%IJ ^   8AA!Ac                    K   t        j                  d| d|        | j                  j                  ||       d{   }|rt        j                  d|        |S 7  w)r  z-Updating subscriptions: participant_settings=z profile_settings=)r  r  Nz(Unable to update subscription settings: )r   r   r
  r  r  )rX   r  r  r  s       rD   r  z#DailyTransport.update_subscriptionss
  sr      	;<P;QQcdtcuv	
 ll77!5HX 8 
 
 LLCE7KL
s   <A!A!A!rs   c                    K   t        j                  d|        | j                  j                  |       d{   }|rt        j                  d|        |S 7  w)r  z2Updating remote participants: remote_participants=)rs   Nr  )r   r   r
  r  r  )rX   rs   r  s      rD   r  z)DailyTransport.update_remote_participants
  sb      	IJ]I^_`ll== 3 > 
 
 LLA%IJ
r  r  c                 D   K   | j                  d|       d{    y7 w)z$Handle active speaker change events.r   N_call_event_handlerr  s     rD   r  z)DailyTransport._on_active_speaker_changed
  s     &&'BKPPP     c                   K   | j                   j                  r]| j                   j                  j                  d      }| j	                  |       d{   }|r| j                  d|        d{    | j                  d|       d{    | j                  d|       d{    | j                  r,| j                  j                  t                      d{    yy7 7 s7 [7 C7 w)zHandle room joined events.T)exclude_noneNr  r   r  )
r   r   r   
model_dumpr  r  r  r  r  r   )rX   r  rk   r  s       rD   r  zDailyTransport._on_joined
  s     <<-- ||::EESWEXH228<<Enn'Fug%NOOO&&{D999&&~t<<<;;++(():)<===  =O9<=sZ   AC-C#C-1C%2C-C'C-%C)&6C-C+C-%C-'C-)C-+C-c                 B   K   | j                  d       d{    y7 w)zHandle room left events.r   Nr  r   s    rD   r  zDailyTransport._on_left
  s     &&y111r  c                    K   | j                   j                  r6| j                          d{   }|r| j                  d|        d{    | j	                  d       d{    y7 <7  7 	w)z Handle before leave room events.Nr  r   )r   r   r  r  r  r  s     rD   r  zDailyTransport._on_before_leave
  se     <<-- 1133Enn'EeW%MNNN&&'8999 4N9s3   *A/A)A/
A+A/#A-$A/+A/-A/c                 N  K   | j                  d|       d{    | j                  r%| j                  j                  |       d{    y| j                  r%| j                  j                  |       d{    yt	        j
                  d       t        d      7 7 X7 )w)z*Handle error events and push error frames.r   N)r  z9Both input and output are None while trying to push errorz.No valid input or output channel to push error)r  r  r  r  r   r  rH  r  s     rD   r  zDailyTransport._on_error
  s     &&z5999;;++((5(999\\,,))E):::LLTULMM 	:9:s3   B%B/B%B!	0B%9B#:&B%!B%#B%r	  c                    K   | j                   r$| j                   j                  ||       d{    | j                  d||       d{    y7  7 w)z"Handle application message events.Nr   )r  r  r  r  s      rD   r  zDailyTransport._on_app_message
  sJ     ;;++..w???&&'7&III @Is!   ,AAA	A
AAr  c                 D   K   | j                  d|       d{    y7 w)z Handle call state update events.r   Nr  r  s     rD   r  z%DailyTransport._on_call_state_updated
  s     &&'>FFFr  c                 D   K   | j                  d|       d{    y7 w)zHandle client connected events.r   Nr  r  s     rD   r  z#DailyTransport._on_client_connected
  s     &&'<kJJJr  c                 D   K   | j                  d|       d{    y7 w)z"Handle client disconnected events.r   Nr  r  s     rD   r  z&DailyTransport._on_client_disconnected
  s     &&'?MMMr  r  c           	      >  K   | j                   j                  syt        j                         4 d{   }d| j                   j                   dd}| j                   j                  j
                  | j                   j                  j                  |d}| j                   j                   d}	 |j                  |||t        j                  d      	      4 d{   }|j                  d
k7  r`|j                          d{   }t        j                  d|j                   d| d       	 ddd      d{    ddd      d{    yt        j                  d       ddd      d{    ddd      d{    y7 T7 7 7 R7 D7  # 1 d{  7  sw Y   0xY w# t        j                   $ r t        j                  d| d       Y at"        $ r%}t        j                  d| d|        Y d}~d}~ww xY w7 # 1 d{  7  sw Y   yxY ww)z:Handle dial-in ready events by updating SIP configuration.NzBearer zapplication/json)AuthorizationzContent-Type)callId
callDomainsipUriz/dialin/pinlessCallUpdate
   )total)headersjsontimeout   z-Unable to handle dialin-ready event (status: z	, error: )z+Event dialin-ready was handled successfullyz%Timeout handling dialin-ready event (z#Error handling dialin-ready event (): )r   r   aiohttpClientSessionr   r   r   r   postClientTimeoutr"  r  r   r  r   r   TimeoutErrorrH  )	rX   r  sessionr/  r  urlrr  es	            rD   _handle_dialin_readyz#DailyTransport._handle_dialin_ready
  s    ||++((* 	P 	Pg#*4<<+?+?*@!A 2G
 ,,66>>"ll::FF&D \\))**CDCP"<<tW=R=RY[=\ (  
P 
Pxx3%&VVX~KAHH:U^_c^ddef 
P 
P	P 	P 	P0 LL!NO
P 
P	P 	P 	P
P  .	
P	P
P 
P 
P 
P '' MDSEKL PB3%s1#NOOP7	P 	P 	P 	Ps  0HFHA8H/-F(F	F( #FF+F/F(:F;F(?H
FHF%F(0F1F(5H HH	F(FF(HF(F%	FF%	!F((,HHHG>9H>HHHHHHHc                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)z Handle dial-in connected events.z dial-in connected: r   Nr   r   r  r  s     rD   r  z#DailyTransport._on_dialin_connected
  5     v1$89&&'<dCCC   0:8:c                    K   t        j                  |  d|        | j                  j                  r| j	                  |       d{    | j                  d|       d{    y7 7 w)zHandle dial-in ready events.z dial-in ready: Nr   )r   r   r   r   r>  r  r  s     rD   r  zDailyTransport._on_dialin_ready  s_     v-l^<=<<''++L999&&'8,GGG :Gs$   AA+A'A+!A)"A+)A+c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)zHandle dial-in stopped events.z dial-in stopped: r   Nr@  r  s     rD   r  z!DailyTransport._on_dialin_stopped  s5     v/v67&&':DAAArB  c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)zHandle dial-in error events.z dial-in error: r   Nr   r  r  r  s     rD   r  zDailyTransport._on_dialin_error  s5     v-dV45&&'8$???rB  c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)zHandle dial-in warning events.z dial-in warning: r   Nr   rH  r  r  s     rD   r  z!DailyTransport._on_dialin_warning  s5     $1$89&&':DAAArB  c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)z Handle dial-out answered events.z dial-out answered: r   Nr@  r  s     rD   r  z#DailyTransport._on_dialout_answered  rA  rB  c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)z!Handle dial-out connected events.z dial-out connected: r   Nr@  r  s     rD   r  z$DailyTransport._on_dialout_connected  s5     v24&9:&&'=tDDDrB  c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)zHandle dial-out stopped events.z dial-out stopped: r   Nr@  r  s     rD   r  z"DailyTransport._on_dialout_stopped$  s5     v078&&';TBBBrB  c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)zHandle dial-out error events.z dial-out error: r   NrF  r  s     rD   r  z DailyTransport._on_dialout_error)  s5     v.tf56&&'94@@@rB  c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)zHandle dial-out warning events.z dial-out warning: r   NrH  r  s     rD   r  z"DailyTransport._on_dialout_warning.  s5     $24&9:&&';TBBBrB  c                 n  K   |d   }t        j                  d|        | j                  re| j                  j                  rO| j                  j
                  r9| j                  j                  |d| j                  j                         d{    | j                  s!d| _	        | j                  d|       d{    | j                  d|       d{    | j                  d|       d{    | j                  r,| j                  j                  t                      d{    yy7 7 s7 [7 C7 w)	z!Handle participant joined events.rx  zParticipant joined r  NTr  r   r   )r   r{  r  r   ra  r   r  r
  r  r  r  r  r   )rX   r  rx  s      rD   r  z%DailyTransport._on_participant_joined3  s    )"./;;4<<88T\\=^=^++77L$,,"="=   1115D.**+H+VVV&&'>LLL&&'<kJJJ;;++(()=)?@@@  WLJ@sZ   B
D5D+,D59D-:D5D/D5-D1.6D5$D3%D5-D5/D51D53D5c                    K   |d   }t        j                  d|        | j                  d||       d{    | j                  d|       d{    y7 7 w)zHandle participant left events.rx  zParticipant left r   Nr   )r   r{  r  )rX   r  r  rx  s       rD   r  z#DailyTransport._on_participant_leftG  s^     't,-&&'<k6RRR&&'?MMM 	SMs!   4AAAAAAc                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)z"Handle participant updated events.z participant updated: r   N)r   tracer  r  s     rD   r  z&DailyTransport._on_participant_updatedO  s5     v3K=AB&&'?MMMrB  c                 ,  K   | j                  d|       d{    d}d|v r|d   }|sy|d   }|d   }|j                  dd      }|j                  di       }|j                  d	d
      }	 |d   d   d   d   d   }t        |      }|r-t	        |||||      }	t        j                  d| d| d       nt        |||||      }	||	_        | j                  r$| j                  j                  |	       d{    yy7 # t        $ r d}Y w xY w7 w)z$Handle transcription message events.r   Nr   participantIdr  r  	trackTyperawResponseis_finalFchannelalternativesr   	languages)r@  zTranscription (from: z): [rE  )r  r8  r'   KeyErrorr!   r   r   r   r  r  r  )
rX   r(  r:   r  r  
track_typeraw_responserV  r   r  s
             rD   r  z(DailyTransport._on_transcription_messageT  sI    &&'A7KKKg%$_5NvK(	[[d3
{{="5##J6	#I.~>qA+NqQH)H &t^YY`aELL00@TF!LM-E ",;;++66u=== ? 	L   	H	  >sA   DC?AD,D A0D8D9DDDDDc                    K   t        j                  |  d| d| d       | j                  d||       d{    y7 w)z$Handle transcription stopped events.z transcription stopped by: z	 (error: r3  r   Nr@  r%  s      rD   r  z(DailyTransport._on_transcription_stoppedx  sC     v8IN^M__`ab&&'A:O_```s   5?=?c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)z"Handle transcription error events.z transcription error: r   NrF  r)  s     rD   r  z&DailyTransport._on_transcription_error}  s5     v3G9=>&&'?IIIrB  c                 x   K   t        j                  |  d|        | j                  d|       d{    y7 w)z Handle recording started events.z recording started: r   Nr@  r!  s     rD   r  z$DailyTransport._on_recording_started  s5     v1&:;&&'=vFFFrB  c                 z   K   t        j                  |  d| d       | j                  d|       d{    y7 w)z Handle recording stopped events.z recording stopped (id: r3  r   Nr@  r-  s     rD   r  z$DailyTransport._on_recording_stopped  s7     v5i[BC&&'=yIIIs   1;9;c                    K   t        j                  |  d| d|        | j                  d||       d{    y7 w)zHandle recording error events.z recording error (id: r4  r   NrF  r/  s      rD   r  z"DailyTransport._on_recording_error  s=     v3I;c'KL&&';YPPPs   4><>)NNNrL  r  rO  rQ  )Jr<   r=   r>   r?   r@   r   r   r}   rV  r  r  r  rR  r   r:   DailyLogLevelr  r   r   r  r   r  r   r   rv  r  r   rS  r  r  r  r  r  r  r  r  r  r  r   r  r  r:  r  r  r  r  r  r  r  r  r  r  r  r>  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r\   r]   s   @rD   r  r    s   >J )-$(%)ZCZC }ZC 	ZC
 %ZC SMZC c]ZC@
* 

, 
  %# % % + + +
#= 
#M&9K&G MM&9 M+gc3h/ +1GCH$5 1!E#x?X:X4Y !"H_4M  8O3L  8O+D " BF	sH_--	..h6O  (?:S  (?*C  8<'/}	/	""Mc M ) 	cc c 	c& $!  	
 (#*38#4	/	"& ;?	/	".#*38#4	/	"(QC Q>2:	NJS J# JG# GKc KN N!Ps !PFD
HB
@
B
D
E
C
A
C
A(NN
">wsCx7H ">T ">Ha
J
G
J
QrC   r  )gr?   r   r  concurrent.futuresr   rA  r   dataclassesr   r   typingr   r   r	   r
   r   r   r   r5  logurur   pydanticr   pipecat.audio.vad.vad_analyzerr   r   pipecat.frames.framesr   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   "pipecat.processors.frame_processorr%   r&   pipecat.transcriptions.languager'   pipecat.transports.base_inputr(   pipecat.transports.base_outputr)   !pipecat.transports.base_transportr*   r+   "pipecat.utils.asyncio.task_managerr,   dailyr-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   rb  ModuleNotFoundErrorr=  r  rH  r   r9   rG   rI   r`   rc   re   rh   rp   rr   ru   r   r   r   r   r   r   r   r   r   r@   rS  r   rV  r  r  rB   rC   rD   <module>rr     s     F 1 ( K K K    A     * S 4 < > L >,   0   )'B ) ) )-N ) ) !A  2 'M  2 )&@ ) ),K 2 >I > > > > > I I I( (V	) 	9 903) 3(3) 3$V/ V8=>Y =>@2 	 	 	 	 	 	 I?< I?X&qY, qYh	q
. q
hmQ] mQ}B  ,FLL;qc"#FLL[ &qc*
++,s   G$ $H )2HH 