Skip to content

Python/AI client

Python client нужен для AI-сценариев: speech-to-text, summaries, command agents, bots, semantic search по конференции, voice assistant. На первом этапе его лучше делать как receiver/publisher bot поверх WebSocket/WSS API, без native UDP.

Рекомендуемый первый scope

flowchart TB
    Py[Python AI client]
    Control[CommandLoop WS]
    Media[WSMedia WSS mux]
    STT[Speech-to-text]
    LLM[AI logic]
    Out[Optional response: text/audio/control]

    Py --> Control
    Py --> Media
    Media --> STT
    STT --> LLM
    LLM --> Out
    Out --> Control
    Out --> Media

Первый MVP:

  • логин по CommandLoop;
  • вход в конференцию;
  • прием remote microphone streams через WSMedia;
  • Opus decode;
  • передача PCM в STT/AI pipeline;
  • отправка текстового результата в chat или внешний webhook.

Почему WSMedia, а не UDP

Для AI клиента WSS проще:

  • один transport через firewall/NAT;
  • одинаковая модель с browser media;
  • меньше требований к системным правам и UDP routing;
  • проще запускать в облаке и контейнерах.

UDP можно добавить позже для low-latency on-prem deployments.

Предлагаемая структура SDK

python-videograce/
  videograce/
    control.py        # CommandLoop JSON WS
    media_mux.py      # WSMedia binary mux/demux
    protocol.py       # command dataclasses / serializers
    rtp.py            # RTP/RTCP helpers
    opus.py           # decode/encode integration
    client.py         # high-level state machine
  examples/
    record_audio.py
    ai_observer.py
    speaking_bot.py

High-level API

async with VideoGraceClient(server, login, password) as vg:
    await vg.join_conference("default", receive=True, publish=False)

    async for event in vg.events():
        if isinstance(event, RemoteAudioFrame):
            pcm = opus.decode(event.payload)
            text = await stt.feed(pcm)
            if text:
                await vg.send_message(event.conference_tag, text)

Это псевдокод. Реальный SDK должен явно разделять control events и media frames.

Обязательные инварианты SDK

  • Control reconnect и media reconnect независимы.
  • Один WSMedia socket на client/access token.
  • Demux только по ssrc.
  • device_id не использовать для media routing.
  • На reconnect заново отправлять RTP init для receiver streams.
  • Для video receiver отправлять ForceKeyFrame после attach/reconnect.
  • Не создавать локальные devices до connect_to_conference_response OK.

Следующие решения

Вопрос Рекомендация
Какой async runtime asyncio, без thread-heavy модели.
JSON protocol dataclasses + explicit enum values из Engine/Proto.
Media transport Сначала WSMedia mux only.
Audio decode Opus через opuslib, pyogg или собственную thin binding.
Video На первом этапе не декодировать, только audio. Видео добавить отдельным milestone.
Auth Логин/пароль на control, token на media/blob.