o
    i$                  
   @   s`  d Z ddlZddlZddlmZ ddlmZ ddlZ	ddl
mZ ddlmZmZmZmZ ddlmZ ddlmZ dd	lmZmZ zddlZW n  eyf Z zed
e  ed ede dZ[ww zddlZW n  ey Z zed
e  ed ede dZ[ww G dd deZG dd deZG dd deZG dd deZ dS )zTkinter-based local transport implementation for Pipecat.

This module provides a local transport using Tkinter for video display and
PyAudio for audio I/O, suitable for desktop applications and testing.
    N)ThreadPoolExecutor)Optional)logger)InputAudioRawFrameOutputAudioRawFrameOutputImageRawFrame
StartFrame)BaseInputTransport)BaseOutputTransport)BaseTransportTransportParamszException: z~In order to use local audio, you need to `pip install pipecat-ai[local]`. On MacOS, you also need to `brew install portaudio`.zMissing module: zOtkinter missing. Try `apt install python3-tk` or `brew install python-tk@3.10`.c                   @   s2   e Zd ZU dZdZee ed< dZee ed< dS )TkTransportParamsa  Configuration parameters for Tkinter transport.

    Parameters:
        audio_input_device_index: PyAudio device index for audio input. If None, uses default.
        audio_output_device_index: PyAudio device index for audio output. If None, uses default.
    Naudio_input_device_indexaudio_output_device_index)	__name__
__module____qualname____doc__r   r   int__annotations__r    r   r   O/home/ubuntu/.local/lib/python3.10/site-packages/pipecat/transports/local/tk.pyr   0   s   
 r   c                       s\   e Zd ZU dZeed< dejdef fddZde	f fdd	Z
 fd
dZdd Z  ZS )TkInputTransportzTkinter-based audio input transport.

    Captures audio from the system's audio input device using PyAudio and
    converts it to InputAudioRawFrame objects for pipeline processing.
    _paramspy_audioparamsc                    s"   t  | || _d| _d| _dS )zInitialize the Tkinter input transport.

        Args:
            py_audio: PyAudio instance for audio device management.
            params: Transport configuration parameters.
        Nr   )super__init__	_py_audio
_in_stream_sample_rate)selfr   r   	__class__r   r   r   E   s   
zTkInputTransport.__init__framec              	      s   t  |I dH  | jrdS | jjp|j| _t| jd d }| jj| j	d| jj
| j|| jd| jjd| _| j  | |I dH  dS )z~Start the audio input stream.

        Args:
            frame: The start frame containing initialization parameters.
        Nd      T)formatchannelsrateframes_per_bufferstream_callbackinputinput_device_index)r   startr   r   audio_in_sample_rater    r   r   openget_format_from_widthaudio_in_channels_audio_in_callbackr   start_streamset_transport_ready)r!   r$   
num_framesr"   r   r   r.   Q   s"   

	zTkInputTransport.startc                    :   t   I dH  | jr| j  | j  d| _dS dS )z(Stop and cleanup the audio input stream.N)r   cleanupr   stop_streamcloser!   r"   r   r   r8   l      


zTkInputTransport.cleanupc                 C   s4   t || j| jjd}t| ||   dtj	fS )z+Callback function for PyAudio input stream.)audiosample_ratenum_channelsN)
r   r    r   r2   asynciorun_coroutine_threadsafepush_audio_frameget_event_looppyaudio
paContinue)r!   in_dataframe_count	time_infostatusr$   r   r   r   r3   t   s   
z#TkInputTransport._audio_in_callback)r   r   r   r   r   r   rD   PyAudior   r   r.   r8   r3   __classcell__r   r   r"   r   r   <   s   
 r   c                       s   e Zd ZU dZeed< dejdej	def fddZ
def fd	d
Z 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  ZS )TkOutputTransportzTkinter-based audio and video output transport.

    Plays audio through PyAudio and displays video frames in a Tkinter window,
    providing a complete multimedia output solution for desktop applications.
    r   tk_rootr   r   c                    s   t  | || _d| _d| _tdd| _tdd }dd d	d d
	 |
tj  }tjdd|dd}tj||d| _| j  dS )zInitialize the Tkinter output transport.

        Args:
            tk_root: The root Tkinter window for video display.
            py_audio: PyAudio instance for audio device management.
            params: Transport configuration parameters.
        Nr      )max_workers)   rP         zP5 rP     255 PPMwidthheightdatar'   image)r   r   r   _out_streamr    r   	_executornponesencodeastypeuint8tobytestk
PhotoImageLabel_image_labelpack)r!   rM   r   r   arrayrY   photor"   r   r   r      s   &zTkOutputTransport.__init__r$   c                    sv   t  |I dH  | jrdS | jjp|j| _| jj| jd| jj	| jd| jj
d| _| j  | |I dH  dS )zStart the audio output stream.

        Args:
            frame: The start frame containing initialization parameters.
        Nr&   T)r'   r(   r)   outputoutput_device_index)r   r.   r\   r   audio_out_sample_rater    r   r0   r1   audio_out_channelsr   r4   r5   r!   r$   r"   r   r   r.      s   

zTkOutputTransport.startc                    r7   )z)Stop and cleanup the audio output stream.N)r   r8   r\   r9   r:   r;   r"   r   r   r8      r<   zTkOutputTransport.cleanupreturnc                    s0   | j r|  | j| j j|jI dH  dS dS )zWrite an audio frame to the output stream.

        Args:
            frame: The audio frame to write to the output device.

        Returns:
            True if the audio frame was written successfully, False otherwise.
        NTF)r\   rC   run_in_executorr]   writer=   ro   r   r   r   write_audio_frame   s   	
z#TkOutputTransport.write_audio_framec                    s   |   | j| dS )zWrite a video frame to the Tkinter display.

        Args:
            frame: The video frame to display in the Tkinter window.

        Returns:
            True if the video frame was written successfully, False otherwise.
        T)rC   	call_soon_write_frame_to_tkro   r   r   r   write_video_frame   s   	z#TkOutputTransport.write_video_framec                 C   s\   |j d }|j d }d| d| d |j }tj|||dd}| jj|d || j_d	S )
z,Write frame data to the Tkinter image label.r   rN   zP6 rS   rT   rU   rV   rZ   N)sizer`   r[   rd   re   rg   config)r!   r$   rW   rX   rY   rj   r   r   r   ru      s   

z$TkOutputTransport._write_frame_to_tk)r   r   r   r   r   r   rd   TkrD   rJ   r   r   r.   r8   r   boolrs   r   rv   ru   rK   r   r   r"   r   rL      s   
 rL   c                       sH   e Zd ZdZdejdef fddZdefddZ	de
fd	d
Z  ZS )TkLocalTransportzComplete Tkinter-based local transport with audio and video capabilities.

    Provides a unified interface for local multimedia I/O using Tkinter for video
    display and PyAudio for audio, suitable for desktop applications and testing.
    rM   r   c                    s0   t    || _|| _t | _d| _d| _dS )zInitialize the Tkinter local transport.

        Args:
            tk_root: The root Tkinter window for video display.
            params: Transport configuration parameters.
        N)	r   r   _tk_rootr   rD   rJ   _pyaudio_input_output)r!   rM   r   r"   r   r   r      s   


zTkLocalTransport.__init__rp   c                 C   s   | j st| j| j| _ | j S )zGet the input frame processor for this transport.

        Returns:
            The Tkinter input transport processor.
        )r~   r   r}   r   r;   r   r   r   r,     s   zTkLocalTransport.inputc                 C   s    | j st| j| j| j| _ | j S )zGet the output frame processor for this transport.

        Returns:
            The Tkinter output transport processor.
        )r   rL   r|   r}   r   r;   r   r   r   rk     s   zTkLocalTransport.output)r   r   r   r   rd   ry   r   r   r   r,   rL   rk   rK   r   r   r"   r   r{      s
    
r{   )!r   r@   tkinterrd   concurrent.futuresr   typingr   numpyr^   logurur   pipecat.frames.framesr   r   r   r   pipecat.transports.base_inputr	   pipecat.transports.base_outputr
   !pipecat.transports.base_transportr   r   rD   ModuleNotFoundErroreerror	Exceptionr   r   rL   r{   r   r   r   r   <module>   sB   
Ej