
    qi#                         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 ddl	m
Z
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 ddlmZ  G d	 d
e      Zy)z5Plivo WebSocket frame serializer for audio streaming.    N)Optional)logger)KeypadEntry)create_stream_resamplerpcm_to_ulawulaw_to_pcm)
AudioRawFrameCancelFrameEndFrameFrameInputAudioRawFrameInputDTMFFrameInterruptionFrameOutputTransportMessageFrame!OutputTransportMessageUrgentFrame
StartFrame)FrameSerializerc                        e Zd ZdZ G d dej
                        Z	 	 	 	 ddedee   dee   dee   d	ee   f
 fd
Zde	fdZ
dedeez  dz  fdZd Zdeez  dedz  fdZ xZS )PlivoFrameSerializera  Serializer for Plivo Audio Streaming WebSocket protocol.

    This serializer handles converting between Pipecat frames and Plivo's WebSocket
    audio streaming protocol. It supports audio conversion, DTMF events, and automatic
    call termination.

    When auto_hang_up is enabled (default), the serializer will automatically terminate
    the Plivo call when an EndFrame or CancelFrame is processed, but requires Plivo
    credentials to be provided.
    c                   B    e Zd ZU dZdZeed<   dZee   ed<   dZ	e
ed<   y) PlivoFrameSerializer.InputParamsa  Configuration parameters for PlivoFrameSerializer.

        Parameters:
            plivo_sample_rate: Sample rate used by Plivo, defaults to 8000 Hz.
            sample_rate: Optional override for pipeline input sample rate.
            auto_hang_up: Whether to automatically terminate call on EndFrame.
            ignore_rtvi_messages: Inherited from base FrameSerializer, defaults to True.
        i@  plivo_sample_rateNsample_rateTauto_hang_up)__name__
__module____qualname____doc__r   int__annotations__r   r   r   bool     K/opt/pipecat/venv/lib/python3.12/site-packages/pipecat/serializers/plivo.pyInputParamsr   ,   s,    	 "&3%%)Xc])!d!r#   r%   N	stream_idcall_idauth_id
auth_tokenparamsc                    t         |   |xs t        j                                || _        || _        || _        || _        | j                  j                  | _
        d| _        t               | _        t               | _        d| _        y)ay  Initialize the PlivoFrameSerializer.

        Args:
            stream_id: The Plivo Stream ID.
            call_id: The associated Plivo Call ID (optional, but required for auto hang-up).
            auth_id: Plivo auth ID (required for auto hang-up).
            auth_token: Plivo auth token (required for auto hang-up).
            params: Configuration parameters.
        r   FN)super__init__r   r%   
_stream_id_call_id_auth_id_auth_token_paramsr   _plivo_sample_rate_sample_rater   _input_resampler_output_resampler_hangup_attempted)selfr&   r'   r(   r)   r*   	__class__s         r$   r-   zPlivoFrameSerializer.__init__:   sv    " 	E#7#C#C#EF#%"&,,"@"@ 7 9!8!:!&r#   framec                 ^   K   | j                   j                  xs |j                  | _        yw)zSets up the serializer with pipeline configuration.

        Args:
            frame: The StartFrame containing pipeline configuration.
        N)r2   r   audio_in_sample_rater4   )r8   r:   s     r$   setupzPlivoFrameSerializer.setupY   s%      !LL44R8R8Rs   +-returnc                 ,  K   | j                   j                  rB| j                  s6t        |t        t
        f      r d| _        | j                          d{    yt        |t              r$d| j                  d}t        j                  |      S t        |t              r|j                  }t        ||j                  | j                  | j                          d{   }|t#        |      dk(  ryt%        j&                  |      j)                  d      }dd| j                  |d	| j                  d
}t        j                  |      S t        |t*        t,        f      r1| j/                  |      ryt        j                  |j0                        S y7 :7 w)a  Serializes a Pipecat frame to Plivo WebSocket format.

        Handles conversion of various frame types to Plivo WebSocket messages.
        For EndFrames, initiates call termination if auto_hang_up is enabled.

        Args:
            frame: The Pipecat frame to serialize.

        Returns:
            Serialized data as string or bytes, or None if the frame isn't handled.
        TN
clearAudio)eventstreamIdr   zutf-8	playAudiozaudio/x-mulaw)contentType
sampleRatepayload)rA   mediarB   )r2   r   r7   
isinstancer   r
   _hang_up_callr   r.   jsondumpsr	   audior   r   r3   r6   lenbase64	b64encodedecoder   r   should_ignore_framemessage)r8   r:   answerdataserialized_datarF   s         r$   	serializezPlivoFrameSerializer.serializea   sa     LL%%**58["9:%)D"$$&&&01+IF::f%%}-;;D %0e'')@)@$BXBX% O &#o*>!*C&&7>>wGG$#2"&"9"9&
 !OOF ::f%% ;=^_`''.::emm,, E 's&   AFFBFFB5FFc           
        K   	 ddl }| j                  }| j                  }| j                  }|r|r|scg }|s|j	                  d       |s|j	                  d       |s|j	                  d       t        j                  ddj                  |              yd| d	| d
}|j                  ||      }|j                         4 d{   }|j                  ||      4 d{   }	|	j                  dk(  rt        j                  d|        ni|	j                  dk(  rt        j                  d| d       n@|	j                          d{   }
t        j                  d| d|	j                   d|
        ddd      d{    ddd      d{    y7 7 7 Q7 # 1 d{  7  sw Y   +xY w7 "# 1 d{  7  sw Y   yxY w# t        $ r"}t        j                  d|        Y d}~yd}~ww xY ww)z.Hang up the Plivo call using Plivo's REST API.r   Nr'   r(   r)   z8Cannot hang up Plivo call: missing required parameters: z, z!https://api.plivo.com/v1/Account/z/Call//)auth   z#Successfully terminated Plivo call i  zPlivo call z already terminatedzFailed to terminate Plivo call z	: Status z, Response: zFailed to hang up Plivo call: )aiohttpr0   r1   r/   appendr   warningjoin	BasicAuthClientSessiondeletestatusdebugtexterror	Exception)r8   r[   r(   r)   r'   missingendpointrY   sessionresponse
error_textes               r$   rI   z"PlivoFrameSerializer._hang_up_call   s    +	?mmG))JmmG'NN9-NN9-!NN<0NtyyY`OaNbc  ;7)6'RSTH $$Wj9D ,,.  '">>(>>  (#-'J7)%TU!C/{7);N%OP ,4==?%:
=gY G&&.oo%6l:,P    &;        	?LL9!=>>	?s   G9BG G9/G FG F6 F!F6$A%F	F
,F6F6FF6G F4G G9G F6FF6F1	%F(&F1	-F64G 6G<F?=GG G9G 	G6G1,G91G66G9rT   c                   K   	 t        j                  |      }|j                  d      dk(  r|j                  di       }|j                  d      }|syt        j                  |      }t        || j                  | j                  | j                         d{   }|t        |      dk(  ryt        |d| j                        }|S |j                  d      d	k(  r;|j                  d	i       }|j                  d
      }	|	r	 t        t        |	            S yy# t         j                  $ r t        j                  d|        Y yw xY w7 # t         $ r t        j                  d|	        Y yw xY ww)a8  Deserializes Plivo WebSocket data to Pipecat frames.

        Handles conversion of Plivo media events to appropriate Pipecat frames.

        Args:
            data: The raw WebSocket data from Plivo.

        Returns:
            A Pipecat frame corresponding to the Plivo event, or None if unhandled.
        zFailed to parse JSON message: NrA   rG   rF   r      )rL   num_channelsr   dtmfdigitzInvalid DTMF digit received: )rJ   loadsJSONDecodeErrorr   r]   getrN   	b64decoder   r3   r4   r5   rM   r   r   r   
ValueError)
r8   rT   rR   rG   payload_base64rF   deserialized_dataaudio_frame	dtmf_datarq   s
             r$   deserializez PlivoFrameSerializer.deserialize   sp    	jj&G
 ;;w7*KK,E"YYy1N!&&~6G '200$2C2CTEZEZ' ! !(C0A,Ba,G,'aTEVEVK [[!V+FB/IMM'*E )+e*<==  I ## 	NN;D6BC	!" "  NN%B5'#JK sY   E1D A>E1EA(E1E
 E1+EE1EE1
!E.+E1-E..E1)NNNN)r   r   r   r   r   r%   strr   r-   r   r=   r   bytesrV   rI   r{   __classcell__)r9   s   @r$   r   r       s    	"o11 "" "&!%$((,'' #' #	'
 SM' %'>S S4U 4sU{T/A 4l-?^1cEk 1edl 1r#   r   )r   rN   rJ   typingr   logurur   pipecat.audio.dtmf.typesr   pipecat.audio.utilsr   r   r   pipecat.frames.framesr	   r
   r   r   r   r   r   r   r   r   #pipecat.serializers.base_serializerr   r   r"   r#   r$   <module>r      sB    <     0 Q Q   @W? Wr#   