
    &2j                        d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlmZ ddlmZ  ed          ZdZd	\  ZZZZd
\  ZZdZdZdZd/dZefd0dZd1dZd2dZd3d Zd! Zd4d(Z d5d6d+Z!d7d-Z"d5d8d.Z#dS )9uF  火山引擎(豆包)大模型流式语音识别 ASR —— V3 WebSocket 二进制协议。

文档:wss://openspeech.bytedance.com/api/v3/sauc/bigmodel(用户提供)。
对外:`recognize(pcm_bytes, rate=16000) -> text`(同步,内部 asyncio)。输入须 16k/16bit/单声道 PCM。
鉴权(旧版):X-Api-App-Key(=appid)+ X-Api-Access-Key + X-Api-Resource-Id(volc.bigasr.sauc.duration)。
帧:4B header [+seq int32(大端)] + payload_size(uint32) + payload(gzip);full-client=JSON,audio=raw。
最后一包音频用 flags=0b0011(负 seq)标记;响应里 flags 含 0b0010 即最终包。
    )annotationsN)Path)Optional)
get_loggerz	voice.asrz3wss://openspeech.bytedance.com/api/v3/sauc/bigmodel)      	      )r   r   r      returntuple[str, str]c                 d   t          j        d          t          j        d          }} | r|st          t                                                    j        d         dz  }|                                r|                    d                                          D ]}}|	                                }|
                    d          r| p|                    dd	          d	         } J|
                    d
          r|p|                    dd	          d	         }~| r|st          d          | |fS )NVOLC_APP_IDVOLC_ACCESS_TOKENr   z.envutf-8)encodingzVOLC_APP_ID==r   zVOLC_ACCESS_TOKEN=u3   缺少 VOLC_APP_ID / VOLC_ACCESS_TOKEN(请配 .env))osgetenvr   __file__resolveparentsexists	read_text
splitlinesstrip
startswithsplitRuntimeError)appidtokenenvflns       1/root/genesis-world/src/genesis/voice/volc_asr.py_credsr%   "   s)   9]++RY7J-K-K5E 9e 9H~~%%''/2V;;;== 	9nngn66AACC 9 9XXZZ==00 9!8RXXc1%5%5a%8EE]]#788 9!8RXXc1%5%5a%8E Re RPQQQ%<    msg_typeintflagsserialcompressbytesc                @    t          d| dz  |z  |dz  |z  dg          S )N      r   )r,   )r'   r)   r*   r+   s       r$   _hdrr0   2   s.    (8q=E*AFaKS[C[]^_```r&   paramsdictc                0   t          j        t          j        | d                              d                    }t          t          t          t                    t          j
        dd          z   t          j
        dt          |                    z   |z   S )NF)ensure_asciir   >ir   >I)gzipr+   jsondumpsencoder0   MT_FULL_CLIENTFLAG_POS_SEQSER_JSONstructpacklen)r1   payloads     r$   _full_clientrB   6   su    mDJvEBBBII'RRSSGh77&+dA:N:NN
+dCLL
)
)*,34 4r&   chunkseqlastboolc                   |rt           nt          }|r| n|}t          j        |           }t	          t
          |t                    t          j        d|          z   t          j        dt          |                    z   |z   S )Nr5   r6   )
FLAG_LAST_SEQr<   r7   r+   r0   MT_AUDIOSER_RAWr>   r?   r@   )rC   rD   rE   r)   srA   s         r$   _audiorL   <   sv    !3MM|E#AmE""G%))FKa,@,@@
+dCLL
)
)*,34 4r&   datac                   | d         dz	  dz  }| d         dz  }| d         dz  }d}|t           k    rzt          j        d| ||dz                      d         }|dz  }t          j        d| ||dz                      d         }|dz  }|| |||z                                dd          d	S |t          z  r|dz  }t          j        d| ||dz                      d         }|dz  }| |||z            }|t
          k    r|rt          j        |          }|r't          j	        |                    d                    ni }|t          |dz            d
S )Nr   r/   r
   r   r6   r   r   ignore)errormsg)objrE   )MT_ERRORr>   unpackdecoder<   GZIPr7   
decompressr8   loadsrF   )	rM   r'   r)   r+   offcodesizerA   rR   s	            r$   _parser\   D   sp   Q1$HGdNEAw~H
C8}T4C!G#455a8#(#}T4C!G#455a8#(#d3sTz>&:&A&A'8&T&TUUU| q=tCaK011!4DcQhc3sTz>"G4G/'**18
@$*W^^G,,
-
-
-bCUV^ 4 4555r&   c                   K   dd l }	 |                    t          | d            d {V S # t          $ r& |                    t          | d            d {V cY S w xY w)Nr   )additional_headersmax_size)extra_headersr_   )
websocketsconnectWS_URL	TypeError)headersra   s     r$   _connectrf   W   s      V''7UY'ZZZZZZZZZ V V V''gPT'UUUUUUUUUUUVs   "+ -AApcmrater    strr!   resource_idc                   	
K   |||t          t          j                              t          t          j                              d}ddid|ddddd	d	d
d
t          dt	          |dz  dz                       fdt          dt                               D             pdg	ddit          |           d {V 	
fd}fd}	 t          j	         |             |                       d {V  
                                 d {V  n# 
                                 d {V  w xY wd         S )NzX-Api-App-KeyzX-Api-Access-KeyzX-Api-Resource-IdzX-Api-Request-IdzX-Api-Connect-Iduidgenesisrg      r   formatrh   bitschannelbigmodelT
model_name
enable_itnenable_puncuseraudiorequestr   g?c                *    g | ]}||z            S  r~   ).0irC   rg   s     r$   
<listcomp>z_recognize.<locals>.<listcomp>f   s&    BBB1c!AI+BBBr&   r   r&   text c                 D  K                        t                               d {V  d} t                    D ]b\  }}| dz  }                      t          || |t	                    dz
  k                         d {V  t          j        d           d {V  cd S )Nr   gQ?)sendrB   	enumeraterL   r@   asynciosleep)rD   idxchchunksr1   wss      r$   senderz_recognize.<locals>.senderj   s      ggl6**+++++++++ (( 	& 	&GC1HC''&S#Vq*@AABBBBBBBBB-%%%%%%%%%%	& 	&r&   c                 6  K   	 t                                           d {V           } d| v r)t          d| d          d| d         d d                    | d                             d          pi                     d	          }|r|d	<   | d
         rd S )NTrP   u   ASR 错误 z: rQ      rR   resultr   rE   )r\   recvr   get)rtr   r   s     r$   receiverz_recognize.<locals>.receiverr   s      	RWWYY''A!||"#O7#O#Oqx~#O#OPPP5h''-2226::A #!"vy 	r&   )ri   uuiduuid4maxr(   ranger@   rf   r   gatherclose)rg   rh   r    r!   rj   re   r   r   rC   r   r1   r   r   s   `       @@@@@r$   
_recognizer   _   s      %5Wb#&tz||#4#4#djllJ[J[] ]Gi("'raPP(2$W[\\^ ^F 3tax#~&&''EBBBBBaS5(A(ABBBKseFb\F  	 	 	 	 	 	 B& & & & & & &	 	 	 	 	 	nVVXXxxzz222222222hhjjbhhjj&>s   +D D8>  Optional[str]c           	         t                      \  }}|pt          j        d          pd}t          j        t          | ||||                    S )u{   16k/16bit/单声道 PCM → 识别文本(同步)。resource_id 默认 VOLC_ASR_RESOURCE_ID 或 volc.bigasr.sauc.duration。VOLC_ASR_RESOURCE_IDvolc.bigasr.sauc.duration)r%   r   r   r   runr   )rg   rh   rj   r    r!   rids         r$   	recognizer      sJ    88LE5

Y#9::
Y>YC;z#tUE3??@@@r&   Nonec                d   K   	 |                      |           d {V  d S # t          $ r Y d S w xY w)N)r   	Exception)r   rM   s     r$   
_safe_sendr      sU      ggdmm   s   ! 
//c                   
K   t                      \  }}|pt          j        d          pd}|||t          t	          j                              t          t	          j                              d}ddid|ddd	d
dddd}t          |           d{V ddi
d	                     t          |                     d{V   fd} 
fd}	t          j
         |             |	                       d{V  	                                  d{V  n@# t          $ r Y n4w xY w# 	                                  d{V  w # t          $ r Y w w xY wxY w
d         S )ud  全流式桥:浏览器 WS 边说边送 PCM,火山的中间识别结果实时回传浏览器(真·边说边出字)。

    client_ws:服务端 websockets 连接 —— 二进制帧=一段 16k/16bit 单声道 PCM;文本帧(如 {"event":"stop"})=收尾。
    每收到火山一版累计文本就回传 {"text": "...", "last": bool};返回最终文本。
    r   r   rl   rm   rn   rg   ro   r   rp   rt   Tru   ry   Nr   r   c                   K   	 2 3 d {V } t          | t          t          f          r>dz                      t	          t          |           d                     d {V  a n6 n# t
          $ r Y nw xY wdz  	                     t	          dd                     d {V  d S # t
          $ r Y d S w xY w)Nr   F)rE   r&   T)
isinstancer,   	bytearrayr   rL   r   )rQ   	client_wsrD   volcs    r$   to_volczrelay.<locals>.to_volc   s&     !*       #!#y'9:: q"iiuSzz3U(K(K(KLLLLLLLLLL "+    1HCiisCd ; ; ;<<<<<<<<<<<   s.   A, A*AA, ,
A98A9+B/ /
B=<B=c                   K   	 	 t                                           d {V           } d| v r2t          t          j        d| d         i                     d {V  d S | d                             d          pi                     d          }|r|d<   t          t          j        |pd| d         d	                     d {V  | d         rd S # t          $ r Y d S w xY w)
NTrP   rQ   rR   r   r   r   rE   )r   rE   )r\   r   r   r8   r9   r   r   )r   r   r   finalr   s     r$   	from_volczrelay.<locals>.from_volc   s.     	TYY[[00000011A!||(DJ5?R4S4STTTTTTTTTV[V[5h//52::6BBA *()f$Y
AGUVW]U^;_;_0`0`aaaaaaaaay 	    s   AC #A2C C 
C&%C&)r%   r   r   ri   r   r   rf   r   rB   r   r   r   r   )r   rh   rj   r    r!   r   re   r1   r   r   r   rD   r   s   `         @@@r$   relayr      s      88LE5

Y#9::
Y>YC %5WZ#&tz||#4#4#djllJ[J[] ]Gi("'raPP(2$W[\\^ ^F '""""""""DRLE
C(iiV,,---------	 	 	 	 	 	 	"	 	 	 	 	 	 	 nWWYY		444444444	**,, 	 	 	D		**,, 	 	 	D	=sC   !A!D. D 
D+*D+.E0E
E
EEEE)r   r   )
r'   r(   r)   r(   r*   r(   r+   r(   r   r,   )r1   r2   r   r,   )rC   r,   rD   r(   rE   rF   r   r,   )rM   r,   r   r2   )rg   r,   rh   r(   r    ri   r!   ri   rj   ri   r   ri   )r   N)rg   r,   rh   r(   rj   r   r   ri   )r   r   )rh   r(   rj   r   r   ri   )$__doc__
__future__r   r   r7   r8   r   r>   r   pathlibr   typingr   genesis.obs.logging_setupr   loggerrc   r;   rI   MT_FULL_SERVERrS   r=   rJ   rV   r<   rH   r%   r0   rB   rL   r\   rf   r   r   r   r   r~   r&   r$   <module>r      s    # " " " " "    				               0 0 0 0 0 0	K	 	 	>5S 2.(" '     BF a a a a a4 4 4 44 4 4 46 6 6 6&V V V" " " "JA A A A A   9 9 9 9 9 9 9r&   