рдХреЙрдиреНрдЯреЗрдВрдЯ рдкрд░ рдЬрд╛рдПрдВ

рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ 200ms рд╕реЗ рдХрдо рдореЗрдВ: рдПрдХ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдЧрд╛рдЗрдб

рд▓реЗрдЦрдХ
Tadas Petra
Jack Limebear
рдкреНрд░рдХрд╛рд╢рд┐рдд
рдЖрдЦрд┐рд░реА рдмрд╛рд░ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛

рд╕реБрдиреЗрдВрдЗрд╕ рдЖрд░реНрдЯрд┐рдХрд▓ рдХреЛ рд╕реБрдиреЗрдВ

рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ (STT) рдСрдбрд┐рдпреЛ рдХреЛ рдЙрд╕реА рд╕рдордп рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд╛рдЗрдм рдХрд░рддрд╛ рд╣реИ рдЬрдм рдХреЛрдИ рдмреЛрд▓рддрд╛ рд╣реИ, рдФрд░ рдХреБрдЫ рд╣реА рд╕реМ рдорд┐рд▓реАрд╕реЗрдХрдВрдб рдореЗрдВ рдЙрдирдХреЗ рд╢рдмреНрдж рдЯреЗрдХреНрд╕реНрдЯ рдореЗрдВ рдмрджрд▓ рджреЗрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди STT рдХреА рд▓реЗрдЯреЗрдВрд╕реА рдХрдо рд░рдЦрдирд╛ рд╕рд┐рд░реНрдл рдореЙрдбрд▓ рдХрд╛ рдирд╣реАрдВ, рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХрд╛ рднреА рд╕рд╡рд╛рд▓ рд╣реИред рдЗрдВрдЬреАрдирд┐рдпрд░реНрд╕ рдХреЛ рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ, рдЪрдВрдХрд┐рдВрдЧ, рдПрдВрдб-рдкреЙрдЗрдВрдЯрд┐рдВрдЧ рдФрд░ рдХреИрдкреНрдЪрд░ рдкрд╛рдетАФрд╣рд░ рд╕реНрдЯреЗрдктАФрдХреА рдкреНрд▓рд╛рдирд┐рдВрдЧ рдХрд░рдиреА рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣рд░ рдПрдХ рд▓реЗрдЯреЗрдВрд╕реА рдмрдврд╝рд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрдирдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рднреА рд╣рд┐рд╕реНрд╕реЗ рдореЗрдВ рдЧрдбрд╝рдмрдбрд╝реА рдЖрдкрдХреЗ 200ms рдХреЗ рдмрдЬрдЯ рдХреЛ рдмрд┐рдЧрд╛рдбрд╝ рд╕рдХрддреА рд╣реИред

рдпрд╣ рдЧрд╛рдЗрдб рдЖрдкрдХреЛ рдПрдХ рдкреНрд░реИрдХреНрдЯрд┐рдХрд▓ рд╕рд┐рд╕реНрдЯрдо рджреЗрддрд╛ рд╣реИ рдЬрд┐рд╕рд╕реЗ рдЖрдк рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ рд▓реЗрдпрд░ рд╕реЗ рд▓реЗрдХрд░ рдКрдкрд░ рддрдХ рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рдкрд╛рдЗрдкрд▓рд╛рдЗрдиреНрд╕ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рдлреЛрдХрд╕ рдХрд░реЗрдВрдЧреЗ Scribe v2 рд░реАрдпрд▓рдЯрд╛рдЗрдо рдкрд░, рдЬреЛ рд▓рдЧрднрдЧ 150ms рдореЙрдбрд▓ рд▓реЗрдЯреЗрдВрд╕реА рдореЗрдВ рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрд╢рди рджреЗрддрд╛ рд╣реИ, 90+ рднрд╛рд╖рд╛рдУрдВ рдХреЛ рд╕рдкреЛрд░реНрдЯ рдХрд░рддрд╛ рд╣реИ, PCM (8kHz-48kHz) рдФрд░ mu-law рдСрдбрд┐рдпреЛ рд▓реЗрддрд╛ рд╣реИ, рдФрд░ рд╡реЙрдЗрд╕ рдПрдХреНрдЯрд┐рд╡рд┐рдЯреА рдбрд┐рдЯреЗрдХреНрд╢рди рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдореИрдиреНрдпреБрдЕрд▓ рдХрдорд┐рдЯ рдХрдВрдЯреНрд░реЛрд▓ рднреА рджреЗрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╕реЗрдЧрдореЗрдВрдЯ рдлрд╛рдЗрдирд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред

рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдСрдбрд┐рдпреЛ рд╕рд░реНрд╡рд░ рддрдХ рдХреИрд╕реЗ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИ, рд╣рд╛рдЗрдкреЛрдереЗрд╕рд┐рд╕ рдХреИрд╕реЗ рдлрд╛рдЗрдирд▓ рдЯреЗрдХреНрд╕реНрдЯ рдореЗрдВ рдмрджрд▓рддрд╛ рд╣реИ, рдЗрди-рд╕реНрдЯреНрд░реАрдо рдлреАрдЪрд░реНрд╕ рдХрд╛ рдХреНрдпрд╛ рдЕрд╕рд░ рдкрдбрд╝рддрд╛ рд╣реИ, рдФрд░ рдСрдбрд┐рдпреЛ рдХреЛ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХреИрд╕реЗ рдХреИрдкреНрдЪрд░ рдФрд░ рдлреЙрд░рд╡рд░реНрдб рдХрд░реЗрдВред

рд╕рд╛рд░рд╛рдВрд╢

  • рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛рдирд╛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЛ рдмрд╛рд░реАрдХреА рд╕реЗ рдЯреНрдпреВрди рдХрд░рдиреЗ рдХреА рдорд╛рдВрдЧ рдХрд░рддрд╛ рд╣реИ, рддрд╛рдХрд┐ рдкреВрд░реА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рд▓реЗрдЯреЗрдВрд╕реА рдХрдо рд░рд╣реЗред
  • рдЬреНрдпрд╛рджрд╛рддрд░ рдкрд╛рдЗрдкрд▓рд╛рдЗрдиреНрд╕ рдХреЗ рд▓рд┐рдП WebSocket рд╕рд╣реА рдбрд┐рдлреЙрд▓реНрдЯ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ WebRTC рднреА рдХрдИ рдлрд╛рдпрджреЗ рджреЗрддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдереЛрдбрд╝рд╛ рдЬрдЯрд┐рд▓ рд╣реИред
  • рд╡реЙрдЗрд╕ рдПрдХреНрдЯрд┐рд╡рд┐рдЯреА рдбрд┐рдЯреЗрдХреНрд╢рди рд╣реИрдВрдбреНрд╕-рдлреНрд░реА рд╕реЗрдЧрдореЗрдВрдЯреЗрд╢рди рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ, рдФрд░ рдореИрдиреНрдпреБрдЕрд▓ рдХрдорд┐рдЯ рдЖрдкрдХреЗ рдРрдк рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд╛ рдСрдкреНрд╢рди рджреЗрддрд╛ рд╣реИ рдЬрдм рдЙрд╕реЗ рдкрддрд╛ рд╣реЛ рдХрд┐ рдЯрд░реНрди рдЦрддреНрдо рд╣реЛ рдЧрдпрд╛ рд╣реИред
  • рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдЕрд╕реНрдерд╛рдпреА рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рдлрд╛рдЗрдирд▓ рдХрдорд┐рдЯреЗрдб, рдЗрд╕рд▓рд┐рдП рдЗрдиреНрд╣реЗрдВ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рджрд┐рдЦрд╛рдПрдВред
  • рдХрд░реАрдм 100ms рдХреЗ рдЫреЛрдЯреЗ PCM рдЪрдВрдХреНрд╕ рд╕реЗ рдкрд╣рд▓реЗ рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдХреА рд▓реЗрдЯреЗрдВрд╕реА рдХрдо рд╣реЛрддреА рд╣реИред

рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рдХреЗ рд▓рд┐рдП WebSocket рдмрдирд╛рдо WebRTC

рдХреЛрдИ рднреА рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрд╢рди рд╢реБрд░реВ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдСрдбрд┐рдпреЛ рдХреЛ рд╕реЛрд░реНрд╕ рд╕реЗ рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рддрдХ рдкрд╣реБрдВрдЪрдирд╛ рд╣реЛрддрд╛ рд╣реИред рдЬреЛ рдЪреИрдирд▓ рдЖрдк рдЪреБрдирддреЗ рд╣реИрдВ, рд╡рд╣реА рдЖрдЧреЗ рдХреА рдкреВрд░реА рд▓реЗрдЯреЗрдВрд╕реА рдХрд╛ рдмреЗрд╕ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред рдСрдбрд┐рдпреЛ рдХреЛ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрд╢рди рд▓реЗрдпрд░ рддрдХ рдкрд╣реБрдВрдЪрд╛рдиреЗ рдХреЗ рджреЛ рдЕрдЪреНрдЫреЗ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВред

WebSocket рдПрдХ рд▓рдВрдмрд╛ рдЪрд▓рдиреЗ рд╡рд╛рд▓рд╛, рдСрд░реНрдбрд░ рдореЗрдВ, рднрд░реЛрд╕реЗрдордВрдж, рдмрд╛рдпрдбрд╛рдпрд░реЗрдХреНрд╢рдирд▓ рдЪреИрдирд▓ рд╣реИ рдЬреЛ TCP рдкрд░ рдЪрд▓рддрд╛ рд╣реИред рдЖрдк рдХрдиреЗрдХреНрд╢рди рдЦреЛрд▓рддреЗ рд╣реИрдВ, рдмрд╛рдЗрдирд░реА рдСрдбрд┐рдпреЛ рдлреНрд░реЗрдореНрд╕ рднреЗрдЬрддреЗ рд╣реИрдВ, рдФрд░ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдЗрд╡реЗрдВрдЯреНрд╕ рдкрдврд╝рддреЗ рд╣реИрдВред рдпрд╣ рдХреНрд▓рд╛рдЗрдВрдЯ рдФрд░ рд╕рд░реНрд╡рд░ рджреЛрдиреЛрдВ рдкрд░ рд╕реАрдзрд╛ рд╣реИ, HTTPS рдХреЛ рд╕рдкреЛрд░реНрдЯ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЙрд░реНрдкреЛрд░реЗрдЯ рдкреНрд░реЙрдХреНрд╕реА рдФрд░ рдлрд╛рдпрд░рд╡реЙрд▓реНрд╕ рдХреЛ рдкрд╛рд░ рдХрд░ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╣рд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╡ рд╕рд░реНрд╡рд░ рд░рдирдЯрд╛рдЗрдо рдЗрд╕реЗ рд╕рдкреЛрд░реНрдЯ рдХрд░рддрд╛ рд╣реИред

WebSocket рдХреА рд▓рд┐рдорд┐рдЯ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ TCP рдкрд░ рдЪрд▓рддрд╛ рд╣реИред рдЕрдЧрд░ рдХреЛрдИ рдкреИрдХреЗрдЯ рдЦреЛ рдЬрд╛рдП, рддреЛ TCP рдЙрд╕реЗ рдлрд┐рд░ рд╕реЗ рднреЗрдЬрддрд╛ рд╣реИ рдФрд░ рдмрд╛рдж рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рд░реЛрдХ рд▓реЗрддрд╛ рд╣реИ рдЬрдм рддрдХ рдЧреИрдк рди рднрд░ рдЬрд╛рдПред рдЕрдЪреНрдЫреА рдиреЗрдЯрд╡рд░реНрдХ рдХрдВрдбреАрд╢рди рдореЗрдВ рдпрд╣ рджрд┐рдЦрддрд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдкреИрдХреЗрдЯ рд▓реЙрд╕ рдореЗрдВ рдСрдбрд┐рдпреЛ рд░реБрдХ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдлрд┐рд░ рдПрдХ рд╕рд╛рде рдЖ рдЬрд╛рддрд╛ рд╣реИред

WebRTC рд░реАрдпрд▓-рдЯрд╛рдЗрдо рдореАрдбрд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реИред рдпрд╣ рдореАрдбрд┐рдпрд╛ рдХреЛ UDP (SRTP рдХреЗ рдЬрд░рд┐рдП) рдкрд░ рднреЗрдЬрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЦреЛрдпрд╛ рдкреИрдХреЗрдЯ рд╕реНрдЯреНрд░реАрдо рдХреЛ рдирд╣реАрдВ рд░реЛрдХрддрд╛; рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдЪрд▓рддреА рд░рд╣рддреА рд╣реИред рдЗрд╕рдореЗрдВ рдЬрд┐рдЯрд░ рдмрдлрд░ рд╣реИ рдЬреЛ рдкреИрдХреЗрдЯ рдХреЗ рдЖрдиреЗ рдХреЗ рд╕рдордп рдореЗрдВ рдлрд░реНрдХ рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ, ICE/STUN/TURN рд╕реЗ NAT рдЯреНрд░реИрд╡рд░реНрд╕рд▓ рдХрд░рддрд╛ рд╣реИ рддрд╛рдХрд┐ рд░рд╛рдЙрдЯрд░ рдХреЗ рдкреАрдЫреЗ рдХреЗ рдкреАрдпрд░реНрд╕ рдХрдиреЗрдХреНрдЯ рд╣реЛ рд╕рдХреЗрдВ, рдФрд░ рдЗрд╕рдореЗрдВ рдЕрдкрдирд╛ рдСрдбрд┐рдпреЛ рдХреИрдкреНрдЪрд░ рд╡ рдПрдирдХреЛрдбрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рд╣реИред

рдЖрдорддреМрд░ рдкрд░ рдЖрдкрдХреЛ рдЙрди рдХреНрд▓рд╛рдЗрдВрдЯреНрд╕ рдХреЗ рд▓рд┐рдП TURN рд╕рд░реНрд╡рд░ рдЪрд╛рд╣рд┐рдП рдЬреЛ рдбрд╛рдпрд░реЗрдХреНрдЯ рдХрдиреЗрдХреНрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдФрд░ рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдХреЛ рдореАрдбрд┐рдпрд╛ рд╕реНрдЯреНрд░реАрдо рдХреЛ рдЯрд░реНрдорд┐рдиреЗрдЯ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ, рдмрд╛рдЗрдЯ рд╕реНрдЯреНрд░реАрдо рдкрдврд╝рдиреЗ рдХреА рдмрдЬрд╛рдпред

рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рддреБрд▓рдирд╛:

WebSocket
Transport
TCP (reliable, ordered)
Behavior under packet loss
Head-of-line blocking, bursty recovery
Jitter handling
Your responsibility
NAT traversal
Not needed (client-initiated)
Browser support
Universal, trivial
Server complexity
Low
WebRTC
Transport
UDP/SRTP (real-time, loss-tolerant)
Behavior under packet loss
Graceful degradation
Jitter handling
Built-in jitter buffer
NAT traversal
Requires ICE/STUN/TURN
Browser support
Universal, but more API surface
Server complexity
High (media server or SFU)

рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ WebSocket рд╕рд╣реА рд╡рд┐рдХрд▓реНрдк рд╣реИред рдЗрд╕реЗ рддрдм рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░реЗрдВ рдЬрдм рдЖрдкрдХреЗ рдХреНрд▓рд╛рдЗрдВрдЯреНрд╕ рдХреА рдХрдиреЗрдХреНрдЯрд┐рд╡рд┐рдЯреА рдареАрдХ рд╣реЛ рдФрд░ рдЖрдк рдХреИрдкреНрдЪрд░ рдкрд╛рде рдХрдВрдЯреНрд░реЛрд▓ рдХрд░рддреЗ рд╣реЛрдВ: рд╕рд░реНрд╡рд░-рдЯреВ-рд╕рд░реНрд╡рд░ рдкрд╛рдЗрдкрд▓рд╛рдЗрдиреНрд╕, рдбреЗрд╕реНрдХрдЯреЙрдк рдРрдкреНрд╕, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдРрдкреНрд╕ рдмреНрд░реЙрдбрдмреИрдВрдб рдкрд░, рдФрд░ рдЬреНрдпрд╛рджрд╛рддрд░ рдХреЙрдиреНрдЯреИрдХреНрдЯ-рд╕реЗрдВрдЯрд░ рдмреИрдХрдПрдВрдбреНрд╕ рдЬрд╣рд╛рдВ рдСрдбрд┐рдпреЛ рдкрд╣рд▓реЗ рд╕реЗ рдЖрдкрдХреЗ рд╕рд░реНрд╡рд░ рдкрд░ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИред

WebRTC рдЪреБрдиреЗрдВ рдЬрдм рдЖрдк рд╕реАрдзреЗ рдХрдВрдЬреНрдпреВрдорд░ рдбрд┐рд╡рд╛рдЗрд╕ рд╕реЗ, рдЕрдирд╕реНрдЯреЗрдмрд▓ рдореЛрдмрд╛рдЗрд▓ рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рдХреИрдкреНрдЪрд░ рдХрд░ рд░рд╣реЗ рд╣реЛрдВ, рдЬрдм рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рдЯреВ-рд╡реЗ рдСрдбрд┐рдпреЛ рдХреЗ рд▓рд┐рдП WebRTC рд╕реНрдЯреИрдХ рдЪрд▓рд╛ рд░рд╣реЗ рд╣реЛрдВ (рдЬреИрд╕реЗ рд╡реЙрдЗрд╕ рдПрдЬреЗрдВрдЯ рдЬреЛ рдЬрд╡рд╛рдм рднреА рджреЗрддрд╛ рд╣реИ), рдпрд╛ рдЬрдм рдХрдо рд▓реЙрд╕ рдФрд░ рд░реАрдпрд▓-рдЯрд╛рдЗрдо рдмрд┐рд╣реЗрд╡рд┐рдпрд░ рдЗрдореНрдкреНрд▓реАрдореЗрдВрдЯреЗрд╢рди рд╕рд┐рдВрдкреНрд▓рд┐рд╕рд┐рдЯреА рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдЬрд░реВрд░реА рд╣реЛред

рдЗрд╕ рдЧрд╛рдЗрдб рдХреЗ рдмрд╛рдХреА рд╣рд┐рд╕реНрд╕реЗ рдореЗрдВ рд╣рдо рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП WebSocket рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░реЗрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рд╕реЗ рд╣рд░ рд╕реНрдЯреЗрдк рд╕рд╛рдл рджрд┐рдЦрддрд╛ рд╣реИ рдФрд░ рдЬреНрдпрд╛рджрд╛рддрд░ рдЯреАрдореНрд╕ рдХреЗ рд▓рд┐рдП рдпрд╣реА рд╕рд╣реА рд╢реБрд░реБрдЖрдд рд╣реИред рдЗрд╕рдореЗрдВ рдХреБрдЫ рднреА WebSocket рдХреЗ рд▓рд┐рдП рдЦрд╛рд╕ рдирд╣реАрдВ рд╣реИ, рдЖрдк рдмрд╛рдж рдореЗрдВ WebRTC рдореАрдбрд┐рдпрд╛ рд▓реЗрдЧ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рд░реНрд╡рд░ рдкрд░ рдСрдбрд┐рдпреЛ рдХреЛ PCM рдореЗрдВ рдбрд┐рдХреЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╡рд╣реА рдЪрдВрдХреНрд╕ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВред

рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдФрд░ рдлрд╛рдЗрдирд▓ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯреНрд╕: рдЕрдВрддрд░рд┐рдо рдирддреАрдЬреЛрдВ рдХреА рд╕рдордЭ

рдПрдХ рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдкреВрд░реА рд▓рд╛рдЗрди рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдирд╣реАрдВ рдХрд░рддрд╛ред рд╡рд╣ рд▓рдЧрд╛рддрд╛рд░ рдЕрдиреБрдорд╛рди рднреЗрдЬрддрд╛ рд╣реИ рдЬреЛ рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рдСрдбрд┐рдпреЛ рдЖрддрд╛ рд╣реИ, рдФрд░ рдкрдХреНрдХрд╛ рд╣реЛрддреЗ рдЬрд╛рддреЗ рд╣реИрдВред рдЗрди рджреЛрдиреЛрдВ рд╕реНрдЯреЗрдЯреНрд╕ рдХрд╛ рдлрд░реНрдХ рд╕рдордЭрдирд╛ рдЬрд░реВрд░реА рд╣реИтАФрдпрд╣реА рдлрд░реНрдХ рдПрдХ рдЬрд┐рдВрджрд╛ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдПрдХ рдЯреВрдЯреЗ рд╣реБрдП рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред

рдкрд╛рд░реНрдЯрд┐рдпрд▓ (рдЗрдВрдЯрд░рд┐рдо) рд╣рд╛рдЗрдкреЛрдереЗрд╕рд┐рд╕ рдореЙрдбрд▓ рдХрд╛ рдЕрдм рддрдХ рдорд┐рд▓реЗ рдСрдбрд┐рдпреЛ рдкрд░ рдмреЗрд╕реНрдЯ рдЕрдиреБрдорд╛рди рд╣реЛрддрд╛ рд╣реИред рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдбрд┐рдЬрд╛рдЗрди рд╕реЗ рд╣реА рдЕрд╕реНрдерд┐рд░ рд╣реЛрддреЗ рд╣реИрдВред рдЬреИрд╕реЗ-рдЬреИрд╕реЗ рдФрд░ рдСрдбрд┐рдпреЛ рдЖрддрд╛ рд╣реИ, рдореЙрдбрд▓ рдкрд╣рд▓реЗ рдХреЗ рд╢рдмреНрдж рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИ: "I want to" рдмрд╛рдж рдореЗрдВ "I want two tickets" рдмрди рд╕рдХрддрд╛ рд╣реИред рдпреЗ рдЬрд▓реНрджреА рдЖрддреЗ рд╣реИрдВ (~150ms рд▓реЗрдЯреЗрдВрд╕реА рдЗрд╕реА рдХрд╛ рдЖрдВрдХрдбрд╝рд╛ рд╣реИ) рдФрд░ рдЗрдиреНрд╣реЗрдВ рдУрд╡рд░рд░рд╛рдЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реА рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдлрд╛рдЗрдирд▓ рд╣рд╛рдЗрдкреЛрдереЗрд╕рд┐рд╕ рдПрдХ рдХрдорд┐рдЯреЗрдб рд╕реЗрдЧрдореЗрдВрдЯ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдЕрдм рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛ред рдПрдХ рдмрд╛рд░ рд╕реЗрдЧрдореЗрдВрдЯ рдлрд╛рдЗрдирд▓ рд╣реЛ рдЧрдпрд╛, рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдЖрдЧреЗ рдмрдврд╝ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЕрдЧрд▓реА рд╣рд╛рдЗрдкреЛрдереЗрд╕рд┐рд╕ рдмрд╛рдж рдХреЗ рдСрдбрд┐рдпреЛ рдХреЗ рд▓рд┐рдП рд╣реЛрддреА рд╣реИред рдлрд╛рдЗрдирд▓реНрд╕ рд╡рд╣реА рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рд╕реЗрд╡ рдХрд░рддреЗ рд╣реИрдВ, LLM рдХреЛ рднреЗрдЬрддреЗ рд╣реИрдВ, рдпрд╛ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдЯреЛрд░ рдХрд░рддреЗ рд╣реИрдВред

рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдФрд░ рдлрд╛рдЗрдирд▓ рдХрд╛ рдлрд░реНрдХ рддреАрди рдЪреАрдЬреЛрдВ рдХреЛ рддрдп рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдЧрд▓рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЕрдЧрд░ рдлрд░реНрдХ рди рд╕рдордЭреЗрдВ:

  • рдпреВрдЬрд╝рд░ рдПрдХреНрд╕рдкреАрд░рд┐рдпрдВрд╕: рдкрд╛рд░реНрдЯрд┐рдпрд▓ рджрд┐рдЦрд╛рдиреЗ рд╕реЗ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рд▓рд╛рдЗрд╡ рд▓рдЧрддрд╛ рд╣реИ: рдпреВрдЬрд╝рд░ рдХреЛ рдмреЛрд▓рддреЗ рд╣реА рд╢рдмреНрдж рджрд┐рдЦрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдЙрдиреНрд╣реЗрдВ рднрд░реЛрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдорд╛рдЗрдХреНрд░реЛрдлреЛрди рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ рдФрд░ рд╕рд┐рд╕реНрдЯрдо рд╕реБрди рд░рд╣рд╛ рд╣реИред
  • рдПрдВрдб-рдкреЙрдЗрдВрдЯрд┐рдВрдЧ: рдкрд╛рд░реНрдЯрд┐рдпрд▓ рд╕реЗ рдЖрдкрдХреЛ рд╕реНрдкреАрдЪ рдПрдХреНрдЯрд┐рд╡рд┐рдЯреА рдХрд╛ рд▓рдЧрд╛рддрд╛рд░ рд╕рд┐рдЧреНрдирд▓ рдорд┐рд▓рддрд╛ рд╣реИред VAD рдХреЗ рд╕рд╛рде рдорд┐рд▓рд╛рдХрд░, рдЖрдк рддрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕реНрдкреАрдХрд░ рдХрдм рд░реБрдХрд╛ рд╣реИред
  • рдбрд╛рдЙрдирд╕реНрдЯреНрд░реАрдо рдЯрд╛рдЗрдорд┐рдВрдЧ: рдПрдХ рд╡реЙрдЗрд╕ рдПрдЬреЗрдВрдЯ рдкрд╛рдЗрдкрд▓рд╛рдЗрди рд╕реНрдЯреЗрдкреНрд╕ рд╣реИрдВ: рдСрдбрд┐рдпреЛ рдЗрди, рдлрд┐рд░ рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ, рдлрд┐рд░ рдПрдХ LLM, рдлрд┐рд░

рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдФрд░ рдлрд╛рдЗрдирд▓ рдХреЛ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рджрд┐рдЦрд╛рдПрдВред рдПрдХ рд╕рд┐рдВрдкрд▓ рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рдПрдХ "рдХрд░рдВрдЯ рд▓рд╛рдЗрди" рдХреЛ рд▓реЗрдЯреЗрд╕реНрдЯ рдкрд╛рд░реНрдЯрд┐рдпрд▓ рд╕реЗ рдмрд╛рдВрдзреЗрдВ рдФрд░ рдлрд╛рдЗрдирд▓ рдЖрддреЗ рд╣реА рдЙрд╕реЗ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЬреЛрдбрд╝ рджреЗрдВ:

type TranscriptState = {
  committed: string[]; // finalized segments, never rewritten
  current: string;     // latest partial, overwritten on each update
};

const onPartial = (s: TranscriptState, text: string): TranscriptState =>
  ({ ...s, current: text });

const onFinal = (s: TranscriptState, text: string): TranscriptState =>
  ({ committed: [...s.committed, text], current: "" });

рджрд┐рдЦрд╛рдиреЗ рдореЗрдВ, рдХрдорд┐рдЯреЗрдб рдЯреЗрдХреНрд╕реНрдЯ рдХреЛ рд╕реЗрдЯреЗрд▓реНрдб рджрд┐рдЦрд╛рдПрдВ рдФрд░ рдХрд░рдВрдЯ рдХреЛ рд╣рд▓реНрдХреЗ рдпрд╛ рдЗрдЯреИрд▓рд┐рдХ рд╕реНрдЯрд╛рдЗрд▓ рдореЗрдВ, рддрд╛рдХрд┐ рдпреВрдЬрд╝рд░ рд╕рдордЭ рд╕рдХреЗ рдХрд┐ рдпрд╣ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред

рдПрдВрдб-рдкреЙрдЗрдВрдЯрд┐рдВрдЧ рдФрд░ рд╡реЙрдЗрд╕ рдПрдХреНрдЯрд┐рд╡рд┐рдЯреА рдбрд┐рдЯреЗрдХреНрд╢рди (VAD)

рдХреНрдпрд╛ рдХрд╣рд╛ рдЧрдпрд╛, рдпрд╣ рдЬрд╛рдирдирд╛ рдЖрдзреА рд▓рдбрд╝рд╛рдИ рд╣реИред рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдХреЛ рдпрд╣ рднреА рдЬрд╛рдирдирд╛ рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдХрдм рдПрдХ рд╡рд┐рдЪрд╛рд░ рдЦрддреНрдо рд╣реБрдЖред рдпрд╣реА рддрдп рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╕реЗрдЧрдореЗрдВрдЯ рдХрдм рдлрд╛рдЗрдирд▓ рдХрд░реЗрдВ рдФрд░ рдПрдЬреЗрдВрдЯ рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рдХрдм рдЬрд╡рд╛рдм рджреЗрдирд╛ рд╢реБрд░реВ рдХрд░реЗред

рдПрдВрдб-рдкреЙрдЗрдВрдЯрд┐рдВрдЧ рдХрд╛ рдорддрд▓рдм рд╣реИ рддрдп рдХрд░рдирд╛ рдХрд┐ рдмреЛрд▓рдирд╛ рдЦрддреНрдо рд╣реЛ рдЧрдпрд╛ рд╣реИред рдЬрд▓реНрджреА рдлрд╛рдЗрдирд▓ рдХрд░рдиреЗ рд╕реЗ рдпреВрдЬрд╝рд░ рдХреА рдмрд╛рдд рдмреАрдЪ рдореЗрдВ рдХрдЯ рд╕рдХрддреА рд╣реИред рджреЗрд░ рд╕реЗ рдлрд╛рдЗрдирд▓ рдХрд░рдиреЗ рд╕реЗ рдпреВрдЬрд╝рд░ рдХреЗ рд░реБрдХрдиреЗ рдХреЗ рдмрд╛рдж рдПрдЬреЗрдВрдЯ рдЪреБрдк рд░рд╣рддрд╛ рд╣реИред

Scribe v2 Realtime рдЖрдкрдХреЛ рджреЛ рдХрдВрдкреНрд▓реАрдореЗрдВрдЯрд░реА рддрд░реАрдХреЗ рджреЗрддрд╛ рд╣реИ:

  • рд╡реЙрдЗрд╕ рдПрдХреНрдЯрд┐рд╡рд┐рдЯреА рдбрд┐рдЯреЗрдХреНрд╢рди рд╕рд╛рдЗрд▓реЗрдВрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдСрдбрд┐рдпреЛ рдХреЛ рд╕реЗрдЧрдореЗрдВрдЯ рдХрд░рддрд╛ рд╣реИ: рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдкрд╣рдЪрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдХрдм рд╕реНрдкреАрдЪ рдХреЗ рдмрд╛рдж рд▓рдЧрд╛рддрд╛рд░ рд╕рд╛рдЗрд▓реЗрдВрд╕ рдЖрддрд╛ рд╣реИ рдФрд░ рдЙрд╕ рдмрд╛рдЙрдВрдбреНрд░реА рдкрд░ рд╕реЗрдЧрдореЗрдВрдЯ рдХреЛ рдСрдЯреЛрдореЗрдЯрд┐рдХрд▓реА рдлрд╛рдЗрдирд▓ рдХрд░ рджреЗрддрд╛ рд╣реИред VAD рдХрдиреНрд╡рд░реНрд╕реЗрд╢рдирд▓ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдбрд┐рдлреЙрд▓реНрдЯ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдиреЗрдЪреБрд░рд▓ рд╕реНрдкреАрдЪ рд░рд┐рджрдо рдХреЗ рд╕рд╛рде рдЦреБрдж рдХреЛ рдПрдбрдЬрд╕реНрдЯ рдХрд░рддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдЯрд╛рдЗрдорд┐рдВрдЧ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рдкрдбрд╝рддреАред
  • рдореИрдиреНрдпреБрдЕрд▓ рдХрдорд┐рдЯ рдХрдВрдЯреНрд░реЛрд▓: рдореИрдиреНрдпреБрдЕрд▓ рдХрдорд┐рдЯ рдХрдВрдЯреНрд░реЛрд▓ рд╕реЗ рдЖрдкрдХрд╛ рдРрдк рдЦреБрдж рддрдп рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХрд░рдВрдЯ рд╕реЗрдЧрдореЗрдВрдЯ рдХрдм рдлрд╛рдЗрдирд▓ рдХрд░рдирд╛ рд╣реИ, рд╕рд╛рдЗрд▓реЗрдВрд╕ рд╕реЗ рдЕрд▓рдЧред рдЖрдк рдХрдорд┐рдЯ рд╕рд┐рдЧреНрдирд▓ рднреЗрдЬрддреЗ рд╣реИрдВ, рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдХрд░рдВрдЯ рд╕реЗрдЧрдореЗрдВрдЯ рдмрдВрдж рдХрд░рддрд╛ рд╣реИ рдФрд░ рдлрд╛рдЗрдирд▓ рднреЗрдЬрддрд╛ рд╣реИред рдпрд╣ рддрдм рд╕рд╣реА рд╣реИ рдЬрдм рдЖрдкрдХреЗ рдРрдк рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рдкрддрд╛ рд╣реЛ рдХрд┐ рдЯрд░реНрди рдЦрддреНрдо рд╣реИ: рдЬреИрд╕реЗ рдкреБрд╢-рдЯреВ-рдЯреЙрдХ рдмрдЯрди рдЫреЛрдбрд╝рдирд╛, "рд╕реЗрдВрдб" рдПрдХреНрд╢рди рдпрд╛ рдХреЛрдИ рдмрд╛рд╣рд░реА рдЯрд░реНрди-рдЯреЗрдХрд┐рдВрдЧ рдкреЙрд▓рд┐рд╕реАред

рдпреЗ рджреЛрдиреЛрдВ рдПрдХ рд╕рд╛рде рдЕрдЪреНрдЫреА рддрд░рд╣ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдПрдХ рдЖрдо

рд╕рд╛рдЗрд▓реЗрдВрд╕ рдереНрд░реЗрд╢реЛрд▓реНрдб рдПрдХ рдЕрд╕рд▓реА рдЯреНрд░реЗрдбрдСрдл рд╣реИ, рдЗрд╕рдХрд╛ рдХреЛрдИ рдПрдХ рд╕рд╣реА рдорд╛рди рдирд╣реАрдВ рд╣реИ:

  • рдЫреЛрдЯрд╛ рдПрдВрдб-рдСрдл-рд╕реНрдкреАрдЪ рдЯрд╛рдЗрдордЖрдЙрдЯ (рдЬреИрд╕реЗ ~200-400ms рд╕рд╛рдЗрд▓реЗрдВрд╕ рдХреЗ рдмрд╛рдж рдлрд╛рдЗрдирд▓рд╛рдЗрдЬреЗрд╢рди) рд╕рд┐рд╕реНрдЯрдо рдХреЛ рд░рд┐рд╕реНрдкреЙрдиреНрд╕рд┐рд╡ рдмрдирд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рд╡реЗ рдпреВрдЬрд╝рд░ рдХрдЯ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдиреЗрдЪреБрд░рд▓ рдкреЙрдЬрд╝ рд▓реЗрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдПрдХ рд╡рд┐рдЪрд╛рд░ рдХрдИ рд╕реЗрдЧрдореЗрдВрдЯреНрд╕ рдореЗрдВ рдмрдВрдЯ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдПрдЬреЗрдВрдЯ рдЬрд▓реНрджреА рдЬрд╡рд╛рдм рджреЗ рд╕рдХрддрд╛ рд╣реИред
  • рд▓рдВрдмрд╛ рдЯрд╛рдЗрдордЖрдЙрдЯ (рдЬреИрд╕реЗ ~800-1200ms) рдиреЗрдЪреБрд░рд▓ рдкреЙрдЬрд╝ рдХреЛ рд╕рд╣рди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкреВрд░реА рдмрд╛рдд рдХреЛ рдПрдХ рд╕рд╛рде рд░рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд░рд┐рдПрдХреНрд╢рди рдореЗрдВ рдереЛрдбрд╝рд╛ рд▓реИрдЧ рдЖ рд╕рдХрддрд╛ рд╣реИред

рдпрд╣рд╛рдВ рдХреЛрдИ рдЧреНрд▓реЛрдмрд▓ рдХреЙрдиреНрд╕реНрдЯреЗрдВрдЯ рдирд╣реАрдВ рд╣реИ; рдереНрд░реЗрд╢реЛрд▓реНрдб рдХреЛ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЗ рд╣рд┐рд╕рд╛рдм рд╕реЗ рдЯреНрдпреВрди рдХрд░реЗрдВ:

  • рдбрд┐рдХреНрдЯреЗрд╢рди рдФрд░ рдиреЛрдЯ-рдЯреЗрдХрд┐рдВрдЧ рдореЗрдВ рдпреВрдЬрд╝рд░ рдмреАрдЪ рдореЗрдВ рд╕реЛрдЪрддреЗ рд╣реИрдВ, рддреЛ рд▓рдВрдмрд╛ рдкреЙрдЬрд╝ рдЪрд▓рддрд╛ рд╣реИред рд▓рдВрдмреЗ рдЯрд╛рдЗрдордЖрдЙрдЯ рд░рдЦреЗрдВ рдФрд░ VAD рдкрд░ рднрд░реЛрд╕рд╛ рдХрд░реЗрдВред
  • рдХрдорд╛рдВрдб-рдПрдВрдб-рдХрдВрдЯреНрд░реЛрд▓ рдФрд░ рдЯреНрд░рд╛рдВрдЬреИрдХреНрд╢рдирд▓ рдПрдЬреЗрдВрдЯреНрд╕ рдореЗрдВ рдЫреЛрдЯреЗ рдЯрд╛рдЗрдордЖрдЙрдЯ рдФрд░ рдореИрдиреНрдпреБрдЕрд▓ рдХрдорд┐рдЯ рдлрд╛рдпрджреЗрдордВрдж рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЯрд░реНрди рдЫреЛрдЯреЗ рдФрд░ рддреЗрдЬ рд╣реЛрддреЗ рд╣реИрдВред
  • рдорд▓реНрдЯреАрд▓рд┐рдВрдЧреБрдЕрд▓ рдпрд╛ рдиреЙрди-рдиреЗрдЯрд┐рд╡ рд╕реНрдкреАрдХрд░реНрд╕ рдЬреНрдпрд╛рджрд╛ рдкреЙрдЬрд╝ рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдлрд╛рдЗрдирд▓рд╛рдЗрдЬреЗрд╢рди рд╕реЗ рдкрд╣рд▓реЗ рдЬреНрдпрд╛рджрд╛ рд╕рд╛рдЗрд▓реЗрдВрд╕ рдХрд╛ рдмрдЬрдЯ рд░рдЦреЗрдВред

рдЗрди рдЯрд┐рдкреНрд╕ рд╕реЗ рдЖрдк рдПрдХ рдЕрд╕рд░рджрд╛рд░ рдПрдВрдб-рдкреЙрдЗрдВрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рдХреА рдУрд░ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрди-рд╕реНрдЯреНрд░реАрдо рдлреАрдЪрд░реНрд╕: рд▓реИрдВрдЧреНрд╡реЗрдЬ рдбрд┐рдЯреЗрдХреНрд╢рди рдФрд░ рд╕реНрдкреАрдХрд░ рдбрд╛рдпрд░рд╛рдЗрдЬреЗрд╢рди

рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рд░рд┐рдХрдЧреНрдирд┐рд╢рди рд╕рд┐рд░реНрдл рд╢рдмреНрдж рд╣реА рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддрд╛ред рд▓реЗрдХрд┐рди рд╣рд░ рдПрдХреНрд╕реНрдЯреНрд░рд╛ рд╕рд┐рдЧреНрдирд▓ рд▓реЗрдЯреЗрдВрд╕реА рдФрд░ рд╕реНрдЯреЗрдмрд┐рд▓рд┐рдЯреА рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИред рд╕рд┐рдВрдкрд▓ рд░реВрд▓ рд╣реИтАФрд╕рд┐рд░реНрдл рд╡рд╣реА рдСрди рдХрд░реЗрдВ рдЬреЛ рд▓рд╛рдЗрд╡ рдПрдХреНрд╕рдкреАрд░рд┐рдпрдВрд╕ рдХреЗ рд▓рд┐рдП рдЬрд░реВрд░реА рд╣реЛ, рдмрд╛рдХреА рдХреЛ рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕ рдореЗрдВ рдбрд╛рд▓реЗрдВред

рдСрдЯреЛрдореИрдЯрд┐рдХ рд▓реИрдВрдЧреНрд╡реЗрдЬ рд░рд┐рдХрдЧреНрдирд┐рд╢рди Scribe v2 Realtime рдХреЛ 90+ рд╕рдкреЛрд░реНрдЯреЗрдб рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рд╕реЗ рдмреЛрд▓реА рдЬрд╛ рд░рд╣реА рднрд╛рд╖рд╛ рдкрд╣рдЪрд╛рдирдиреЗ рджреЗрддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рдмрддрд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВред рдЗрд╕рдХреА рдХреАрдордд рдпрд╣ рд╣реИ рдХрд┐ рдореЙрдбрд▓ рдХреЛ рднрд░реЛрд╕реЗрдордВрдж рдкрд╣рдЪрд╛рди рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рдСрдбрд┐рдпреЛ рдЪрд╛рд╣рд┐рдП, рддреЛ рд╕реНрдЯреНрд░реАрдо рдХреЗ рд╢реБрд░реБрдЖрддреА рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдХрдо рд╕реНрдерд┐рд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдЧрд░ рдЖрдкрдХреЛ рднрд╛рд╖рд╛ рдкрд╣рд▓реЗ рд╕реЗ рдкрддрд╛ рд╣реИ, рддреЛ рдЙрд╕реЗ рдмрддрд╛рдиреЗ рд╕реЗ рд╢реБрд░реБрдЖрддреА рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдЬреНрдпрд╛рджрд╛ рд╕реНрдерд┐рд░ рдорд┐рд▓рддреЗ рд╣реИрдВред

рд╕реНрдкреАрдХрд░ рдбрд╛рдпрд░рд╛рдЗрдЬреЗрд╢рди рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕реНрдкреАрдХрд░реНрд╕ рдХреА рд╕реНрдкреАрдЪ рдХреЛ рдкрд╣рдЪрд╛рдирддрд╛ рд╣реИ, рдХреМрди рдХреНрдпрд╛ рдмреЛрд▓ рд░рд╣рд╛ рд╣реИред рдмреИрдЪ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрд╢рди рдореЗрдВ рдпрд╣ рдЖрд╕рд╛рди рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореЙрдбрд▓ рдкреВрд░реА рдлрд╛рдЗрд▓ рджреЗрдЦрддрд╛ рд╣реИред рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдореЗрдВ рдпрд╣ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ: рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдХреЛ рдЕрдм рддрдХ рдХреЗ рдСрдбрд┐рдпреЛ рд╕реЗ рд╣реА рд╕реНрдкреАрдХрд░ рд▓реЗрдмрд▓ рджреЗрдирд╛ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рд╢реБрд░реВ рдореЗрдВ рджрд┐рдпрд╛ рдЧрдпрд╛ рд▓реЗрдмрд▓ рдмрд╛рдж рдореЗрдВ рдмрджрд▓рдирд╛ рдкрдбрд╝ рд╕рдХрддрд╛ рд╣реИред рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рд╕реНрдкреАрдХрд░ рд▓реЗрдмрд▓реНрд╕ рдХреЛ рд╡реИрд╕реЗ рд╣реА рдЯреНрд░реАрдЯ рдХрд░реЗрдВ рдЬреИрд╕реЗ рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдЯреЗрдХреНрд╕реНрдЯ рдХреЛ: рдлрд╛рдЗрдирд▓рд╛рдЗрдЬреЗрд╢рди рддрдХ рдкреНрд░реЛрд╡рд┐рдЬрдирд▓ред

рд╡рд░реНрдб-рд▓реЗрд╡рд▓ рдЯрд╛рдЗрдорд┐рдВрдЧ рдФрд░ рдПрдВрдЯрд┐рдЯреА рдХреЙрдиреНрдЯреЗрдХреНрд╕реНрдЯ рднреА рдпрд╣реА рд▓реЙрдЬрд┐рдХ рдлреЙрд▓реЛ рдХрд░рддреЗ рд╣реИрдВред рдЬрд┐рддрдирд╛ рдЬреНрдпрд╛рджрд╛ рдкрд░-рдЯреЛрдХрди рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдорд╛рдВрдЧреЗрдВрдЧреЗ, рдореЙрдбрд▓ рдФрд░ рд╡рд╛рдпрд░ рджреЛрдиреЛрдВ рдкрд░ рд▓реЛрдб рдмрдврд╝реЗрдЧрд╛ред рдЬреНрдпрд╛рджрд╛рддрд░ рд░реАрдпрд▓-рдЯрд╛рдЗрдо UI рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рд╕рд┐рд░реНрдл рдЯреЗрдХреНрд╕реНрдЯ рдФрд░ рд╕реЗрдЧрдореЗрдВрдЯ рдмрд╛рдЙрдВрдбреНрд░реА рд▓рд╛рдЗрд╡ рдЪрд╛рд╣рд┐рдП, рдмрд╛рдХреА рдлрд╛рдЗрди-рдЧреНрд░реЗрдиреНрдб рдореЗрдЯрд╛рдбреЗрдЯрд╛ Scribe v2 рдХреЗ рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕ рдореЗрдВ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред

рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдСрдбрд┐рдпреЛ рдлреЙрд░реНрдореЗрдЯреНрд╕: PCM рдФрд░ mu-law

рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ рдФрд░ рд░рд┐рдХрдЧреНрдирд┐рд╢рди рд▓реЙрдЬрд┐рдХ рдкрд░ рд╕рдмрд╕реЗ рдЬреНрдпрд╛рджрд╛ рдзреНрдпрд╛рди рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрд╕рд▓ рдореЗрдВ рдХрдИ рдмрдЧ рдиреАрдЪреЗ рдХреА рд▓реЗрдпрд░ рдореЗрдВ рд╣реЛрддреЗ рд╣реИрдВтАФрдХреИрд╕реЗ рдЖрдк рдСрдбрд┐рдпреЛ рдХреЛ рдПрдирдХреЛрдб рдФрд░ рдЪрдВрдХ рдХрд░рддреЗ рд╣реИрдВред рдлреЙрд░реНрдореЗрдЯ рдФрд░ рдЪрдВрдХ рд╕рд╛рдЗрдЬ рд╕рд╣реА рд░рдЦрдирд╛ рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рд▓реЗрдЯреЗрдВрд╕реА рдХрдо рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИред

PCM (рд▓рд┐рдирд┐рдпрд░, 16-рдмрд┐рдЯ рд╕рд╛рдЗрди, рд▓рд┐рдЯрд┐рд▓-рдПрдВрдбрд┐рдпрди) рддрдм рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░реЗрдВ рдЬрдм рдЖрдк рдХреИрдкреНрдЪрд░ рдХрдВрдЯреНрд░реЛрд▓ рдХрд░рддреЗ рд╣реИрдВред рдЬреНрдпрд╛рджрд╛ рд╕реИрдВрдкрд▓ рд░реЗрдЯ рдореЗрдВ рдЬреНрдпрд╛рджрд╛ рдбрд┐рдЯреЗрд▓ рдЖрддреА рд╣реИ: 16kHz рд╕реНрдкреАрдЪ рд░рд┐рдХрдЧреНрдирд┐рд╢рди рдХреЗ рд▓рд┐рдП рд╕реНрдЯреИрдВрдбрд░реНрдб рд╣реИ рдФрд░ рдЖрдорддреМрд░ рдкрд░ рдХрд╛рдлреА рд╣реИ; 8kHz рдЯреЗрд▓реАрдлреЛрди-рдЧреНрд░реЗрдб рд╣реИ рдФрд░ рд╣рд╛рдИ-рдлреНрд░реАрдХреНрд╡реЗрдВрд╕реА рдХрдВрдЯреЗрдВрдЯ рдЦреЛ рджреЗрддрд╛ рд╣реИред рд╕реЛрд░реНрд╕ рдХреЗ рд╣рд┐рд╕рд╛рдм рд╕реЗ рд░реЗрдЯ рдЪреБрдиреЗрдВред 8kHz рдЯреЗрд▓реАрдлреЛрдиреА рдСрдбрд┐рдпреЛ рдХреЛ 48kHz рдореЗрдВ рдЕрдкрд╕реИрдВрдкрд▓ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдлрд╛рдпрджрд╛ рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рдЙрд╕рдореЗрдВ рдЙрддрдиреА рдЬрд╛рдирдХрд╛рд░реА рдирд╣реАрдВ рд╣реИред

Mu-law 8kHz рдЯреЗрд▓реАрдлреЛрдиреА рдлреЙрд░реНрдореЗрдЯ рд╣реИред рдЕрдЧрд░ рдЖрдк Twilio рдЬреИрд╕реЗ рдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рд╕реЗ рдХреЙрд▓ рд▓реЗ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдСрдбрд┐рдпреЛ 8kHz mu-law рдореЗрдВ рдЖрддрд╛ рд╣реИ, рдФрд░ рдЖрдкрдХреЛ рдЙрд╕реА рдлреЙрд░реНрдореЗрдЯ рдореЗрдВ рдлреЙрд░рд╡рд░реНрдб рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рджреЛ рдмрд╛рд░ рдЯреНрд░рд╛рдВрд╕рдХреЛрдб рдХрд░рдиреЗ рдХреА рдмрдЬрд╛рдпред рд╕реЛрд░реНрд╕ рдлреЙрд░реНрдореЗрдЯ рдореИрдЪ рдХрд░рдиреЗ рд╕реЗ рд░рд┐рд╕реИрдВрдкрд▓рд┐рдВрдЧ рдЖрд░реНрдЯрд┐рдлреИрдХреНрдЯреНрд╕ рдФрд░ рдмреЗрдХрд╛рд░ рдХрдиреНрд╡рд░реНрдЬрди рд╕реНрдЯреЗрдк рдмрдЪрддрд╛ рд╣реИред

рдЪрдВрдХ рд╕рд╛рдЗрдЬрд┐рдВрдЧ рд╕рдмрд╕реЗ рдбрд╛рдпрд░реЗрдХреНрдЯ рддрд░реАрдХреЗ рд╕реЗ рд▓реЗрдЯреЗрдВрд╕реА рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЖрдк рдСрдбрд┐рдпреЛ рдЪрдВрдХреНрд╕ рдореЗрдВ рднреЗрдЬрддреЗ рд╣реИрдВ, рдФрд░ рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдЪрдВрдХреНрд╕ рдЖрддреЗ рд╣реА рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдмрдирд╛рддрд╛ рд╣реИред рдЫреЛрдЯреЗ рдЪрдВрдХреНрд╕ рдХрд╛ рдорддрд▓рдм рдЬреНрдпрд╛рджрд╛ рдмрд╛рд░ рдЕрдкрдбреЗрдЯ рдФрд░ рдкрд╣рд▓реЗ рдкрд╛рд░реНрдЯрд┐рдпрд▓ рддрдХ рдХрдо рд▓реЗрдЯреЗрдВрд╕реА; рдмрдбрд╝реЗ рдЪрдВрдХреНрд╕ рдХрд╛ рдорддрд▓рдм рдХрдо рдореИрд╕реЗрдЬ рдФрд░ рд╣рд░ рдЗрдВрдлрд░реЗрдВрд╕ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЬреНрдпрд╛рджрд╛ рдХреЙрдиреНрдЯреЗрдХреНрд╕реНрдЯред рдкреНрд░реИрдХреНрдЯрд┐рдХрд▓ рд░реЗрдВрдЬ рд╣реИ 20-250ms рдСрдбрд┐рдпреЛ рдкреНрд░рддрд┐ рдЪрдВрдХред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 16kHz рдореЛрдиреЛ 16-рдмрд┐рдЯ PCM рдореЗрдВ рдПрдХ рд╕реЗрдХрдВрдб рдХрд╛ рдСрдбрд┐рдпреЛ 32,000 рдмрд╛рдЗрдЯреНрд╕ рд╣реЛрддрд╛ рд╣реИ, рддреЛ 100ms рдЪрдВрдХ рдХрд░реАрдм 3,200 рдмрд╛рдЗрдЯреНрд╕ рдХрд╛ рд╣реЛрдЧрд╛ред

рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ рдорд╛рдЗрдХреНрд░реЛрдлреЛрди рдЗрдирдкреБрдЯ рдХреИрдкреНрдЪрд░ рдХрд░рдирд╛

рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдореЗрдВ, рд╕рд╣реА рдЯреВрд▓ рд╣реИ Web

рд╡рд░реНрдХрд▓реЗрдЯ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХрд╛ рдХреЛрд░ рд╣реИ рдлреНрд▓реЛрдЯ-рдЯреВ-PCM рдХрдиреНрд╡рд░реНрдЬрди:

// pcm-worklet.ts - registered via audioContext.audioWorklet.addModule()
class PCMWorklet extends AudioWorkletProcessor {
  process(inputs: Float32Array[][]) {
    const channel = inputs[0]?.[0]; // mono; Float32, range [-1, 1]
    if (!channel) return true;
    const pcm = new Int16Array(channel.length);
    for (let i = 0; i < channel.length; i++) {
      const s = Math.max(-1, Math.min(1, channel[i]));
      pcm[i] = s < 0 ? s * 0x8000 : s * 0x7fff;
    }
    // Transfer the buffer to the main thread without copying.
    this.port.postMessage(pcm.buffer, [pcm.buffer]);
    return true;
  }
}
registerProcessor("pcm-worklet", PCMWorklet);

рдХреЛрдб рдореЗрдВ рдкрд╛рдЗрдкрд▓рд╛рдЗрди

рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдореЗрдВ рддреАрди рд╣рд┐рд╕реНрд╕реЗ рд╣реИрдВ: рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдЬреЛ рдорд╛рдЗрдХреНрд░реЛрдлреЛрди рдХреИрдкреНрдЪрд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ PCM рдХреЛ рд╕рд░реНрд╡рд░ рдкрд░ рд╕реНрдЯреНрд░реАрдо рдХрд░рддрд╛ рд╣реИ, рдПрдХ Node рд╕рд░реНрд╡рд░ рдЬреЛ рдСрдбрд┐рдпреЛ Scribe v2 Realtime рдХреЛ рднреЗрдЬрддрд╛ рд╣реИ рдФрд░ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рд╡рд╛рдкрд╕ рд▓рд╛рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯреЗрдмрд▓ рдХреНрд▓рд╛рдЗрдВрдЯ рдЬреЛ рдлрд╛рдЗрд▓ рдпрд╛ рдЯреЗрд▓реАрдлреЛрдиреА рдмреНрд░рд┐рдЬ рд╕реЗ PCM рд╕реНрдЯреНрд░реАрдо рдХрд░рддрд╛ рд╣реИред

рд╕рд░реНрд╡рд░ рдбрд╛рдпрд░реЗрдХреНрдЯрд▓реА рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдХреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реЗ рдПрдХреНрд╕рдкреЛрдЬрд╝ рдирд╣реАрдВ рдХрд░рддрд╛, рдЗрд╕рдХреА рдПрдХ рдмрдбрд╝реА рд╡рдЬрд╣ рд╣реИ: рдЖрдкрдХрд╛ ElevenLabs API рдХреА рд╕реАрдХреНрд░реЗрдЯ рд╣реИ рдФрд░ рдХрднреА рднреА рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдХреЛрдб рдореЗрдВ рдирд╣реАрдВ рдЖрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╕рд░реНрд╡рд░ рдХреА рдкрд░ рд░рдЦрд┐рдПред рдЕрдЧрд░ рдЖрдкрдХреЛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд╕реЗ рдбрд╛рдпрд░реЗрдХреНрдЯ рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рд╕реЗ рдмрд╛рдд рдХрд░рдиреА рд╣реИ, рддреЛ рд╕рд░реНрд╡рд░-рд╕рд╛рдЗрдб рдПрдХ рд╢реЙрд░реНрдЯ-рд▓рд┐рд╡реНрдб рд╕рд┐рдВрдЧрд▓-рдпреВрдЬрд╝ рдЯреЛрдХрди рдмрдирд╛рдПрдВ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ API рдХреА рдХреА рдЬрдЧрд╣ рд╡рд╣реА рджреЗрдВред

рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреНрд▓рд╛рдЗрдВрдЯ

рдХреНрд▓рд╛рдЗрдВрдЯ рдЖрдкрдХреЗ рд╕рд░реНрд╡рд░ рд╕реЗ WebSocket рдЦреЛрд▓рддрд╛ рд╣реИ, рдКрдкрд░ рдмрддрд╛рдП рд╡рд░реНрдХрд▓реЗрдЯ рд╕реЗ рдорд╛рдЗрдХреНрд░реЛрдлреЛрди рдХреИрдкреНрдЪрд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╣рд░ PCM рдлреНрд░реЗрдо рдХреЛ рдмрдирддреЗ рд╣реА рдлреЙрд░рд╡рд░реНрдб рдХрд░рддрд╛ рд╣реИред рдЗрдирдХрдорд┐рдВрдЧ рдЗрд╡реЗрдВрдЯреНрд╕ (рдЬреЛ рд╕рд░реНрд╡рд░ рдкрд╣рд▓реЗ рд╣реА { type, text } рдореЗрдВ рдиреЙрд░реНрдорд▓рд╛рдЗрдЬрд╝ рдХрд░ рдЪреБрдХрд╛ рд╣реИ) рдКрдкрд░ рдмрддрд╛рдП рдкрд╛рд░реНрдЯрд┐рдпрд▓/рдлрд╛рдЗрдирд▓ рд╕реНрдЯреЗрдЯ рдХреЛ рдбреНрд░рд╛рдЗрд╡ рдХрд░рддреЗ рд╣реИрдВ:

// client.ts - runs in the browser. ws is an open WebSocket to your server.
const audioContext = new AudioContext({ sampleRate: 16000 });
await audioContext.audioWorklet.addModule("pcm-worklet.js");

const mediaStream = await navigator.mediaDevices.getUserMedia({
  audio: { channelCount: 1, echoCancellation: true, noiseSuppression: true },
});

const source = audioContext.createMediaStreamSource(mediaStream);
const worklet = new AudioWorkletNode(audioContext, "pcm-worklet");

// Forward each PCM frame to the server the moment it is produced.
worklet.port.onmessage = (e: MessageEvent<ArrayBuffer>) => {
  if (ws.readyState === WebSocket.OPEN) ws.send(e.data);
};
source.connect(worklet);

// Manual commit: tell the server to finalize the current segment.
const commit = () => ws.send(JSON.stringify({ type: "commit" }));

рд╕рд░реНрд╡рд░ рд░рд┐рд▓реЗ

рд╕рд░реНрд╡рд░ рд╣рд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдПрдХ рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдХрдиреЗрдХреНрд╢рди рдЦреЛрд▓рддрд╛ рд╣реИ, API рдХреА рд╕рд░реНрд╡рд░ рдкрд░ рд░рдЦрддрд╛ рд╣реИ, рдмрд╛рдЗрдирд░реА PCM рд╕реАрдзреЗ рдлреЙрд░рд╡рд░реНрдб рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдЗрд╡реЗрдВрдЯреНрд╕ рдХреЛ { type, text } рдХреЗ рд╕реНрдЯреЗрдмрд▓ рдлреЙрд░реНрдореЗрдЯ рдореЗрдВ рдиреЙрд░реНрдорд▓рд╛рдЗрдЬрд╝ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░рддрд╛ рд╣реИ:

// server.ts - Node, using the `ws` library. ELEVENLABS_API_KEY and the
// recognizer URL come from the environment; see the Speech to Text reference
// for the exact path and query parameters.
import { WebSocketServer, WebSocket } from "ws";

new WebSocketServer({ port: 8080 }).on("connection", (client) => {
  // The API key stays on the server, never on the wire to the browser.
  const recognizer = new WebSocket(process.env.RECOGNIZER_WSS_URL!, {
    headers: { "xi-api-key": process.env.ELEVENLABS_API_KEY! },
  });

  // Browser -> recognizer: forward binary PCM, translate control messages.
  client.on("message", (data, isBinary) => {
    if (recognizer.readyState !== WebSocket.OPEN) return;
    if (isBinary) recognizer.send(data); // raw PCM bytes
    else if (JSON.parse(data.toString()).type === "commit")
      recognizer.send(sendCommit());
  });

  // Recognizer -> browser: normalize events into a stable shape.
  recognizer.on("message", (raw) => {
    const event = parseRecognizerEvent(raw.toString());
    if (event && client.readyState === WebSocket.OPEN)
      client.send(JSON.stringify(event));
  });

  // ... open handshake, queueing pre-open audio, and teardown on close/error
});

рд╣рд░ рдПрдВрдбрдкреЙрдЗрдВрдЯ-рд╕реНрдкреЗрд╕рд┐рдлрд┐рдХ рдЪреАрдЬ рдиреАрдЪреЗ рджрд┐рдП рджреЛ рдПрдбреЙрдкреНрдЯрд░ рдлрдВрдХреНрд╢рдиреНрд╕ рдореЗрдВ рд╕реАрдорд┐рдд рд╣реИред рдлреАрд▓реНрдб рдиреЗрдореНрд╕ рдХреЛ рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рд░реЗрдлрд░реЗрдВрд╕ рд╕реЗ рдмрд┐рд▓реНрдХреБрд▓ рд╡реИрд╕реЗ рд╣реА рдмрджрд▓реЗрдВ; рдмрд╛рдХреА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдирд╣реАрдВ рдмрджрд▓рддреА:

// The single place that knows the recognizer's wire format.
const sendCommit = (): string => JSON.stringify({ type: "commit" });

type NormalizedEvent =
  | { type: "partial"; text: string }
  | { type: "final"; text: string }
  | { type: "vad"; speaking: boolean };

function parseRecognizerEvent(raw: string): NormalizedEvent | null {
  const msg = JSON.parse(raw);
  if (msg.is_final === true || msg.type === "final")
    return { type: "final", text: msg.text ?? "" };
  if (msg.type === "vad") return { type: "vad", speaking: !!msg.speaking };
  if (typeof msg.text === "string")
    return { type: "partial", text: msg.text };
  return null;
}

рд╕реНрдХреНрд░рд┐рдкреНрдЯреЗрдмрд▓ рдмреИрдХрдПрдВрдб рдХреНрд▓рд╛рдЗрдВрдЯ

рдмреИрдХрдПрдВрдб рдкрд╛рдЗрдкрд▓рд╛рдЗрдиреНрд╕ рдФрд░ рдиреАрдЪреЗ рджрд┐рдП рдмреЗрдВрдЪрдорд╛рд░реНрдХ рдХреЗ рд▓рд┐рдП, рд╡рд╣реА рд░рд┐рдХрдЧреНрдирд╛рдЗрдЬрд╝рд░ рдХрдиреЗрдХреНрд╢рди рдмрд┐рдирд╛ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЗ рднреА рдЪрд▓рддрд╛ рд╣реИ: рдХрд┐рд╕реА рднреА рд╕реЛрд░реНрд╕ рд╕реЗ PCM рдкрдврд╝реЗрдВ, рдЙрд╕реЗ рд░реАрдпрд▓-рдЯрд╛рдЗрдо рдЪрдВрдХ рдХреИрдбреЗрдВрд╕ рдкрд░ рднреЗрдЬреЗрдВ, рдФрд░ рдЗрд╡реЗрдВрдЯреНрд╕ рд╡рд╛рдкрд╕ рдкрдврд╝реЗрдВред API рдХреА рдФрд░ URL рдПрдирд╡рд╛рдпрд░рдирдореЗрдВрдЯ рд╕реЗ рдЖрддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рд╕рд░реНрд╡рд░ рдкрд░ред

// stream-stt.ts - pace ~100ms chunks at real time, then commit the tail.
const SAMPLE_RATE = 16000, CHUNK_MS = 100;
const CHUNK_BYTES = (SAMPLE_RATE * 2 * CHUNK_MS) / 1000; // 3200 bytes
const ws = new WebSocket(process.env.RECOGNIZER_WSS_URL!, {
  headers: { "xi-api-key": process.env.ELEVENLABS_API_KEY! },
});

// Send: walk the PCM buffer in 100ms chunks, sleeping between to mimic a
// live source. For audio that already arrives in real time, drop the sleep.
async function sendAudio(pcm: Buffer) {
  for (let off = 0; off < pcm.length; off += CHUNK_BYTES) {
    ws.send(pcm.subarray(off, off + CHUNK_BYTES));
    await new Promise((r) => setTimeout(r, CHUNK_MS));
  }
  ws.send(JSON.stringify({ type: "commit" })); // finalize the trailing segment
}

// Receive: print partials in place, append finals.
ws.on("message", (raw) => {
  const e = parseRecognizerEvent(raw.toString());
  if (e?.type === "final") console.log(`[final]   ${e.text}`);
  else if (e?.type === "partial") process.stdout.write(`[partial] ${e.text}\r`);
});

рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рд▓реЗрдЯреЗрдВрд╕реА рдФрд░ рд╡рд░реНрдб рдПрд░рд░ рд░реЗрдЯ рдХреА рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ

рд▓реЗрдЯреЗрдВрд╕реА рдФрд░ рд╡рд░реНрдб рдПрд░рд░ рд░реЗрдЯ рджреЛрдиреЛрдВ рд╕реНрдкреАрдХрд░, рднрд╛рд╖рд╛, рдСрдбрд┐рдпреЛ рдХреА рдХреНрд╡рд╛рд▓рд┐рдЯреА, рдСрдбрд┐рдпреЛ рдХреА рд▓рдВрдмрд╛рдИ, рдЖрдкрдХреЗ рдиреЗрдЯрд╡рд░реНрдХ рдкрд╛рде рдФрд░ рд╣рд░ рд╕рд░реНрд╡рд┐рд╕ рдХреЗ рдХрд░рдВрдЯ рд▓реЛрдб рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреЗ рд╣реИрдВред

рдПрдХ рд▓реИрдкрдЯреЙрдк рд╕реЗ рдПрдХ рд╢рд╣рд░ рдореЗрдВ рдорд╛рдкрд╛ рдЧрдпрд╛ рд░рд┐рдЬрд▓реНрдЯ рдЖрдкрдХреЗ рдкреНрд░реЛрдбрдХреНрд╢рди рдлреНрд▓реАрдЯ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реЛрддрд╛ред рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ рдЙрд╕реА рдЗрдВрдлреНрд░рд╛рд╕реНрдЯреНрд░рдХреНрдЪрд░ рд╕реЗ рдХрд░реЗрдВ рдЬреЛ рдкреНрд░реЛрдбрдХреНрд╢рди рдЬреИрд╕рд╛ рд╣реЛ, рдЙрд╕реА рддрд░рд╣ рдХреЗ рдСрдбрд┐рдпреЛ рдкрд░, рдФрд░ рдПрдХ рдирдВрдмрд░ рдХреА рдмрдЬрд╛рдп рд░реЗрдВрдЬ рдФрд░ рдбрд┐рд╕реНрдЯреНрд░реАрдмреНрдпреВрд╢рди рд░рд┐рдкреЛрд░реНрдЯ рдХрд░реЗрдВред

рд╕рд┐рд░реНрдл рд╡рд╣реА рд▓реЗрдЯреЗрдВрд╕реА рдФрд░ рдПрдХреНрдпреБрд░реЗрд╕реА рдорд╛рдпрдиреЗ рд░рдЦрддреА рд╣реИ рдЬреЛ рдЖрдк рдЕрдкрдиреЗ рдСрдбрд┐рдпреЛ рдФрд░ рдкреНрд░реЛрдбрдХреНрд╢рди рдЬреИрд╕реА рдЗрдВрдлреНрд░рд╛рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдкрд░ рдорд╛рдкрддреЗ рд╣реИрдВред рдпрд╣рд╛рдВ рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рд▓реЗрдЯреЗрдВрд╕реА рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ рдХрд╛ рдЧрд╛рдЗрдб рд╣реИред

рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рд▓реЗрдЯреЗрдВрд╕реА рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдорд╛рдкреЗрдВ

рдиреАрдЪреЗ рд╡реЗ рдореБрдЦреНрдп рдореЗрдЯреНрд░рд┐рдХреНрд╕ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдкрдХреЛ рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рд▓реЗрдЯреЗрдВрд╕реА рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ рдореЗрдВ рдорд╛рдкрдирд╛ рдЪрд╛рд╣рд┐рдП:

  • рдкрд╣рд▓реЗ рдкрд╛рд░реНрдЯрд┐рдпрд▓ рддрдХ рдХрд╛ рд╕рдордп: рдкрд╣рд▓рд╛ рдСрдбрд┐рдпреЛ рдЪрдВрдХ рднреЗрдЬрдиреЗ рд╕реЗ рд▓реЗрдХрд░ рдкрд╣рд▓рд╛ рдиреЙрди-рдПрдореНрдкреНрдЯреА рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдорд┐рд▓рдиреЗ рддрдХред
  • рдкрд╛рд░реНрдЯрд┐рдпрд▓-рд╕реЗ-рдлрд╛рдЗрдирд▓ рд▓реИрдЧ: рдПрдХ рдЙрдЪреНрдЪрд╛рд░рдг рдХреЗ рдЖрдЦрд┐рд░реА рдСрдбрд┐рдпреЛ рдЪрдВрдХ рд╕реЗ рдлрд╛рдЗрдирд▓ рд╣рд╛рдЗрдкреЛрдереЗрд╕рд┐рд╕ рддрдХред
  • рд╡рд░реНрдб рдПрд░рд░ рд░реЗрдЯ (WER): рдлрд╛рдЗрдирд▓ рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рдкрд░ рд╣реНрдпреВрдорди рд░реЗрдлрд░реЗрдВрд╕ рдХреЗ рдореБрдХрд╛рдмрд▓реЗ WER, рд╕рднреА рд╕рд┐рд╕реНрдЯрдореНрд╕ рдореЗрдВ рдПрдХ рд╣реА рддрд░рд╣ рд╕реЗ рдЧрд┐рдирд╛ рдЬрд╛рддрд╛ рд╣реИред
  • рд╕реНрдЯреЗрдмрд┐рд▓рд┐рдЯреА рдЪрд░реНрди: рдлрд╛рдЗрдирд▓рд╛рдЗрдЬреЗрд╢рди рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐рддрдиреЗ рдкрд╛рд░реНрдЯрд┐рдпрд▓ рджреЛрдмрд╛рд░рд╛ рд▓рд┐рдЦреЗ рдЧрдПред рдпрд╣ рдорд╛рдкрддрд╛ рд╣реИ рдХрд┐ рд▓рд╛рдЗрд╡ UI рдХрд┐рддрдирд╛ рдмрджрд▓рддрд╛ рджрд┐рдЦреЗрдЧрд╛ред

рдХрдВрдЯреНрд░реЛрд▓реНрд╕

рдЕрдирд░рд┐рд▓рд╛рдПрдмрд▓ рдбреЗрдЯрд╛ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдПрдХреНрд╕рдкреЗрд░рд┐рдореЗрдВрдЯ рдореЗрдВ рдХреБрдЫ рдХрдВрдЯреНрд░реЛрд▓реНрд╕ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдЪрд╛рд╣рд┐рдП рддрд╛рдХрд┐ рд╕рдм рдХреБрдЫ рдПрдХ рдЬреИрд╕рд╛ рд░рд╣реЗред

рдпрд╣рд╛рдБ рдореБрдЦреНрдп рдХрдВрдЯреНрд░реЛрд▓реНрд╕ рджрд┐рдП рдЧрдП рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк

  • рдПрдХ рдЬреИрд╕рд╛ рдСрдбрд┐рдпреЛ: рд╣рд░ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рд╡рд╣реА рдлрд╛рдЗрд▓реНрд╕, рд╡рд╣реА рд╕реИрдВрдкрд▓ рд░реЗрдЯ рдФрд░ рд╡рд╣реА рдПрдирдХреЛрдбрд┐рдВрдЧ рджреЗрдВред
  • рдПрдХ рдЬреИрд╕реА рд╕реНрдкреАрдб: рд╣рд░ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдПрдХ рд╣реА рд░реАрдпрд▓-рдЯрд╛рдЗрдо рдЪрдВрдХ рдХреИрдбреЗрдВрд╕ (рдЬреИрд╕реЗ 100ms рдЪрдВрдХреНрд╕) рдкрд░ рд╕реНрдЯреНрд░реАрдо рдХрд░реЗрдВред
  • рд░рд┐рдкреАрдЯ рдФрд░ рдбрд┐рд╕реНрдЯреНрд░реАрдмреНрдпреВрд╢рди рд░рд┐рдкреЛрд░реНрдЯ рдХрд░реЗрдВ: рд╣рд░ рдлрд╛рдЗрд▓ рдХреЛ рджрд┐рди рдореЗрдВ рдХрдИ рдмрд╛рд░ рдЪрд▓рд╛рдПрдВ; рдореАрдбрд┐рдпрди рдФрд░ рдЯреЗрд▓ (p50/p95) рд░рд┐рдкреЛрд░реНрдЯ рдХрд░реЗрдВред
  • рдПрдХ рдЬреИрд╕реЗ рд░реЗрдлрд░реЗрдВрд╕ рдФрд░ рд╕реНрдХреЛрд░рд┐рдВрдЧ: WER рдЧрд┐рдирдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЯреЗрдХреНрд╕реНрдЯ рдХреЛ рдПрдХ рд╣реА рддрд░рд╣ (рдХреЗрд╕рд┐рдВрдЧ, рдкрдВрдХреНрдЪреБрдПрд╢рди, рдирдВрдмрд░) рдиреЙрд░реНрдорд▓рд╛рдЗрдЬрд╝ рдХрд░реЗрдВред
  • рд░реАрдЬрди рдФрд░ рдиреЗрдЯрд╡рд░реНрдХ рдмрддрд╛рдПрдВ: рдмрддрд╛рдПрдВ рдХрд┐ рд╣рд╛рд░реНрдиреЗрд╕ рдХрд╣рд╛рдВ рдЪрд▓рд╛ рдФрд░ рд╣рд░ рдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рддрдХ рдкрд╛рде рдХреНрдпрд╛ рдерд╛ред

рдЗрди рд╕рдм рдЪреАрдЬреЛрдВ рдХреЛ рдПрдХ рдЬреИрд╕рд╛ рд░рдЦрдХрд░ рдЖрдк рдЬреНрдпрд╛рджрд╛ рд╕рдЯреАрдХ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдкрд╛рдПрдВрдЧреЗред

рд╣рд╛рд░реНрдиреЗрд╕ рдХрд╛ рдврд╛рдВрдЪрд╛

рдореЗрдЬрд░рдореЗрдВрдЯ рдХреЛрд░ рдПрдХ рдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рдПрдбреЙрдкреНрдЯрд░ рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЯрд╛рдЗрдо-рдЯреВ-рдлрд░реНрд╕реНрдЯ-рдкрд╛рд░реНрдЯрд┐рдпрд▓, рдлрд╛рдЗрдирд▓рд╛рдЗрдЬреЗрд╢рди рд▓реИрдЧ рдФрд░ рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдЪрд░реНрди рд░рд┐рдХреЙрд░реНрдб рдХрд░рддрд╛ рд╣реИ:

// benchmark.ts - measurement core; one StreamFn adapter per provider.
type StreamFn = (
  audioPath: string,
  onEvent: (kind: "partial" | "final", text: string) => void,
  result: RunResult
) => Promise<void>; // adapter sets result.lastChunkSentAt on the final chunk

interface RunResult {
  firstPartialMs?: number;
  finalLagMs?: number;
  hypothesis: string;
  partialEdits: number;
  lastChunkSentAt: number;
  startedAt: number;
}

async function measure(streamFn: StreamFn, audioPath: string): Promise<RunResult> {
  const result: RunResult = {
    hypothesis: "", partialEdits: 0, lastChunkSentAt: 0,
    startedAt: performance.now(),
  };
  let prevPartial = "";

  await streamFn(audioPath, (kind, text) => {
    const now = performance.now();
    if (kind === "partial") {
      if (text && result.firstPartialMs === undefined)
        result.firstPartialMs = now - result.startedAt;
      if (text !== prevPartial) { result.partialEdits++; prevPartial = text; }
    } else { // final
      result.hypothesis = result.hypothesis ? `${result.hypothesis} ${text}` : text;
      if (result.lastChunkSentAt)
        result.finalLagMs = now - result.lastChunkSentAt;
    }
  }, result);

  return result;
}

рд╡рд░реНрдб рдПрд░рд░ рд░реЗрдЯ рдиреЙрд░реНрдорд▓рд╛рдЗрдЬрд╝реНрдб рдЯреЗрдХреНрд╕реНрдЯ рдкрд░ рд╕реНрдЯреИрдВрдбрд░реНрдб рдЯреЛрдХрди-рд▓реЗрд╡рд▓ рд▓реЗрд╡реЗрдирд╕реНрдЯреАрди рдбрд┐рд╕реНрдЯреЗрдВрд╕ рд╣реИред рд░реЗрдлрд░реЗрдВрд╕ рдФрд░ рд╣рд╛рдЗрдкреЛрдереЗрд╕рд┐рд╕ рджреЛрдиреЛрдВ рдкрд░ рд▓реЛрдЕрд░рдХреЗрд╕ рдФрд░ рдкрдВрдХреНрдЪреБрдПрд╢рди рд╣рдЯрд╛рдПрдВ, рдирд╣реАрдВ рддреЛ рдЖрдк рдЕрдкрдиреЗ рдиреЙрд░реНрдорд▓рд╛рдЗрдЬрд╝рд░ рдХреЛ рдорд╛рдкреЗрдВрдЧреЗ, рдореЙрдбрд▓ рдХреЛ рдирд╣реАрдВред рдЗрд╕ рдорд╛рдк рдХреЛ рдПрдХ рд▓реВрдк рдореЗрдВ рдбрд╛рд▓реЗрдВ рдЬреЛ рд╣рд░ рдлрд╛рдЗрд▓ рдХреЛ рд╣рд░ рдкреНрд░реЛрд╡рд╛рдЗрдбрд░ рдкрд░ ~10 рдмрд╛рд░ рдЪрд▓рд╛рдП рдФрд░ рдореАрдбрд┐рдпрди рдЯрд╛рдЗрдо-рдЯреВ-рдлрд░реНрд╕реНрдЯ-рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдФрд░ рдореАрдбрд┐рдпрди WER (p50/p95) рд░рд┐рдкреЛрд░реНрдЯ рдХрд░реЗ, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рд╕реИрдВрдкрд▓ рдиреЗрдЯрд╡рд░реНрдХ рд╡реЗрд░рд┐рдПрдВрд╕ рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЗрд╕реЗ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рджреЛ рдЪреАрдЬреЗрдВ рджреЗрдиреА рд╣реЛрдВрдЧреАред рдкрд╣рд▓реЗ, рд╣рд░ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рдПрдХ StreamFn рдПрдбреЙрдкреНрдЯрд░ рд▓рд┐рдЦреЗрдВред рдКрдкрд░ рджрд┐рдпрд╛ рд╕реНрдХреНрд░рд┐рдкреНрдЯреЗрдмрд▓ рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд╣рд▓реЗ рд╕реЗ рдПрдХ рд╣реИ, рдмрд╛рдХреА рдХреЗ рд▓рд┐рдП рднреА рд╡рд╣реА (audioPath, onEvent, result) рдХреЙрдиреНрдЯреНрд░реИрдХреНрдЯ рдлреЙрд▓реЛ рдХрд░реЗрдВ рдФрд░ result.lastChunkSentAt рд╕реЗрдЯ рдХрд░реЗрдВ рдЬрдм рдлрд╛рдЗрдирд▓ рдСрдбрд┐рдпреЛ рдЪрдВрдХ рднреЗрдЬрд╛ рдЬрд╛рдПред рджреВрд╕рд░рд╛, рдЕрдкрдиреА рдСрдбрд┐рдпреЛ рдлрд╛рдЗрд▓реНрд╕ рдФрд░ рд░реЗрдлрд░реЗрдВрд╕ рд▓реЛрдб рдХрд░реЗрдВ рдФрд░ рдЙрди рдкрд░ рдореЗрдЬрд░реНрд╕ рдЪрд▓рд╛рдПрдВред рдЗрд╕реЗ рдЙрд╕реА рдорд╢реАрди рд╕реЗ рдЪрд▓рд╛рдПрдВ рдЬреЛ рдЖрдкрдХреЗ рдбрд┐рдкреНрд▓реЙрдпрдореЗрдВрдЯ рдЬреИрд╕реА рд╣реЛ, рдЙрд╕реА рддрд░рд╣ рдХреЗ рдСрдбрд┐рдпреЛ рдкрд░, рдФрд░ рдЖрдкрдХреЛ рдПрдХ рджреЛрд╣рд░рд╛рдиреЗ рдпреЛрдЧреНрдп рддреБрд▓рдирд╛ рдорд┐рд▓реЗрдЧреАред

рдХреИрд╕реЗ рдЖрдк рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВтАФрд╕рд╛рд░рд╛рдВрд╢

рдЗрд╕ рдЖрд░реНрдЯрд┐рдХрд▓ рдореЗрдВ рд╣рдордиреЗ рдХрдИ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рд▓ рдмрджрд▓рд╛рд╡ рдХрд╡рд░ рдХрд┐рдП, рдЬрд┐рд╕рд╕реЗ рдЖрдк рдЕрдкрдиреЗ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рдХрд░ рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рдХреЗ рдХрд░реАрдм рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдПрдХ рдкреНрд░реЛрдбрдХреНрд╢рди рд░реАрдпрд▓-рдЯрд╛рдЗрдо STT рд╕рд┐рд╕реНрдЯрдо рдХреБрдЫ рдЕрд╣рдо рдлреИрд╕рд▓реЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ:

  • рдЯреНрд░рд╛рдВрд╕рдкреЛрд░реНрдЯ: рд╕рд┐рдВрдкреНрд▓рд┐рд╕рд┐рдЯреА рдФрд░ рдХрдВрдЯреНрд░реЛрд▓реНрдб рдиреЗрдЯрд╡рд░реНрдХреНрд╕ рдХреЗ рд▓рд┐рдП WebSocket рдЪреБрдиреЗрдВ, рдФрд░ рдЬрдм рд▓реЙрд╕ рдЯреЙрд▓рд░реЗрдВрд╕ рдЪрд╛рд╣рд┐рдП рдпрд╛ рдХрдВрдЬреНрдпреВрдорд░ рдбрд┐рд╡рд╛рдЗрд╕ рд╕реЗ рдХреИрдкреНрдЪрд░ рдХрд░ рд░рд╣реЗ рд╣реЛрдВ рддреЛ WebRTCред
  • рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдФрд░ рдлрд╛рдЗрдирд▓: рдкрд╛рд░реНрдЯрд┐рдпрд▓ рдХреЛ рдкреНрд░реЛрд╡рд┐рдЬрдирд▓ рдФрд░ рдлрд╛рдЗрдирд▓ рдХреЛ рдХрдорд┐рдЯреЗрдб рдорд╛рдиреЗрдВ, рдФрд░ рдЗрдиреНрд╣реЗрдВ рдЕрд▓рдЧ рджрд┐рдЦрд╛рдПрдВ рддрд╛рдХрд┐ рдпреВрдЬрд╝рд░ рдХреЛ рд▓рд╛рдЗрд╡ рдЯреЗрдХреНрд╕реНрдЯ рдкрд░ рднрд░реЛрд╕рд╛ рд╣реЛред
  • рдПрдВрдб-рдкреЙрдЗрдВрдЯрд┐рдВрдЧ: рд╣реИрдВрдбреНрд╕-рдлреНрд░реА рд╕реЗрдЧрдореЗрдВрдЯреЗрд╢рди рдХреЗ рд▓рд┐рдП VAD, рдУрд╡рд░рд░рд╛рдЗрдб рдХреЗ рд▓рд┐рдП рдореИрдиреНрдпреБрдЕрд▓ рдХрдорд┐рдЯ, рдФрд░ рд╕рд╛рдЗрд▓реЗрдВрд╕ рдереНрд░реЗрд╢реЛрд▓реНрдб рдХреЛ рдЗрдВрдЯрд░реИрдХреНрд╢рди рдХреЗ рд╣рд┐рд╕рд╛рдм рд╕реЗ рдЯреНрдпреВрди рдХрд░реЗрдВ, рди рдХрд┐ рдХрд┐рд╕реА рдПрдХ рдорд╛рди рдкрд░ред
  • рдЗрди-рд╕реНрдЯреНрд░реАрдо рдлреАрдЪрд░реНрд╕: рдЗрди-рд╕реНрдЯреНрд░реАрдо рдлреАрдЪрд░реНрд╕ рд╕рд┐рд░реНрдл рд╡рд╣реАрдВ рдСрди рдХрд░реЗрдВ рдЬрд╣рд╛рдВ рд▓рд╛рдЗрд╡ рдПрдХреНрд╕рдкреАрд░рд┐рдпрдВрд╕ рдХреЛ рдЬрд░реВрд░рдд рд╣реЛ, рдмрд╛рдХреА рдХреЛ Scribe v2 рдХреЗ рдмреИрдЪ рдкреНрд░реЛрд╕реЗрд╕ рдореЗрдВ рдбрд╛рд▓реЗрдВред
  • рдСрдбрд┐рдпреЛ рдлреЙрд░реНрдореЗрдЯ: рдЫреЛрдЯреЗ PCM рдлреНрд░реЗрдореНрд╕ рдореЗрдВ рдХреИрдкреНрдЪрд░ рдХрд░реЗрдВ, ~100ms рдХреЗ рдЪрдВрдХреНрд╕ рднреЗрдЬреЗрдВ, рдФрд░ рдЯреЗрд▓реАрдлреЛрдиреА рдХреЗ рд▓рд┐рдП рд╕реЛрд░реНрд╕ рдлреЙрд░реНрдореЗрдЯ рдореИрдЪ рдХрд░реЗрдВред
  • рдмреЗрдВрдЪрдорд╛рд░реНрдХрд┐рдВрдЧ: рдПрдХреНрдпреБрд░реЗрд╕реА рдмрдирд╛рдо рд▓реЗрдЯреЗрдВрд╕реА рдХреЛ рдЕрдкрдиреЗ рдСрдбрд┐рдпреЛ рдФрд░ рдЯрд╛рд░рдЧреЗрдЯ рдореЗрдЯреНрд░рд┐рдХ рдХреЗ рд╣рд┐рд╕рд╛рдм рд╕реЗ рдПрдореНрдкрд┐рд░рд┐рдХрд▓реА рд╕реЗрдЯ рдХрд░реЗрдВред
  • API рд╕реБрд░рдХреНрд╖рд╛: рдЕрдкрдиреА API рдХреА рд╕рд░реНрд╡рд░ рдкрд░ рд░рдЦреЗрдВ, рдпрд╛ рдбрд╛рдпрд░реЗрдХреНрдЯ рдХреНрд▓рд╛рдЗрдВрдЯ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЧрд▓-рдпреВрдЬрд╝ рдЯреЛрдХрди рдмрдирд╛рдПрдВред

рдЕрдЧрд░ рдЖрдк рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╡реЙрдЗрд╕ рдПрдЬреЗрдВрдЯ рдореЗрдВ рд▓реЗрдЯреЗрдВрд╕реА рдХреИрд╕реЗ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝ рдХрд░реЗрдВ, рддреЛ рд╣рдордиреЗ рдЖрдкрдХреЗ рд▓рд┐рдП рдПрдХ рдЧрд╛рдЗрдб рднреА рд▓рд┐рдЦрд╛ рд╣реИред

Scribe v2 Realtime рдХреЗ рд╕рд╛рде рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛рдПрдВ

Scribe v2 Realtime рд▓рдЧрднрдЧ 150ms рдореЙрдбрд▓ рд▓реЗрдЯреЗрдВрд╕реА рдореЗрдВ рдкрд╛рд░реНрдЯрд┐рдпрд▓ рджреЗрддрд╛ рд╣реИред рдЖрдкрдХреЗ рдпреВрдЬрд╝рд░реНрд╕ рдХреЛ рд╡рд╣реА рд▓реЗрдЯреЗрдВрд╕реА рдорд┐рд▓реЗрдЧреА рдпрд╛ рдЬреНрдпрд╛рджрд╛, рдпрд╣ рдЖрдкрдХреЗ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдЖрдк рдХрдВрдЯреНрд░реЛрд▓ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдЖрд░реНрдЯрд┐рдХрд▓ рдореЗрдВ рдмрддрд╛рдП рдЧрдП рд╕реНрдЯреНрд░реИрдЯреЗрдЬреАрдЬрд╝ рд╕реЗ рдЖрдк рдЕрдкрдиреА рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдЯреЗрдВрд╕реА рдШрдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХрд╕реНрдЯрдорд░ рдПрдХреНрд╕рдкреАрд░рд┐рдпрдВрд╕ рд╕реБрдзрд╛рд░ рд╕рдХрддреЗ рд╣реИрдВред

рдФрд░ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рджреЗрдЦреЗрдВ рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рдХреА рдХреНрд╖рдорддрд╛рдПрдВ рдХрд╛ рдУрд╡рд░рд╡реНрдпреВ, рд╣рдорд╛рд░реЗ рдореЙрдбрд▓реНрд╕ рд░реЗрдлрд░реЗрдВрд╕ рдореЗрдВ рдкреВрд░реА рдлреАрдЪрд░ рдФрд░ рднрд╛рд╖рд╛ рд▓рд┐рд╕реНрдЯ рдкрдврд╝реЗрдВ, рдФрд░ рд░реАрдпрд▓-рдЯрд╛рдЗрдо рдкреНрд░реЛрдбрдХреНрдЯ рдкреЗрдЬреЗрдЬрд╝ рджреЗрдЦреЗрдВ: рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ API рдФрд░ рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ.

рдЬрдм рдЖрдк рддреИрдпрд╛рд░ рд╣реЛрдВ, рдореБрдлрд╝реНрдд рдореЗрдВ ElevenLabs рдЕрдХрд╛рдЙрдВрдЯ рдмрдирд╛рдПрдВ рдФрд░ рдЖрдЬ рд╣реА рдЕрдкрдиреА рдкрд╣рд▓реА рдЯреНрд░рд╛рдВрд╕рдХреНрд░рд┐рдкреНрдЯ рд╕реНрдЯреНрд░реАрдо рдХрд░реЗрдВред

рд░реАрдпрд▓-рдЯрд╛рдЗрдо рд╕реНрдкреАрдЪ рдЯреВ рдЯреЗрдХреНрд╕реНрдЯ рд▓реЗрдЯреЗрдВрд╕реА FAQ

рд╕рдВрдмрдВрдзрд┐рдд рд▓реЗрдЦ

рдЙрдЪреНрдЪрддрдо рдЧреБрдгрд╡рддреНрддрд╛ рд╡рд╛рд▓реЗ AI рдСрдбрд┐рдпреЛ рдХреЗ рд╕рд╛рде рдмрдирд╛рдПрдВ