o
    i1                 
   @   s^  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 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/m0Z0 ddl1m2Z2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9 ddl:m;Z;m<Z< ddl=m>Z> z ddl?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZI ddl?mJZK W n  eLy ZM zeNdeM  eNd eOdeM dZM[Mww dZPeG dd de)ZQeG dd de*ZReG dd deQZSeG dd deRZTeG d d! d!e%ZUG d"d# d#eUZVeG d$d% d%e ZWeG d&d' d'e ZXeG d(d) d)e ZYG d*d+ d+eZZG d,d- d-eZ[G d.d/ d/eZ\G d0d1 d1eZ]G d2d3 d3eZ^G d4d5 d5e<Z_G d6d7 d7eZ`d8d9 ZaeG d:d; d;ZbeG d<d= d=ZcedZeG d>d? d?eGZfG d@dA dAe7ZgG dBdC dCe9ZhG dDdE dEe;ZidS )FzDaily 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)KeypadEntry)VADAnalyzer	VADParams)BotConnectedFrameCancelFrameClientConnectedFrame	DataFrameEndFrameFrameInputAudioRawFrameInputDTMFFrame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< dS ) 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__ rC   rC   V/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/transports/daily/transport.pyr:   P      
 r:   c                   @   r9   )&DailyOutputTransportMessageUrgentFramezFrame for urgent transport messages in Daily calls.

    Parameters:
        participant_id: Optional ID of the participant this message is for/from.
    Nr;   r<   rC   rC   rC   rD   rF   [   rE   rF   c                           e Zd ZdZ fddZ  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                    Z   t    dd l}|  |d |jdtdd W d    d S 1 s&w   Y  d S )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selfrQ   	__class__rC   rD   rP   r      


"z(DailyTransportMessageFrame.__post_init__r=   r>   r?   r@   rP   __classcell__rC   rC   rX   rD   rH   f       
rH   c                       rG   ) 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                    rI   )Nr   rJ   zDailyTransportMessageUrgentFrame is deprecated and will be removed in a future version. Instead, use DailyOutputTransportMessageUrgentFrame.rK   rL   rN   rV   rX   rC   rD   rP      rZ   z.DailyTransportMessageUrgentFrame.__post_init__r[   rC   rC   rX   rD   r^      r]   r^   c                   @   r9   )DailyInputTransportMessageFramezFrame for input urgent transport messages in Daily calls.

    Parameters:
        participant_id: Optional ID of the participant this message is for/from.
    Nr;   r<   rC   rC   rC   rD   r_      rE   r_   c                       rG   )%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                    rI   )Nr   rJ   zDailyInputTransportMessageUrgentFrame is deprecated and will be removed in a future version. Instead, use DailyInputTransportMessageFrame.rK   rL   rN   rV   rX   rC   rD   rP      rZ   z3DailyInputTransportMessageUrgentFrame.__post_init__r[   rC   rC   rX   rD   r`      s    
r`   c                   @   ,   e Zd ZU dZeedZeee	f e
d< dS )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   dictre   r
   rA   r   rB   rC   rC   rC   rD   rb         
 
rb   c                   @   ra   )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.
    rc   re   Nrf   rC   rC   rC   rD   ri      rh   ri   c                   @   ra   )"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.
    rc   remote_participantsN)r=   r>   r?   r@   r   rg   rk   r
   rA   r   rB   rC   rC   rC   rD   rj      s   
 rj   c                       sV   e Zd ZdZddddee dee f fddZdefd	d
Zde	fddZ
  ZS )WebRTCVADAnalyzerz~Voice Activity Detection analyzer using WebRTC.

    Implements voice activity detection using Daily's native WebRTC VAD.
    Nsample_rateparamsrn   ro   c                   s2   t  j||d tjt| jdd| _td dS )zInitialize the WebRTC VAD analyzer.

        Args:
            sample_rate: Audio sample rate in Hz.
            params: VAD configuration parameters.
        rm      )reset_period_msrn   channelszLoaded native WebRTC VADN)	rO   __init__r4   create_native_vadVAD_RESET_PERIOD_MSrn   _webrtc_vadr   debug)rW   rn   ro   rX   rC   rD   rs      s
   zWebRTCVADAnalyzer.__init__returnc                 C   s   t | jd S )zGet the number of audio frames required for VAD analysis.

        Returns:
            The number of frames needed (equivalent to 10ms of audio).
        g      Y@)intrn   rW   rC   rC   rD   num_frames_required   s   z%WebRTCVADAnalyzer.num_frames_requiredc                 C   s    d}t |dkr| 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   )lenrv   analyze_frames)rW   buffer
confidencerC   rC   rD   voice_confidence  s   	z"WebRTCVADAnalyzer.voice_confidence)r=   r>   r?   r@   r   ry   r   rs   r{   floatr   r\   rC   rC   rX   rD   rl      s
    &rl   c                   @   s*   e Zd ZU dZdZeed< dZeed< dS )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   rA   rB   r   rC   rC   rC   rD   r     s   
 r   c                   @   s~   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< dS )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   rA   rB   r   r   boolr   r   r   r   r   r
   r   rC   rC   rC   rD   r     s   
 r   c                   @   sN   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	< dS )
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   ry   rB   r   r   rA   r   r   r	   r   rC   rC   rC   rD   r   6  s   
 r   c                   @   sF   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< dS )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
    Nrn   rp   rr   r   )r=   r>   r?   r@   rn   r   ry   rB   rr   r   r	   rA   r   rC   rC   rC   rD   r   J  s
   
 r   c                   @   s   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< d	S )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   rA   rB   r   r   r   r   r   r   r
   r   r   r   r   r   r   r   r   r   rC   rC   rC   rD   r   \  s   
 r   c                   @   s  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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< dS ) DailyCallbacksa  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_dtmf_event: Called when a DTMF tone happens.
        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_dtmf_event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
   rA   r   r   rB   r   rC   rC   rC   rD   r   x  s>   
 " r   c                    s    fd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                     s$   dd }   j| g| R   d S )Nc                 W   sD   zt |dkr| | W d S | j|  W d S  tjy!   Y d S w )Nrp   )r|   
set_resultasyncioInvalidStateError)futureargsrC   rC   rD   r     s   z:completion_callback.<locals>._callback.<locals>.set_result)get_loopcall_soon_threadsafe)r   r   r   rC   rD   	_callback  s   	z&completion_callback.<locals>._callbackrC   )r   r   rC   r   rD   completion_callback  s   
r   c                   @   "   e Zd ZU dZeed< eed< dS )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@   r0   rB   r1   rC   rC   rC   rD   r        
 r   c                   @   r   )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@   r2   rB   r3   rC   rC   rC   rD   r     r   r   c                       s   e Zd ZU dZdZeed<  fddZdede	e ded	e
d
edef fddZdd ZedefddZedefddZedefddZedefddZdeeB de	e fddZde	e fddZdefdd Zdefd!d"Zdedefd#d$Zdedefd%d&Zd'e fd(d)Z!d*d+ Z"de#fd,d-Z$d.d/ Z%d0d1 Z&d2d3 Z'd4d5 Z(d6d7 Z)de*ee+f fd8d9Z,de*ee+f fd:d;Z-de.ee	e f fd<d=Z/de	e fd>d?Z0de	e fd@dAZ1de	e fdBdCZ2de	e fdDdEZ3de.ee	e f fdFdGZ4de	e fdHdIZ5de	e fdJdKZ6de	e fdLdMZ7	NddOedPe	e de	e fdQdRZ8dSefdTdUZ9	V	W	XddSedYe:dZed[ed\ef
d]d^Z;	_	`	addSedYe:dbedceddef
dedfZ<	Nddged	e	e= de>fdhdiZ?dgede	e fdjdkZ@	Nddged	e	eA deBfdldmZCdgede	e fdndoZD	Ndde	e fdpdqZE	Ndde	e fdrdsZFdte*ee+f de	e fdudvZGdwe*ee+f de	e fdxdyZHdzd{ ZIdOe+d|efd}d~ZJdefddZKde+fddZLdefddZMde+fddZNde+fddZOde+fddZPde+fddZQde+fddZRde+fddZSde+fddZTde+fddZUde+fddZVdd ZWdd ZXdd ZYdd ZZdd Z[dd Z\dd Z]dd Z^dd Z_dd Z`dSedeadZefddZbdSedecdcefddZddd Zedd Zfdd ZgdehjifddZjdehjifddZkdd ZldehjmfddZnddĄ Zo  ZpS )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                    s   t  | S )zPOverride EventHandler's __new__ method to ensure Daily is initialized only once.)rO   __new__)clsr   kwargsrX   rC   rD   r        zDailyTransportClient.__new__room_urltokenbot_namero   	callbackstransport_namec                    s   t    tjsdt_t  || _|| _|| _|| _	|| _
|| _d| _i | _i | _g | _d| _d| _d| _d| _d| _t | _d| _d| _tdd| _t| d| _d| _d| _d| _ g | _!d| _"d| _#d| _$d| _%d| _&i | _'i | _(dS )	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   rp   )max_workers)event_handler))rO   rs   r   r   r4   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)rW   r   r   r   ro   r   r   rX   rC   rD   rs     sF   


zDailyTransportClient.__init__c                 C   s
   d|  S )z@Generate a unique virtual speaker name for this client instance.zspeaker-rC   rz   rC   rC   rD   _speaker_nameL  s   
z"DailyTransportClient._speaker_namerx   c                 C      | j S )zhGet the Daily room URL.

        Returns:
            The room URL this client is connected to.
        )r   rz   rC   rC   rD   r   P     zDailyTransportClient.room_urlc                 C   r  )ztGet the participant ID for this client.

        Returns:
            The participant ID assigned by Daily.
        )r   rz   rC   rC   rD   r;   Y  r  z#DailyTransportClient.participant_idc                 C   r  )zdGet the input audio sample rate.

        Returns:
            The input sample rate in Hz.
        )r   rz   rC   rC   rD   in_sample_rateb  r  z#DailyTransportClient.in_sample_ratec                 C   r  )zfGet the output audio sample rate.

        Returns:
            The output sample rate in Hz.
        )r   rz   rC   rC   rD   out_sample_ratek  r  z$DailyTransportClient.out_sample_rateframec                    s^   | j s| j| dS d}t|ttfr|j}|   }| j	j
|j|t|d |I dH S )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
isinstancer:   rF   r;   _get_event_loopcreate_futurer   send_app_messagemessager   )rW   r  r;   r   rC   rC   rD   send_messaget  s   
z!DailyTransportClient.send_messagec                    s   | j sdS | j}| jj}t|d d }|   }| j j|t|d |I dH }t	|dkr7t
|||dS tdI dH  dS )z9Reads the next 20ms audio frame from the virtual speaker.Nd   rK   r  r   )audiorn   num_channelsg{Gz?)r   r   r   audio_in_channelsry   r
  r  read_framesr   r|   r   r   sleep)rW   rn   r  
num_framesr   r  rC   rC   rD   read_next_audio_frame  s   
z*DailyTransportClient.read_next_audio_framedestinationc                    f   | j jpi |}| j||dI dH | j|< d|dii}|r+|jr+d|ji|d |< | j| dS )zRegister a custom audio destination for multi-track output.

        Args:
            destination: The destination identifier to register.
        ro   NcustomAudioTsendSettings)r   r   getadd_custom_audio_trackr   r   r   update_publishingrW   r  ro   
publishingrC   rC   rD   register_audio_destination     
z/DailyTransportClient.register_audio_destinationc                    r  )zRegister a custom video destination for multi-track output.

        Args:
            destination: The destination identifier to register.
        r  NcustomVideoTr  )r   r   r  add_custom_video_trackr   r   r   r  r  rC   rC   rD   register_video_destination  r"  z/DailyTransportClient.register_video_destinationc                    s   |    }|j}d}|s| jr| jj}n|r%|| jv r%| j| }|j}|r2|j|jt|d nt	
|  d| d |d |I dH }|dkS )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   )rW   r  r   r  audio_sourcer   r  rC   rC   rD   write_audio_frame  s   	




z&DailyTransportClient.write_audio_framec                    sl   |j }d}|s| jr| jj}n|r|| jv r| j| }|j}|r)||j dS t|  d| d dS )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 [r&  F)r'  r   r   r   write_frameimager   r)  )rW   r  r  video_sourcer   rC   rC   rD   write_video_frame  s   	


z&DailyTransportClient.write_video_framesetupc                    s@   | j rdS |j| _ t | _| j | | j|  d| _dS )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   rW   r0  rC   rC   rD   r0    s   


zDailyTransportClient.setupc                    s   | j r| jr| j| j I dH  d| _ | jr'| jr'| j| jI dH  d| _| jr:| jr:| j| jI dH  d| _|  | j| jI dH  dS )z*Cleanup client resources and cancel tasks.N)	r   r   cancel_taskr   r   r
  run_in_executorr   _cleanuprz   rC   rC   rD   cleanup
  s   zDailyTransportClient.cleanupc                    sR  | j jp|j| _| j jp|j| _| j jrM| j jr4| js4| jr4t	
 | _| j| | j|  d| _n| jsMtj|  | j| j jdd| _t|   | j jrk| jsk| jrkt	
 | _| j| | j|  d| _| j jr| jst| j j| j j| j j}t|}t||d| _| j jr| j st!| j| j j"}t#|}t$||d| _ dS dS dS )zStart the client and initialize audio/video components.

        Args:
            frame: The start frame containing initialization parameters.
        z::audio_callback_taskT)rn   rr   non_blockingz::video_callback_taskr   r   N)%r   audio_in_sample_rater   audio_out_sample_rater   audio_in_enabledr   r   r   r   r2  _audio_queuer4  r5  r   r4   create_speaker_devicer   r  select_speaker_devicevideo_in_enabledr   _video_queuevideo_out_enabledr   r2   video_out_widthvideo_out_heightvideo_out_color_formatr3   r   audio_out_enabledr   r0   audio_out_channelsr1   r   )rW   r  r.  video_trackr*  audio_trackrC   rC   rD   start  sJ   



zDailyTransportClient.startc                    s<  | j s| jr|  jd7  _dS td| j  d| _| jddddi | j| j	 | 
 I dH \}}|sd| _ d| _|  jd7  _|d	i d
i d}|di d}td| j d| d|  | j|I dH  | j  |  I dH  dS d| j d| }t| | j|I dH  d| _dS )z-Join the Daily room with configured settings.rp   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   _joinr  r   r   r   set_flush_join_messageserrorr   )rW   datar^  r;   
meeting_id	error_msgrC   rC   rD   joinF  s6   


zDailyTransportClient.joinc                    s  | j sdS |   }| jjo| jj}| jjo| jj}| j j| j	| j
t||dd| jr1| jjjndiid|dd| jrA| jjjndiidddd	d
i| jjrVd| jjini dd
| jj| jjdiiid| jjdkrodnd| jjdiddd |I dH S )z'Execute the actual room join operation.NcustomTrackrU  zno-camera-track)	isEnabledre   zno-microphone-track)rQ  
microphoner  
maxQualitylowpreferredCodec	encodings)
maxBitratemaxFrameraterK   stereomono)channelConfigbitrate)inputsr   )r  client_settings)r   r
  r  r   rE  r   rI  r   rb  r   r   r   r   r   rU  r   video_out_codecvideo_out_bitratevideo_out_frameraterJ  audio_out_bitrate)rW   r   camera_enabledmicrophone_enabledrC   rC   rD   r[  r  sn   
8zDailyTransportClient._joinc                    s  |  j d8  _ | jr| j dkrdS d| _| j  td| j  | j I dH  | j	
 D ]\}}| |I dH  q0| j
 D ]\}}| |I dH  qB|  I dH }|sktd| j  | j I dH  dS d| j d| }t| | j|I dH  dS )	z+Leave the Daily room and cleanup resources.rp   r   NFzLeaving zLeft zError leaving rW  )r   r   r   clearr   rX  r   r   r   r   itemsremove_custom_audio_trackr   remove_custom_video_track_leaver   r^  r   )rW   
track_name_r^  ra  rC   rC   rD   leave  s&   

zDailyTransportClient.leavec                    s4   | j sdS |   }| j jt|d |I dH S )z(Execute the actual room leave operation.Nr  )r   r
  r  r  r   rW   r   rC   rC   rD   r|    s   
zDailyTransportClient._leavec                 C   s   | j r| j   d| _ dS dS )z"Cleanup the Daily client instance.N)r   releaserz   rC   rC   rD   r9    s   

zDailyTransportClient._cleanupc                 C   
   | j  S zGet current participants in the room.

        Returns:
            Dictionary of participants keyed by participant ID.
        r   rS  rz   rC   rC   rD   rS       
z!DailyTransportClient.participantsc                 C   r  ztGet participant count information.

        Returns:
            Dictionary with participant count details.
        r   participant_countsrz   rC   rC   rD   r    r  z'DailyTransportClient.participant_countsc                    ,   |    }| jj|t|d |I dH S )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   rW   re   r   rC   rC   rD   r    s   

z"DailyTransportClient.start_dialoutc                    r  )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   )rW   r;   r   rC   rC   rD   r       	
z!DailyTransportClient.stop_dialoutc                    sL   | dp| j}|sdS ||d< |   }| jj|t|d |I dH S )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)r  r   r
  r  r   	send_dtmfr   rW   re   
session_idr   rC   rC   rD   r    s   	
zDailyTransportClient.send_dtmfc                    sR   | dp| jp| j}|sdS ||d< |   }| jj|t|d |I dH S )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)r  r   r   r
  r  r   sip_call_transferr   r  rC   rC   rD   r  $  s   

z&DailyTransportClient.sip_call_transferc                    r  )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  rC   rC   rD   r  :  r  zDailyTransportClient.sip_referc                    s0   |    }| jj|||t|d |I dH S )}  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   )rW   streaming_settings	stream_id	force_newr   rC   rC   rD   r  G  s   
z$DailyTransportClient.start_recordingc                    r  )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   )rW   r  r   rC   rC   rD   r  [  r  z#DailyTransportClient.stop_recordingc                    s6   | j sdS |   }| jj|t|d |I dH S )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)re   r  N)r   r
  r  r   start_transcriptionr   r  rC   rC   rD   r  h  s   	
z(DailyTransportClient.start_transcriptionc                    s4   | j sdS |   }| jjt|d |I dH S )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  rC   rC   rD   r  x  s   
z'DailyTransportClient.stop_transcriptionNr  	user_namec                    s8   | j sdS |   }| jj||t|d |I dH S )  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   )rW   r  r  r   rC   rC   rD   r    s   

z/DailyTransportClient.send_prebuilt_chat_messager;   c                    sD   | j jsdS | j| | jr| jr | | jI dH  dS dS dS 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rW   r;   rC   rC   rD   !capture_participant_transcription  s   z6DailyTransportClient.capture_participant_transcriptionre  >     callbackr*  rn   callback_interval_msc                    s   |dv rd|dii}ndd|diii}| j ||idI dH  || j|i |< td| d|  | jj|| j|||d	 dS )
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.
        )re  screenAudiomedia
subscribedr  participant_settingsNStarting to capture [z] audio from participant )r*  rn   r  )update_subscriptionsr   
setdefaultr   rw   r   set_audio_renderer_audio_data_received)rW   r;   r  r*  rn   r  r  rC   rC   rD   capture_participant_audio  s    
z.DailyTransportClient.capture_participant_audio   rQ  r   	framerater.  r   c                    s   |dv rd|dii}ndd|diii}| j ||idI dH  || j|i |< td| d|  | jj|| j||d	 dS )
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.
        rP  r  r  r#  r  Nr  z] video from participant )r.  r   )r  r   r  r   rw   r   set_video_renderer_video_frame_received)rW   r;   r  r  r.  r   r  rC   rC   rD   capture_participant_video  s   
z.DailyTransportClient.capture_participant_videor}  c           	         sv   |    }|r|jr|jn| j}|r|jnd}t||}t|}| jj||dt	|d |I dH  t
||d}|S )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.
        rp   T)r}  rL  ignore_audio_levelr  Nr<  )r
  r  rn   r   rr   r0   r1   r   r  r   r   )	rW   r}  ro   r   rn   rr   r*  rL  r   rC   rC   rD   r    s   

z+DailyTransportClient.add_custom_audio_trackc                    r  )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   rz  r   rW   r}  r   rC   rC   rD   rz       	
z.DailyTransportClient.remove_custom_audio_trackc           	         s   |    }|r|jn| jj}|r|jn| jj}|r|jn| jj}t	|||}t
|}| jj||t|d |I dH  t||dS )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}  rK  r  Nr<  )r
  r  r   r   rF  r   rG  r   rH  r2   r3   r   r$  r   r   )	rW   r}  ro   r   r   r   r   r.  rK  rC   rC   rD   r$  (  s   
z+DailyTransportClient.add_custom_video_trackc                    r  )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  rC   rC   rD   r{  J  r  z.DailyTransportClient.remove_custom_video_trackc                    .   |    }| jj||t|d |I dH S )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   )rW   rS  instance_idr   rC   rC   rD   r  Z  s   

z)DailyTransportClient.update_transcriptionc                    r  )  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   )rW   r  r  r   rC   rC   rD   r  l  s   
z)DailyTransportClient.update_subscriptionspublishing_settingsc                    r  )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   )rW   r  r   rC   rC   rD   r    s   
z&DailyTransportClient.update_publishingrk   c                    r  )Update settings for remote participants.

        Args:
            remote_participants: Remote participant configuration settings.

        Returns:
            error: An error description or None.
        )rk   r  N)r
  r  r   update_remote_participantsr   )rW   rk   r   rC   rC   rD   r    s   
z/DailyTransportClient.update_remote_participantsc                 C      |  | jj| dS )z~Handle active speaker change events.

        Args:
            participant: The new active speaker participant info.
        N)_call_event_callbackr   r   rW   participantrC   rC   rD   r        z.DailyTransportClient.on_active_speaker_changedsenderc                 C      |  | jj|| dS )zHandle application message events.

        Args:
            message: The received message data.
            sender: ID of the message sender.
        N)r  r   r   rW   r  r  rC   rC   rD   r        z#DailyTransportClient.on_app_messagestatec                 C   r  )z_Handle call state update events.

        Args:
            state: The new call state.
        N)r  r   r   rW   r  rC   rC   rD   r     r  z*DailyTransportClient.on_call_state_updatedr_  c                 C   *   d|v r|d nd| _ | | jj| dS )zcHandle dial-in connected events.

        Args:
            data: Dial-in connection data.
        r  r   N)r   r  r   r   rW   r_  rC   rC   rD   r        z(DailyTransportClient.on_dialin_connectedsip_endpointc                 C   r  )zlHandle dial-in ready events.

        Args:
            sip_endpoint: The SIP endpoint for dial-in.
        N)r  r   r   rW   r  rC   rC   rD   r     r  z$DailyTransportClient.on_dialin_readyc                 C   *   | d| jkrd| _| | jj| dS )z[Handle dial-in stopped events.

        Args:
            data: Dial-in stop data.
        r  r   N)r  r   r  r   r   r  rC   rC   rD   r        z&DailyTransportClient.on_dialin_stoppedc                 C   r  )zZHandle dial-in error events.

        Args:
            data: Dial-in error data.
        r  r   N)r  r   r  r   r   r  rC   rC   rD   r     r  z$DailyTransportClient.on_dialin_errorc                 C   r  )z^Handle dial-in warning events.

        Args:
            data: Dial-in warning data.
        N)r  r   r   r  rC   rC   rD   r     r  z&DailyTransportClient.on_dialin_warningc                 C   r  )zbHandle dial-out answered events.

        Args:
            data: Dial-out answered data.
        N)r  r   r   r  rC   rC   rD   r     r  z(DailyTransportClient.on_dialout_answeredc                 C   r  )zeHandle dial-out connected events.

        Args:
            data: Dial-out connection data.
        r  r   N)r   r  r   r   r  rC   rC   rD   r     r  z)DailyTransportClient.on_dialout_connectedc                 C   r  )z]Handle dial-out stopped events.

        Args:
            data: Dial-out stop data.
        r  r   N)r  r   r  r   r   r  rC   rC   rD   r     r  z'DailyTransportClient.on_dialout_stoppedc                 C   r  )z\Handle dial-out error events.

        Args:
            data: Dial-out error data.
        r  r   N)r  r   r  r   r   r  rC   rC   rD   r     r  z%DailyTransportClient.on_dialout_errorc                 C   r  )z`Handle dial-out warning events.

        Args:
            data: Dial-out warning data.
        N)r  r   r   r  rC   rC   rD   r     r  z'DailyTransportClient.on_dialout_warningc                 C   r  )zQHandle incoming DTMF events.

        Args:
            data: DTMF data.
        N)r  r   r   r  rC   rC   rD   r     r  z"DailyTransportClient.on_dtmf_eventc                 C   r  )zoHandle participant joined events.

        Args:
            participant: The participant that joined.
        N)r  r   r   r  rC   rC   rD   r   '  r  z*DailyTransportClient.on_participant_joinedc                 C   r  )zHandle participant left events.

        Args:
            participant: The participant that left.
            reason: Reason for leaving.
        N)r  r   r   )rW   r  reasonrC   rC   rD   r   /  r  z(DailyTransportClient.on_participant_leftc                 C   r  )zqHandle participant updated events.

        Args:
            participant: The updated participant info.
        N)r  r   r   r  rC   rC   rD   r   8  r  z+DailyTransportClient.on_participant_updatedc                 C   s*   t d|  || _| | j| j dS )zlHandle transcription started events.

        Args:
            status: Transcription start status.
        zTranscription started: N)r   rw   r   r  r  r   rW   statusrC   rC   rD   on_transcription_started@  s   z-DailyTransportClient.on_transcription_startedc                 C   s    t d | | jj|| dS )zHandle transcription stopped events.

        Args:
            stopped_by: Who stopped the transcription.
            stopped_by_error: Whether stopped due to error.
        zTranscription stoppedN)r   rw   r  r   r   rW   
stopped_bystopped_by_errorrC   rC   rD   r   J  s   

z-DailyTransportClient.on_transcription_stoppedc                 C   r  )z^Handle transcription error events.

        Args:
            message: Error message.
        N)r  r   r   rW   r  rC   rC   rD   r   V  r  z+DailyTransportClient.on_transcription_errorc                 C   r  )zqHandle transcription message events.

        Args:
            message: The transcription message data.
        N)r  r   r   r  rC   rC   rD   r   ^  r  z-DailyTransportClient.on_transcription_messagec                 C   $   t d|  | | jj| dS )zdHandle recording started events.

        Args:
            status: Recording start status.
        zRecording started: N)r   rw   r  r   r   r  rC   rC   rD   r   f     z)DailyTransportClient.on_recording_startedc                 C   r  )zsHandle recording stopped events.

        Args:
            stream_id: ID of the stopped recording stream.
        zRecording stopped: N)r   rw   r  r   r   rW   r  rC   rC   rD   r   o  r  z)DailyTransportClient.on_recording_stoppedc                 C   s,   t d| d|  | | jj|| dS )zHandle recording error events.

        Args:
            stream_id: ID of the recording stream with error.
            message: Error message.
        zRecording error for rW  N)r   r^  r  r   r   rW   r  r  rC   rC   rD   r   x  s   z'DailyTransportClient.on_recording_error
audio_datac                 C   "   | j | | }| |||| dS )z-Handle received audio data from participants.N)r   _call_audio_callback)rW   r;   r  r*  r  rC   rC   rD   r    s   z)DailyTransportClient._audio_data_receivedvideo_framec                 C   r  )z/Handle received video frames from participants.N)r   _call_video_callback)rW   r;   r  r.  r  rC   rC   rD   r    s   z*DailyTransportClient._video_frame_receivedc                 G      | j | j|g|R   dS )z,Queue an audio callback for async execution.N)_call_async_callbackr@  rW   r  r   rC   rC   rD   r       z)DailyTransportClient._call_audio_callbackc                 G   r  )z+Queue a video callback for async execution.N)r  rD  r  rC   rC   rD   r    r  z)DailyTransportClient._call_video_callbackc                 G   r  )z,Queue an event callback for async execution.N)r  r3  r  rC   rC   rD   r    r  z)DailyTransportClient._call_event_callbackqueuec                 G   sB   zt ||g|R |  }|  W dS  ty    Y dS w )z7Queue a callback for async execution on the event loop.N)r   run_coroutine_threadsafeputr
  resultFuturesCancelledError)rW   r  r  r   r   rC   rC   rD   r    s   z)DailyTransportClient._call_async_callbackc                    s>   	 | j  I dH  | I dH ^}}|| I dH  |  q)z1Handle queued callbacks from the specified queue.TN)r   waitr  	task_done)rW   r  r  r   rC   rC   rD   r5    s   z+DailyTransportClient._callback_task_handlerc                    s,   | j D ]
}| |I dH  q| j   dS )z9Send any messages that were queued before join completed.N)r   r  rx  rW   r  rC   rC   rD   r]    s   
z)DailyTransportClient._flush_join_messagesc                 C   s   | j s
t|  d| j  S )z)Get the event loop from the task manager.z.: missing task manager (pipeline not started?))r   	Exceptionget_event_looprz   rC   rC   rD   r
    s   
z$DailyTransportClient._get_event_loopc                 C   s   | j  dS )z2String representation of the DailyTransportClient.z::DailyTransportClient)r   rz   rC   rC   rD   __str__  r   zDailyTransportClient.__str__N)re  r  r  r  rQ  r   NN)qr=   r>   r?   r@   r   r   rB   r   rA   r   r   r   rs   r   propertyr   r;   ry   r  r  r   r   CallClientErrorr  r   r  r!  r%  r   r+  r   r/  r'   r0  r:  r!   rM  rb  r[  r  r|  r9  r
   r   rS  r  r   r  r  r  r  r  r  r  r  r  r  r  r   r  r  r   r   r  rz  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  r6   r  r  r  r  r   r2  r  r5  r]  AbstractEventLoopr
  r  r\   rC   rC   rX   rD   r     sT  
 M
-,D 	


+
)
$
"





				
		

	r   c                	       sZ  e Zd ZdZdededef fddZede	e
 fdd	Zd
d Zdef fddZ fddZdef fddZdef fddZdef fddZdedef fddZdeeB fddZdedefdd Z	!	"d:d#ed$ed%efd&d'Z d#ed(e!d$efd)d*Z"d+d, Z#	-	.	/d;d#ed0ed1ed2efd3d4Z$de%fd5d6Z&d#ed7e'd1efd8d9Z(  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clientro   c                    sP   t  j|fi | || _|| _|| _i | _d| _d| _g | _d| _	|j
| _dS )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)rO   rs   
_transportr   r   r   _initialized_streaming_started_capture_participant_audio_audio_in_taskvad_analyzer_vad_analyzerrW   r  r  ro   r   rX   rC   rD   rs     s   zDailyInputTransport.__init__rx   c                 C   r  )zzGet the Voice Activity Detection analyzer.

        Returns:
            The VAD analyzer instance if configured.
        )r  rz   rC   rC   rD   r
    r  z DailyInputTransport.vad_analyzerc                    sv   | j jsdS td | j jr6| j jr+| jD ]\}}}| j|| j||I dH  qn| j	s6| 
|  | _	d| _dS )z(Start receiving audio from participants.NzStart receiving audioT)r   r?  r   rw   r   r  r   r  _on_participant_audio_datar	  r4  _audio_in_task_handlerr  rW   r;   r*  rn   rC   rC   rD   start_audio_in_streaming  s   


z,DailyInputTransport.start_audio_in_streamingr0  c                    *   t  |I dH  | j|I dH  dS )zSetup the input transport with shared client setup.

        Args:
            setup: The frame processor setup configuration.
        NrO   r0  r   r6  rX   rC   rD   r0       zDailyInputTransport.setupc                    6   t   I dH  | j I dH  | j I dH  dS )z-Cleanup input transport and shared resources.NrO   r:  r   r  rz   rX   rC   rD   r:       zDailyInputTransport.cleanupr  c                    st   t  |I dH  | jrdS d| _| j|I dH  | j I dH  | |I dH  | jjr8|  I dH  dS dS )zStart the input transport and join the Daily room.

        Args:
            frame: The start frame containing initialization parameters.
        NT)	rO   rM  r  r   rb  set_transport_readyr   audio_in_stream_on_startr  r  rX   rC   rD   rM     s   zDailyInputTransport.startc                    J   t  |I dH  | j I dH  | jr#| | jI dH  d| _dS dS )zStop the input transport and leave the Daily room.

        Args:
            frame: The end frame signaling transport shutdown.
        N)rO   stopr   r  r	  r7  r  rX   rC   rD   r  :     
zDailyInputTransport.stopc                    r  )zCancel the input transport and leave the Daily room.

        Args:
            frame: The cancel frame signaling immediate cancellation.
        N)rO   cancelr   r  r	  r7  r  rX   rC   rD   r  I  r  zDailyInputTransport.cancel	directionc                    s8   t  ||I dH  t|tr| |I dH  dS dS )zProcess incoming frames, including user image requests.

        Args:
            frame: The frame to process.
            direction: The direction of frame flow in the pipeline.
        N)rO   process_framer	  r%   request_participant_image)rW   r  r  rX   rC   rD   r  \  s
   
z!DailyInputTransport.process_framec                    s   |  |I dH  dS )zrPush a transcription frame downstream.

        Args:
            frame: The transcription frame to push.
        N)
push_framer  rC   rC   rD   push_transcription_framel  s   z,DailyInputTransport.push_transcription_framer  r  c                    s   | j t||dI dH  dS )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_framer_   r  rC   rC   rD   push_app_messaget  s   z$DailyInputTransport.push_app_messagere  r  r;   r*  rn   c                    s<   | j r| j|| j||I dH  dS | j|||f dS 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  r  r  r  r  rC   rC   rD   r    s   
z-DailyInputTransport.capture_participant_audior  c                    s2   t ||j|j|jd}||_| |I dH  dS )z'Handle received participant audio data.)user_idr  rn   r  N)r#   audio_framesrn   r  transport_sourcepush_audio_frame)rW   r;   r  r*  r  rC   rC   rD   r    s   z.DailyInputTransport._on_participant_audio_datac                    s*   	 | j  I d H }|r| |I d H  qr  )r   r  r(  r  rC   rC   rD   r    s   z*DailyInputTransport._audio_in_task_handlerr  rQ  r   r  r.  r   c                    sL   || j vri | j |< |dg d| j | |< | j|| j|||I dH  dS )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rW   r;   r  r.  r   rC   rC   rD   r    s   

z-DailyInputTransport.capture_participant_videoc                    s@   |j | jv r|jr|jnd}| j|j  | d | dS dS )z{Request a video frame from a specific participant.

        Args:
            frame: The user image request frame.
        rQ  r+  N)r%  r   r.  r  )rW   r  r.  rC   rC   rD   r    s
   z-DailyInputTransport.request_participant_imager  c              	      s   d}t   }| j| | d }| j| | d }d}|dkr+|d|  }	|	| dk }| j| | d rB| j| | d d}d	}|rut||j|j|jf|j|rT|jnd|rZ|j	nd|d
}
||
_
| |
I dH  || j| | d< dS dS )z)Handle received participant video frames.Fr*  r  Nr   rp   g?r+  T)r%  r-  sizeformattextappend_to_contextrequest)timer   popr$   r~   r   r   r   r0  r1  r'  push_video_frame)rW   r;   r  r.  render_frame	curr_time	prev_timer  request_frame	next_timer  rC   rC   rD   r,    s<   
	z/DailyInputTransport._on_participant_video_framere  r  r  )*r=   r>   r?   r@   r+   r   r   rs   r  r   r   r
  r  r'   r0  r:  r!   rM  r   r  r   r  r   r&   r  r"   r   r!  r   rA   r#  ry   r  r.   r  r  r  r%   r  r6   r,  r\   rC   rC   rX   rD   r    sr    &	



r  c                       s   e Zd ZdZdededef fddZdef fdd	Z	 fd
dZ
def fddZdef fddZdef fddZdeeB fddZdefddZdefddZdedefddZdedefddZdefdd Zdefd!d"Zd#d$ Z  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.
    r  r  ro   c                    s*   t  j|fi | || _|| _d| _dS )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)rO   rs   r  r   r  r  rX   rC   rD   rs     s   
zDailyOutputTransport.__init__r0  c                    r  )zSetup the output transport with shared client setup.

        Args:
            setup: The frame processor setup configuration.
        Nr  r6  rX   rC   rD   r0    r  zDailyOutputTransport.setupc                    r  )z.Cleanup output transport and shared resources.Nr  rz   rX   rC   rD   r:    r  zDailyOutputTransport.cleanupr  c                    sZ   t  |I dH  | jrdS d| _| j|I dH  | j I dH  | |I dH  dS )zStart the output transport and join the Daily room.

        Args:
            frame: The start frame containing initialization parameters.
        NT)rO   rM  r  r   rb  r  r  rX   rC   rD   rM  #  s   zDailyOutputTransport.startc                    (   t  |I dH  | j I dH  dS )zStop the output transport and leave the Daily room.

        Args:
            frame: The end frame signaling transport shutdown.
        N)rO   r  r   r  r  rX   rC   rD   r  :     zDailyOutputTransport.stopc                    r=  )zCancel the output transport and leave the Daily room.

        Args:
            frame: The cancel frame signaling immediate cancellation.
        N)rO   r  r   r  r  rX   rC   rD   r  E  r>  zDailyOutputTransport.cancelc                    s6   | j |I dH }|r| d| I dH  dS dS )zySend a transport message to participants.

        Args:
            frame: The transport message frame to send.
        NzUnable to send message: )r   r  
push_errorrW   r  r^  rC   rC   rD   r  P  s
   z!DailyOutputTransport.send_messager  c                       | j |I dH  dS )z}Register a video output destination.

        Args:
            destination: The destination identifier to register.
        N)r   r%  rW   r  rC   rC   rD   r%  \     z/DailyOutputTransport.register_video_destinationc                    rA  )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!  rB  rC   rC   rD   r!  d  s   	z/DailyOutputTransport.register_audio_destinationrx   c                       | j |I dH S )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   r+  r  rC   rC   rD   r+  o     	z&DailyOutputTransport.write_audio_framec                    rD  )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   r/  r  rC   rC   rD   r/  z  rE  z&DailyOutputTransport.write_video_framec                    s   t |tr!| j|jI dH }|r| d| I dH  dS dS t |trA| j|jI dH }|r?| d| I dH  dS dS t |tr_| j	|j
I dH }|ra| d| I dH  dS dS dS )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	  rb   r   r  re   r?  ri   r  rj   r  rk   r@  rC   rC   rD   write_transport_frame  s"   


z*DailyOutputTransport.write_transport_framec                 C   s   dS )zDaily supports native DTMF via telephone events.

        Returns:
            True, as Daily supports native DTMF transmission.
        TrC   rz   rC   rC   rD   _supports_native_dtmf  s   z*DailyOutputTransport._supports_native_dtmfc                    s$   | j |j|jjdI dH  dS )z}Use Daily's native send_dtmf method for telephone events.

        Args:
            frame: The DTMF frame to write.
        )r  tonesN)r   r  r'  buttonvaluer  rC   rC   rD   _write_dtmf_native  s   z'DailyOutputTransport._write_dtmf_native)!r=   r>   r?   r@   r+   r   r   rs   r'   r0  r:  r!   rM  r   r  r   r  r   r   r  rA   r%  r!  r   r   r+  r   r/  r   rI  rJ  rN  r\   rC   rC   rX   rD   r<    s0    	
r<  c                       s  e Zd ZdZ			ddedee dedee dee dee f fd	d
ZdefddZ	de
fddZedefddZedefddZdefddZdeeB fddZdefddZdeeef fddZdeeef fddZddeeee f fd d!Zdee fd"d#Zdee fd$d%Zdee fd&d'Z	ddeeee f fd(d)Z ddee fd*d+Z!ddee fd,d-Z"dee fd.d/Z#	dd0ed1ee dee fd2d3Z$d4efd5d6Z%	7	8dd4ed9ed:e&fd;d<Z'	=	>	?dd4ed@e&dAedBefdCdDZ(dEeeef dee fdFdGZ)	ddee fdHdIZ*dJeeef dee fdKdLZ+dMefdNdOZ,dPdQ Z-dRdS Z.dTdU Z/dVdW Z0d0edXefdYdZZ1d[efd\d]Z2dMefd^d_Z3dMefd`daZ4dbefdcddZ5dedf Z6dgdh Z7didj Z8dkdl Z9dmdn Z:dodp Z;dqdr Z<dsdt Z=dudv Z>dwdx Z?dydz Z@d{d| ZAd}d~ ZBdd ZCd0eeef ddfddZDdd ZEdd ZFdd ZGdd ZHdd ZI  ZJS )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   ro   
input_nameoutput_namec                    sb  t  j||d 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| jd| jd| jd| jd| jd| jd| jd| j}|pt  | _!t"|||| j!|| j#| _$d| _%d| _&d | _'| (d | (d! | (d | (d | (d | (d | (d | (d	 | (d
 | (d | (d | (d | (d | (d | (d | (d | (d | (d | (d | (d | (d" | (d | (d | (d | (d | (d | (d | (d | j(dd#d$ dS )&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.
        )rP  rQ  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)syncrC   ))rO   rs   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_dtmf_event_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)rW   r   r   r   ro   rP  rQ  r   rX   rC   rD   rs     s   	




























zDailyTransport.__init__rx   c                 C   $   | j st| | j| j| jd| _ | j S )zGet the input transport for receiving media and events.

        Returns:
            The Daily input transport instance.
        rr  )rs  r  r   r   _input_namerz   rC   rC   rD   inputQ	  
   zDailyTransport.inputc                 C   rw  )zGet the output transport for sending media and events.

        Returns:
            The Daily output transport instance.
        rx  )rt  r<  r   r   _output_namerz   rC   rC   rD   output]	  r{  zDailyTransport.outputc                 C      | j jS )zkGet the Daily room URL.

        Returns:
            The room URL this transport is connected to.
        )r   r   rz   rC   rC   rD   r   m	     zDailyTransport.room_urlc                 C   r~  )zwGet the participant ID for this transport.

        Returns:
            The participant ID assigned by Daily.
        )r   r;   rz   rC   rC   rD   r;   v	  r  zDailyTransport.participant_idlevelc                 C   s   t | dS )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)r4   set_log_level)rW   r  rC   rC   rD   r  	  s   
zDailyTransport.set_log_levelr  c                    &   | j r| j |tjI dH  dS dS )zjSend an image frame to the Daily call.

        Args:
            frame: The image frame to send.
        Nrt  queue_framer&   
DOWNSTREAMr  rC   rC   rD   
send_image	     zDailyTransport.send_imagec                    r  )zjSend an audio frame to the Daily call.

        Args:
            frame: The audio frame to send.
        Nr  r  rC   rC   rD   
send_audio	  r  zDailyTransport.send_audioc                 C   r  r  r  rz   rC   rC   rD   rS  	  r  zDailyTransport.participantsc                 C   r  r  r  rz   rC   rC   rD   r  	  r  z!DailyTransport.participant_countsc                    sD   t d|  | j|I dH \}}|rt d|  ||fS )r  zStarting dialout: settings=NzUnable to start dialout: )r   rw   r   r  r^  )rW   re   r  r^  rC   rC   rD   r  	  s   
zDailyTransport.start_dialoutc                    <   t d|  | j|I dH }|rt d|  |S )r  z!Stopping dialout: participant_id=NzUnable to stop dialout: )r   rw   r   r  r^  )rW   r;   r^  rC   rC   rD   r  	     	zDailyTransport.stop_dialoutc                    r  )r  z$Staring SIP call transfer: settings=NrF  )r   rw   r   r  r^  rW   re   r^  rC   rC   rD   r  	  r  z DailyTransport.sip_call_transferc                    r  )r  zStaring SIP REFER: settings=NrG  )r   rw   r   r  r^  r  rC   rC   rD   r  	  r  zDailyTransport.sip_referc                    sT   t d| d| d|  | j|||I dH \}}|r&t d|  ||fS )r  zStarting recording: stream_id=z force_new=z
 settings=NzUnable to start recording: )r   rw   r   r  r^  )rW   r  r  r  r_idr^  rC   rC   rD   r  	  s   zDailyTransport.start_recordingc                    r  )r  zStopping recording: stream_id=NzUnable to stop recording: )r   rw   r   r  r^  )rW   r  r^  rC   rC   rD   r  
  r  zDailyTransport.stop_recordingc                    r  )r  z!Starting transcription: settings=NUnable to start transcription: )r   rw   r   r  r^  r  rC   rC   rD   r  
  r  z"DailyTransport.start_transcriptionc                    s4   t d | j I dH }|rt d|  |S )r  zStopping transcriptionNUnable to stop transcription: )r   rw   r   r  r^  rW   r^  rC   rC   rD   r  %
  s   
z!DailyTransport.stop_transcriptionr  r  c                    s.   | j ||I dH }|rtd|  |S )r  Nz&Unable to send prebuilt chat message: )r   r  r   r^  )rW   r  r  r^  rC   rC   rD   r  2
  s
   z)DailyTransport.send_prebuilt_chat_messager;   c                    rA  r  )r   r  r  rC   rC   rD   r  C
  rC  z0DailyTransport.capture_participant_transcriptionre  r  r*  rn   c                    s&   | j r| j |||I dH  dS dS r$  )rs  r  r  rC   rC   rD   r  K
  s   z(DailyTransport.capture_participant_audior  rQ  r   r  r.  r   c                    s(   | j r| j ||||I dH  dS dS )r)  N)rs  r  r-  rC   rC   rD   r  [
  s   z(DailyTransport.capture_participant_videor  c                    >   t d|  | jj|dI dH }|rt d|  |S )r  z'Updating publishing settings: settings=)r  Nz&Unable to update publishing settings: )r   rw   r   r  r^  )rW   r  r^  rC   rC   rD   r  o
  s   z DailyTransport.update_publishingc                    sF   t d| d|  | jj||dI dH }|r!t d|  |S )r  z-Updating subscriptions: participant_settings=z profile_settings=)r  r  Nz(Unable to update subscription settings: )r   rw   r   r  r^  )rW   r  r  r^  rC   rC   rD   r  
  s   z#DailyTransport.update_subscriptionsrk   c                    r  )r  z2Updating remote participants: remote_participants=)rk   NrH  )r   rw   r   r  r^  )rW   rk   r^  rC   rC   rD   r  
  s   z)DailyTransport.update_remote_participantsr  c                       |  d|I dH  dS )z$Handle active speaker change events.r   N_call_event_handlerr  rC   rC   rD   rU  
     z)DailyTransport._on_active_speaker_changedc                    s   | j jr"| j jjdd}| |I dH }|r"| d| I dH  | d|I dH  | d|I dH  | jrC| jt	 I dH  dS dS )zHandle room joined events.T)exclude_noneNr  r   rR  )
r   r   r   
model_dumpr  rY  r  rs  r   r   )rW   r_  re   r^  rC   rC   rD   rV  
  s   zDailyTransport._on_joinedc                    s   |  dI dH  dS )zHandle room left events.r   Nr  rz   rC   rC   rD   rW  
  s   zDailyTransport._on_leftc                    sF   | j jr|  I dH }|r| d| I dH  | dI dH  dS )z Handle before leave room events.Nr  r   )r   r   r  rY  r  r  rC   rC   rD   rX  
  s   zDailyTransport._on_before_leavec                    sb   |  d|I dH  | jr| jj|dI dH  dS | jr(| jj|dI dH  dS td td)z*Handle error events and push error frames.r   N)ra  z9Both input and output are None while trying to push errorz.No valid input or output channel to push error)r  rs  r?  rt  r   r^  r  r  rC   rC   rD   rY  
  s   
zDailyTransport._on_errorr  c                    s4   | j r| j ||I dH  | d||I dH  dS )z"Handle application message events.Nr   )rs  r#  r  r  rC   rC   rD   rZ  
  s   zDailyTransport._on_app_messager  c                    r  )z Handle call state update events.r   Nr  r  rC   rC   rD   r[  
  r  z%DailyTransport._on_call_state_updatedc                    r  )zHandle client connected events.r   Nr  r  rC   rC   rD   r\  
  r  z#DailyTransport._on_client_connectedc                    r  )z"Handle client disconnected events.r   Nr  r  rC   rC   rD   r]  
  r  z&DailyTransport._on_client_disconnectedr  c           	         s  | j jsdS t 4 I dH }d| j j dd}| j jj| j jj|d}| j j d}z]|j|||tj	ddd	4 I dH ?}|j
d
kro| I dH }td|j
 d| d 	 W d  I dH  W W d  I dH  dS td W d  I dH  n1 I dH sw   Y  W n/ tjy   td| d Y n( ty } ztd| d|  W Y d}~nd}~ww W d  I dH  dS W d  I dH  dS W d  I dH  dS 1 I dH sw   Y  dS )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  r0  r   r^  rw   r   TimeoutErrorr  )	rW   r  sessionr  r_  urlrr0  erC   rC   rD   _handle_dialin_ready
  sP   
(".z#DailyTransport._handle_dialin_readyc                    ,   t |  d|  | d|I dH  dS )z Handle dial-in connected events.z dial-in connected: r   Nr   rw   r  r  rC   rC   rD   r^       z#DailyTransport._on_dialin_connectedc                    sD   t |  d|  | jjr| |I dH  | d|I dH  dS )zHandle dial-in ready events.z dial-in ready: Nr   )r   rw   r   r   r  r  r  rC   rC   rD   r_    s
   zDailyTransport._on_dialin_readyc                    r  )zHandle dial-in stopped events.z dial-in stopped: r   Nr  r  rC   rC   rD   r`    r  z!DailyTransport._on_dialin_stoppedc                    r  )zHandle dial-in error events.z dial-in error: r   Nr   r^  r  r  rC   rC   rD   ra    r  zDailyTransport._on_dialin_errorc                    r  )zHandle dial-in warning events.z dial-in warning: r   Nr   r)  r  r  rC   rC   rD   rb  #  r  z!DailyTransport._on_dialin_warningc                    r  )z Handle dial-out answered events.z dial-out answered: r   Nr  r  rC   rC   rD   rc  (  r  z#DailyTransport._on_dialout_answeredc                    r  )z!Handle dial-out connected events.z dial-out connected: r   Nr  r  rC   rC   rD   rd  -  r  z$DailyTransport._on_dialout_connectedc                    r  )zHandle dial-out stopped events.z dial-out stopped: r   Nr  r  rC   rC   rD   re  2  r  z"DailyTransport._on_dialout_stoppedc                    r  )zHandle dial-out error events.z dial-out error: r   Nr  r  rC   rC   rD   rf  7  r  z DailyTransport._on_dialout_errorc                    r  )zHandle dial-out warning events.z dial-out warning: r   Nr  r  rC   rC   rD   rg  <  r  z"DailyTransport._on_dialout_warningc                    sZ   t |  d|  | d|I dH  | jr+tt|d d}| j|I dH  dS dS )zHandle incoming DTMF events.z DTMF event: r   Ntone)rL  )r   rw   r  rs  r   r   r   )rW   r_  r  rC   rC   rD   rh  A  s   zDailyTransport._on_dtmf_eventc                    s   |d }t d|  | jr%| jjr%| jjr%| j|d| jjI dH  | j	s4d| _	| 
d|I dH  | 
d|I dH  | 
d|I dH  | jrU| jt I dH  dS dS )	z!Handle participant joined events.rU  zParticipant joined re  NTrS  r   r   )r   rX  rs  r   r?  r   r  r   r  ru  r  r   r   )rW   r  rU  rC   rC   rD   ri  J  s   

z%DailyTransport._on_participant_joinedc                    sD   |d }t d|  | d||I dH  | d|I dH  dS )zHandle participant left events.rU  zParticipant left r   Nr   )r   rX  r  )rW   r  r  rU  rC   rC   rD   rj  ^  s
   z#DailyTransport._on_participant_leftc                    r  )z"Handle participant updated events.z participant updated: r   N)r   tracer  r  rC   rC   rD   rk  f  r  z&DailyTransport._on_participant_updatedc           
         s  |  d|I dH  d}d|v r|d }|sdS |d }|d }|dd}|di }|d	d
}z|d d d d d }t|}W n tyO   d}Y nw |rht|||||d}	td| d| d n	t|||||d}	||	_| j	r| j	
|	I dH  dS dS )z$Handle transcription message events.r   Nr   participantIdr0  r*  	trackTyperawResponseis_finalFchannelalternativesr   	languages)r  zTranscription (from: z): [r&  )r  r  r(   KeyErrorr"   r   rw   r   r'  rs  r!  )
rW   r  r;   r0  r*  
track_typeraw_responser  r   r  rC   rC   rD   rl  k  s@   z(DailyTransport._on_transcription_messagec                    s6   t |  d| d| d | d||I dH  dS )z$Handle transcription stopped events.z transcription stopped by: z	 (error: r  r   Nr  r  rC   rC   rD   rm    s   z(DailyTransport._on_transcription_stoppedc                    r  )z"Handle transcription error events.z transcription error: r   Nr  r  rC   rC   rD   rn    r  z&DailyTransport._on_transcription_errorc                    r  )z Handle recording started events.z recording started: r   Nr  r  rC   rC   rD   ro    r  z$DailyTransport._on_recording_startedc                    s.   t |  d| d | d|I dH  dS )z Handle recording stopped events.z recording stopped (id: r  r   Nr  r  rC   rC   rD   rp    s   z$DailyTransport._on_recording_stoppedc                    s4   t |  d| d|  | d||I dH  dS )zHandle recording error events.z recording error (id: r  r   Nr  r  rC   rC   rD   rq    s   z"DailyTransport._on_recording_error)NNNr  r;  r  r  )Kr=   r>   r?   r@   rA   r   r   rs   r  rz  r<  r}  r  r   r;   DailyLogLevelr  r   r    r  r   r  r
   r   rS  r  r   r   r  r  r  r  r  r  r  r  r  r  ry   r  r  r  r  r  rU  rV  rW  rX  rY  rZ  r[  r\  r]  r  r^  r_  r`  ra  rb  rc  rd  re  rf  rg  rh  ri  rj  rk  rl  rm  rn  ro  rp  rq  r\   rC   rC   rX   rD   rO    s    Eb		









#	$rO  )jr@   r   r3  concurrent.futuresr   r  r   dataclassesr   r   typingr   r   r   r	   r
   r   r   r  logurur   pydanticr   pipecat.audio.dtmf.typesr   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$   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/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r  ModuleNotFoundErrorr  r^  r  ru   r:   rF   rH   r^   r_   r`   rb   ri   rj   rl   r   r   r   r   r   r   r   r   r   rA   r   r   r  r<  rO  rC   rC   rC   rD   <module>   s   $X0



+B         ]  6 5