
    `gj[$                    P    d Z ddlmZ ddlZddlZddlmZ dZ G d d      Zd	dZ	y)
a@  Virtual audio bridge for feeding generated speech into Chrome's mic.

v2 module. Provisions a platform-specific virtual audio device so the
Meet bot's Chromium instance can be pointed at an input source we
control. The OpenAI Realtime client writes PCM bytes into this device;
Chrome reads them as if they were coming from a microphone.

Linux (primary): uses pactl (PulseAudio) to create a null-sink plus a
virtual source whose master is the null-sink's monitor. Callers set
PULSE_SOURCE=<source_name> in Chrome's env and pass the fake-mic flag.

macOS: requires BlackHole 2ch to be installed. This module only
verifies its presence and returns the device name; routing OS default
input is left to the user (or a future switchaudio-osx integration) to
avoid surprising the user's system audio state.

Windows: not supported in v2.
    )annotationsN)OptionalzBlackHole 2chc                  p    e Zd ZdZdddZedd       Zedd       ZddZddZ	ddZ
ddZedd	       Zy
)AudioBridgezManages a virtual audio device for Chrome fake-mic input.

    Call ``setup()`` once before launching the Meet bot and
    ``teardown()`` when the session ends. ``teardown()`` is idempotent.
    c                X    || _         d | _        d | _        d | _        g | _        d| _        y )NF)_name_prefix	_platform_device_name_write_target_module_ids
_torn_down)selfname_prefixs     S/root/.hermes/venv/lib/python3.12/site-packages/plugins/google_meet/audio_bridge.py__init__zAudioBridge.__init__%   s0    '(,+/,0&(    c                H    | j                   st        d      | j                   S NzAudioBridge not set up yet)r
   RuntimeErrorr   s    r   device_namezAudioBridge.device_name/   s#      ;<<   r   c                H    | j                   st        d      | j                   S r   )r   r   r   s    r   write_targetzAudioBridge.write_target5   s#    !!;<<!!!r   c                    t        j                         }|dk(  r| j                         S |dk(  r| j                         S |dk(  rt	        d      t	        d|       )zProvision the virtual audio device.

        Returns a dict describing the device. Raises RuntimeError on
        unsupported platforms or when required system tools are missing.
        LinuxDarwinWindowswindows not supported in v2unsupported platform: )platformsystem_setup_linux_setup_darwinr   )r   r!   s     r   setupzAudioBridge.setup=   se     "W$$&&X%%''Y<==3F8<==r   c                *   | j                   ry| j                  dk(  ra| j                  rUt        | j                        D ]6  }	 t	        j
                  ddt        |      gddt        j                         8 g | _        d| _         y# t        $ r Y Sw xY w)z-Release the virtual audio device. Idempotent.Nlinuxpactlunload-moduleFTcheckcapture_outputstdin)	r   r	   r   reversed
subprocessrunstrDEVNULL	Exception)r   mod_ids     r   teardownzAudioBridge.teardownL   s    ??>>W$)9)9"4#3#34 
	NN /3v;?#'+(00	
  "D	 ! s   3B	BBc           	     n   | j                    d}| j                    d}	 t        j                  dddd| dgdddt        j                  	      }| j                  |j                        }	 t        j                  dddd| d| dgdddt        j                  	      }| j                  |j                        }d| _        || _        || _        ||g| _        d| _        d|ddt!        | j                        |dS # t        $ r}t        d
      |d }~wt        j                  $ r"}t        d|j                  xs |       |d }~ww xY w# t        j                  $ rU}t        j                  ddt        |      gddt        j                         t        d|j                  xs |       |d }~ww xY w)N_sink_srcr'   zload-modulezmodule-null-sinkz
sink_name=z1sink_properties=device.description=HermesMeetSinkT)r*   r+   textr,   u5   pactl not found — install PulseAudio/pipewire-pulsez$pactl load-module null-sink failed: zmodule-virtual-sourcezsource_name=zmaster=z.monitorr(   Fr)   z)pactl load-module virtual-source failed: r&   逻     r    r   sample_ratechannels
module_idsr   )r   r.   r/   r1   FileNotFoundErrorr   CalledProcessErrorstderr_parse_module_idstdoutr0   r	   r
   r   r   r   list)r   	sink_namesrc_namesink_outexcsink_mod_idsrc_out
src_mod_ids           r   r"   zAudioBridge._setup_linuxc   s   (()/	''(-	!~~!& ,G # ((H, ++HOO<	 nn!+"8*-i[1 # ((G2 **7>>:
 $&'4  # t//0%
 	
[ ! 	G ,, 	6szz7HS6IJ	* ,, 
	NN/3{+;<# ((	 ;CJJ<M#;NO
	s<   0C< ,4E <	E	DE	'EE	F4AF//F4c                   	 t        j                  ddgdt         j                        }d|vrt	        d      d	| _        t        | _	        t        | _
        g | _        d
| _        d	t        ddg t        dS # t        $ r}t	        d      |d }~wt         j
                  $ r}t	        d|j                         |d }~ww xY w)Nsystem_profilerSPAudioDataTypeT)r8   rA   z.system_profiler not found (macOS-only command)zsystem_profiler failed: 	BlackHolezUBlackHole virtual audio device not installed. Install via: brew install blackhole-2chdarwinFr9   r:   r;   )r.   check_outputSTDOUTr?   r   r@   outputr	   _BLACKHOLE_DEVICEr
   r   r   r   )r   outrH   s      r   r#   zAudioBridge._setup_darwin   s    	))"$56!((C c!: 
 "-. !, -
 	
+ ! 	@ ,, 	*3::,7	s#   (A5 5	B>>B

B> B99B>c                   | xs dj                         }|st        d      |j                         d   j                         }|j                         d   }	 t	        |      S # t
        $ r}t        d|       |d}~ww xY w)z5pactl load-module prints the new module ID to stdout. z'pactl load-module returned empty stdoutr   z&could not parse pactl module id from: N)stripr   
splitlinessplitint
ValueError)rC   r8   firsttokenrH   s        r   rB   zAudioBridge._parse_module_id   s     "##%HII!!$**,b!	u: 	8
C	s   
A" "	A?+A::A?N)hermes_meet)r   r0   returnNone)ra   r0   )ra   dict)ra   rb   )rC   r0   ra   r\   )__name__
__module____qualname____doc__r   propertyr   r   r$   r4   r"   r#   staticmethodrB    r   r   r   r      s_      ! !
 " ">.F
P#
N  r   r   c                    t        j                         }|dk(  rdgS |dk(  rdgS |dk(  rt        d      t        d|       )a  Return Chrome flags for using the fake audio input.

    The PulseAudio source is selected via the ``PULSE_SOURCE`` env var,
    which callers must set in Chrome's environment before launch:

        env["PULSE_SOURCE"] = bridge_info["device_name"]

    On macOS the caller must ensure the system default audio input is
    set to the returned BlackHole device (we do not flip that switch).
    r   z--use-fake-ui-for-media-streamr   r   r   r   )r    r!   r   )bridge_infor!   s     r   chrome_fake_audio_flagsrm      s[     __F 111011899
/x8
99r   )rl   rc   ra   z	list[str])
rg   
__future__r   r    r.   typingr   rT   r   rm   rj   r   r   <module>rp      s2   & #    $ B BJ:r   