spatialreal 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- spatialreal/__init__.py +52 -0
- spatialreal/config.py +101 -0
- spatialreal/errors.py +155 -0
- spatialreal/events.py +66 -0
- spatialreal/logid.py +19 -0
- spatialreal/proto/__init__.py +0 -0
- spatialreal/proto/generated/__init__.py +0 -0
- spatialreal/proto/generated/message_pb2.py +96 -0
- spatialreal/proto/generated/message_pb2.pyi +279 -0
- spatialreal/session.py +613 -0
- spatialreal/version.py +1 -0
- spatialreal-0.1.0.dist-info/METADATA +112 -0
- spatialreal-0.1.0.dist-info/RECORD +15 -0
- spatialreal-0.1.0.dist-info/WHEEL +4 -0
- spatialreal-0.1.0.dist-info/licenses/LICENSE +202 -0
spatialreal/__init__.py
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Copyright 2026 SpatialReal.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""SpatialReal Python SDK — realtime avatar sessions.
|
|
16
|
+
|
|
17
|
+
Successor to the retired ``avatarkit`` package: same wire protocol and session
|
|
18
|
+
semantics, one import swap for existing callers, plus structured playback
|
|
19
|
+
events (``on_playback``) and the WebSocket close-code contract (``CloseCode``,
|
|
20
|
+
``AvatarSDKError.retryable``).
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from .config import (
|
|
24
|
+
AgoraEgressConfig,
|
|
25
|
+
AudioFormat,
|
|
26
|
+
LiveKitEgressConfig,
|
|
27
|
+
SessionConfig,
|
|
28
|
+
)
|
|
29
|
+
from .errors import AvatarSDKError, AvatarSDKErrorCode, CloseCode, SessionTokenError
|
|
30
|
+
from .events import InterruptReason, PlaybackSignal, PlaybackState, PlaybackStateEvent
|
|
31
|
+
from .logid import generate_log_id
|
|
32
|
+
from .session import AvatarSession, new_avatar_session
|
|
33
|
+
from .version import __version__
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
"AgoraEgressConfig",
|
|
37
|
+
"AudioFormat",
|
|
38
|
+
"AvatarSDKError",
|
|
39
|
+
"AvatarSDKErrorCode",
|
|
40
|
+
"AvatarSession",
|
|
41
|
+
"CloseCode",
|
|
42
|
+
"LiveKitEgressConfig",
|
|
43
|
+
"PlaybackSignal",
|
|
44
|
+
"PlaybackStateEvent",
|
|
45
|
+
"PlaybackState",
|
|
46
|
+
"InterruptReason",
|
|
47
|
+
"SessionConfig",
|
|
48
|
+
"SessionTokenError",
|
|
49
|
+
"__version__",
|
|
50
|
+
"generate_log_id",
|
|
51
|
+
"new_avatar_session",
|
|
52
|
+
]
|
spatialreal/config.py
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Session configuration types."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Callable
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from enum import Enum
|
|
9
|
+
|
|
10
|
+
from .events import PlaybackSignal, PlaybackStateEvent
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AudioFormat(str, Enum):
|
|
14
|
+
"""Audio input encoding negotiated for a session.
|
|
15
|
+
|
|
16
|
+
``PCM_S16LE``: raw PCM16 mono at ``sample_rate``.
|
|
17
|
+
``OGG_OPUS``: one continuous, pre-encoded Ogg Opus stream per request id
|
|
18
|
+
(this SDK does not encode client-side; send encoded bytes).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
PCM_S16LE = "pcm_s16le"
|
|
22
|
+
OGG_OPUS = "ogg_opus"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class LiveKitEgressConfig:
|
|
27
|
+
"""Stream the avatar's audio/video into a LiveKit room via the egress service.
|
|
28
|
+
|
|
29
|
+
When set on a session, animation is NOT returned over the WebSocket; the
|
|
30
|
+
egress worker joins the room and publishes synchronized tracks. The WebSocket
|
|
31
|
+
carries only control/lifecycle messages.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
url: str = ""
|
|
35
|
+
api_token: str = field(default="", repr=False)
|
|
36
|
+
room_name: str = ""
|
|
37
|
+
publisher_id: str = ""
|
|
38
|
+
extra_attributes: dict[str, str] = field(default_factory=dict)
|
|
39
|
+
# 0 = server default. Server closes the egress connection when completely silent.
|
|
40
|
+
idle_timeout: int = 0
|
|
41
|
+
# Deprecated pair, kept for wire compatibility; prefer api_token.
|
|
42
|
+
api_key: str = field(default="", repr=False)
|
|
43
|
+
api_secret: str = field(default="", repr=False)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class AgoraEgressConfig:
|
|
48
|
+
"""Stream the avatar's audio/video into an Agora channel via the egress service."""
|
|
49
|
+
|
|
50
|
+
channel_name: str = ""
|
|
51
|
+
token: str = field(default="", repr=False)
|
|
52
|
+
uid: int = 0
|
|
53
|
+
publisher_id: str = ""
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass
|
|
57
|
+
class SessionConfig:
|
|
58
|
+
"""Configuration for an :class:`~spatialreal.AvatarSession`.
|
|
59
|
+
|
|
60
|
+
Callback contract (all callbacks run on the session's event loop and must
|
|
61
|
+
not block):
|
|
62
|
+
|
|
63
|
+
- ``on_playback(signal)``: structured playback lifecycle parsed from
|
|
64
|
+
``ServerResponseAnimation`` — preferred over ``transport_frames``.
|
|
65
|
+
- ``on_playback_state(event)``: structured ``ServerPlaybackState`` for
|
|
66
|
+
egress-mode playback control (pause/resume/interrupt position); only
|
|
67
|
+
arrives when the server declares the ``playback_state`` capability.
|
|
68
|
+
- ``transport_frames(frame_bytes, is_last)``: the raw serialized ``Message``
|
|
69
|
+
envelope, for callers that decode the protobuf themselves.
|
|
70
|
+
- ``on_error(error)``: transport/server errors outside a call site (read
|
|
71
|
+
loop). Errors raised by ``send_audio``/``interrupt`` are raised, not
|
|
72
|
+
routed here.
|
|
73
|
+
- ``on_close()``: fired exactly once when the session ends, whether by
|
|
74
|
+
``close()`` or by the connection dropping.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
avatar_id: str = ""
|
|
78
|
+
api_key: str = field(default="", repr=False)
|
|
79
|
+
app_id: str = ""
|
|
80
|
+
# v2 auth style: False = headers (mobile-style), True = URL query params (web-style).
|
|
81
|
+
use_query_auth: bool = False
|
|
82
|
+
expire_at: datetime | None = None
|
|
83
|
+
sample_rate: int = 16000
|
|
84
|
+
bitrate: int = 0
|
|
85
|
+
audio_format: AudioFormat = AudioFormat.PCM_S16LE
|
|
86
|
+
console_endpoint_url: str = ""
|
|
87
|
+
ingress_endpoint_url: str = ""
|
|
88
|
+
livekit_egress: LiveKitEgressConfig | None = None
|
|
89
|
+
agora_egress: AgoraEgressConfig | None = None
|
|
90
|
+
|
|
91
|
+
on_playback: Callable[[PlaybackSignal], None] | None = None
|
|
92
|
+
on_playback_state: Callable[[PlaybackStateEvent], None] | None = None
|
|
93
|
+
transport_frames: Callable[[bytes, bool], None] | None = None
|
|
94
|
+
on_error: Callable[[Exception], None] | None = None
|
|
95
|
+
on_close: Callable[[], None] | None = None
|
|
96
|
+
|
|
97
|
+
# Timeout for the console session-token HTTP call.
|
|
98
|
+
token_request_timeout: float = 30.0
|
|
99
|
+
|
|
100
|
+
def __post_init__(self) -> None:
|
|
101
|
+
self.audio_format = AudioFormat(self.audio_format)
|
spatialreal/errors.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Error taxonomy for the SpatialReal SDK.
|
|
2
|
+
|
|
3
|
+
Error codes keep the names the retired avatarkit SDK used, so migrating callers
|
|
4
|
+
can keep their logging/branching. New in this SDK: ``CloseCode`` mirrors the
|
|
5
|
+
server's WebSocket close-code contract (40xx = the request is at fault, retrying
|
|
6
|
+
changes nothing; 45xx = the server is briefly unable, retry with backoff), and
|
|
7
|
+
``AvatarSDKError.retryable`` answers "should I reconnect?" so callers don't have
|
|
8
|
+
to memorize the ranges.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from enum import Enum, IntEnum
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AvatarSDKErrorCode(str, Enum):
|
|
17
|
+
"""Stable, log-friendly error codes surfaced by the SDK."""
|
|
18
|
+
|
|
19
|
+
sessionTokenExpired = "sessionTokenExpired"
|
|
20
|
+
sessionTokenInvalid = "sessionTokenInvalid"
|
|
21
|
+
appIDUnrecognized = "appIDUnrecognized"
|
|
22
|
+
appIDMismatch = "appIDMismatch"
|
|
23
|
+
avatarNotFound = "avatarNotFound"
|
|
24
|
+
billingRequired = "billingRequired"
|
|
25
|
+
creditsExhausted = "creditsExhausted"
|
|
26
|
+
sessionDurationExceeded = "sessionDurationExceeded"
|
|
27
|
+
concurrencyLimit = "concurrencyLimit"
|
|
28
|
+
unsupportedSampleRate = "unsupportedSampleRate"
|
|
29
|
+
invalidEgressConfig = "invalidEgressConfig"
|
|
30
|
+
egressUnavailable = "egressUnavailable"
|
|
31
|
+
idleTimeout = "idleTimeout"
|
|
32
|
+
upstreamError = "upstreamError"
|
|
33
|
+
invalidRequest = "invalidRequest"
|
|
34
|
+
connectionFailed = "connectionFailed"
|
|
35
|
+
connectionClosed = "connectionClosed"
|
|
36
|
+
protocolError = "protocolError"
|
|
37
|
+
serverError = "serverError"
|
|
38
|
+
unknown = "unknown"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class CloseCode(IntEnum):
|
|
42
|
+
"""WebSocket close codes the server sends when it ends a session.
|
|
43
|
+
|
|
44
|
+
A client contract, not diagnostics (mirrors driveningress/v2 proto):
|
|
45
|
+
40xx — the request itself is at fault; do not reconnect.
|
|
46
|
+
45xx — transient server-side trouble; reconnect with backoff.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
CREDITS_EXHAUSTED = 4001
|
|
50
|
+
SESSION_TIMEOUT = 4002
|
|
51
|
+
CONCURRENCY_LIMIT = 4003
|
|
52
|
+
AUTH_FAILED = 4010
|
|
53
|
+
UPSTREAM_UNAVAILABLE = 4503
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Close codes for which reconnecting is expected to work.
|
|
57
|
+
_RETRYABLE_CLOSE_CODES = frozenset(
|
|
58
|
+
{
|
|
59
|
+
int(CloseCode.SESSION_TIMEOUT), # proto: "Reconnect is allowed and expected"
|
|
60
|
+
int(CloseCode.UPSTREAM_UNAVAILABLE),
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
_CLOSE_CODE_TO_ERROR = {
|
|
65
|
+
int(CloseCode.CREDITS_EXHAUSTED): AvatarSDKErrorCode.creditsExhausted,
|
|
66
|
+
int(CloseCode.SESSION_TIMEOUT): AvatarSDKErrorCode.sessionDurationExceeded,
|
|
67
|
+
int(CloseCode.CONCURRENCY_LIMIT): AvatarSDKErrorCode.concurrencyLimit,
|
|
68
|
+
int(CloseCode.AUTH_FAILED): AvatarSDKErrorCode.sessionTokenInvalid,
|
|
69
|
+
int(CloseCode.UPSTREAM_UNAVAILABLE): AvatarSDKErrorCode.upstreamError,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class AvatarSDKError(Exception):
|
|
74
|
+
"""SDK exception with a stable error code and structured context."""
|
|
75
|
+
|
|
76
|
+
def __init__(
|
|
77
|
+
self,
|
|
78
|
+
code: AvatarSDKErrorCode,
|
|
79
|
+
message: str,
|
|
80
|
+
*,
|
|
81
|
+
phase: str = "unknown",
|
|
82
|
+
http_status: int | None = None,
|
|
83
|
+
server_code: str | None = None,
|
|
84
|
+
server_detail: str | None = None,
|
|
85
|
+
connection_id: str | None = None,
|
|
86
|
+
req_id: str | None = None,
|
|
87
|
+
raw_body: str | None = None,
|
|
88
|
+
close_code: int | None = None,
|
|
89
|
+
close_reason: str | None = None,
|
|
90
|
+
):
|
|
91
|
+
super().__init__(message)
|
|
92
|
+
self.code = code
|
|
93
|
+
self.message = message
|
|
94
|
+
self.phase = phase
|
|
95
|
+
self.http_status = http_status
|
|
96
|
+
self.server_code = server_code
|
|
97
|
+
self.server_detail = server_detail
|
|
98
|
+
self.connection_id = connection_id
|
|
99
|
+
self.req_id = req_id
|
|
100
|
+
self.raw_body = raw_body
|
|
101
|
+
self.close_code = close_code
|
|
102
|
+
self.close_reason = close_reason
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def retryable(self) -> bool:
|
|
106
|
+
"""Whether reconnecting can plausibly succeed, per the close-code contract.
|
|
107
|
+
|
|
108
|
+
Unknown/absent close codes count as retryable: transport-level failures
|
|
109
|
+
(network blips, process restarts) close without our 40xx codes, and for
|
|
110
|
+
those, giving up for good is the wrong default.
|
|
111
|
+
"""
|
|
112
|
+
if self.close_code is None:
|
|
113
|
+
return self.code in (
|
|
114
|
+
AvatarSDKErrorCode.connectionFailed,
|
|
115
|
+
AvatarSDKErrorCode.connectionClosed,
|
|
116
|
+
AvatarSDKErrorCode.upstreamError,
|
|
117
|
+
)
|
|
118
|
+
if self.close_code in _RETRYABLE_CLOSE_CODES:
|
|
119
|
+
return True
|
|
120
|
+
if 4000 <= self.close_code < 4500:
|
|
121
|
+
return False
|
|
122
|
+
return True
|
|
123
|
+
|
|
124
|
+
def __str__(self) -> str: # pragma: no cover
|
|
125
|
+
return f"{self.code.value}: {self.message}"
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class SessionTokenError(AvatarSDKError):
|
|
129
|
+
"""Raised when the session-token exchange with the console API fails."""
|
|
130
|
+
|
|
131
|
+
def __init__(
|
|
132
|
+
self,
|
|
133
|
+
message: str,
|
|
134
|
+
*,
|
|
135
|
+
code: AvatarSDKErrorCode = AvatarSDKErrorCode.invalidRequest,
|
|
136
|
+
http_status: int | None = None,
|
|
137
|
+
server_code: str | None = None,
|
|
138
|
+
server_detail: str | None = None,
|
|
139
|
+
raw_body: str | None = None,
|
|
140
|
+
):
|
|
141
|
+
super().__init__(
|
|
142
|
+
code=code,
|
|
143
|
+
message=message,
|
|
144
|
+
phase="session_token",
|
|
145
|
+
http_status=http_status,
|
|
146
|
+
server_code=server_code,
|
|
147
|
+
server_detail=server_detail,
|
|
148
|
+
raw_body=raw_body,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def error_code_for_close_code(close_code: int | None) -> AvatarSDKErrorCode:
|
|
153
|
+
if close_code is None:
|
|
154
|
+
return AvatarSDKErrorCode.connectionClosed
|
|
155
|
+
return _CLOSE_CODE_TO_ERROR.get(close_code, AvatarSDKErrorCode.connectionClosed)
|
spatialreal/events.py
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Structured events the SDK surfaces to callers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from enum import Enum
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True)
|
|
10
|
+
class PlaybackSignal:
|
|
11
|
+
"""Playback lifecycle parsed from a ``ServerResponseAnimation`` message.
|
|
12
|
+
|
|
13
|
+
Semantics depend on the delivery mode:
|
|
14
|
+
|
|
15
|
+
- WebSocket direct return: frames carry animation data; ``end=True`` means
|
|
16
|
+
generation for the request is complete.
|
|
17
|
+
- LiveKit/Agora egress: frames are empty control signals; a non-end frame
|
|
18
|
+
marks playback progress/start and ``end=True`` means the egress playout
|
|
19
|
+
for the request has fully drained. Egress-path retransmission can deliver
|
|
20
|
+
``end=True`` more than once per ``req_id`` — dedupe on the consumer side.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
req_id: str
|
|
24
|
+
end: bool
|
|
25
|
+
connection_id: str = ""
|
|
26
|
+
avatar_id: str = ""
|
|
27
|
+
has_animation: bool = False
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class PlaybackState(str, Enum):
|
|
31
|
+
"""State reported by a ``ServerPlaybackState`` message (egress mode)."""
|
|
32
|
+
|
|
33
|
+
UNSPECIFIED = "unspecified"
|
|
34
|
+
PLAYING = "playing"
|
|
35
|
+
PAUSED = "paused"
|
|
36
|
+
ENDED = "ended"
|
|
37
|
+
INTERRUPTED = "interrupted"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class InterruptReason(str, Enum):
|
|
41
|
+
"""``reason`` on an INTERRUPTED playback state."""
|
|
42
|
+
|
|
43
|
+
EXPLICIT = "explicit" # an explicit interrupt() / client interrupt
|
|
44
|
+
PREEMPTED = "preempted" # a newer request superseded this one
|
|
45
|
+
PAUSE_TIMEOUT = "pause_timeout" # a held pause exceeded the server limit
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass(frozen=True)
|
|
49
|
+
class PlaybackStateEvent:
|
|
50
|
+
"""Structured ``ServerPlaybackState`` (egress-mode playback control, #51).
|
|
51
|
+
|
|
52
|
+
Emitted for every ``pause()``/``resume()`` (the state *after* the operation)
|
|
53
|
+
and spontaneously by the server on playback start/end/interrupt. Only sent
|
|
54
|
+
when the server declared the ``playback_state`` capability; older servers
|
|
55
|
+
never send it. ``played_ms`` is content playout position (excludes
|
|
56
|
+
transitions, does not advance while paused). ``reason`` is meaningful only
|
|
57
|
+
for ``INTERRUPTED`` — notably ``pause_timeout`` means a held pause hit the
|
|
58
|
+
server limit and the caller should treat the segment as interrupted (drop
|
|
59
|
+
retained audio, do not resume).
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
req_id: str
|
|
63
|
+
state: PlaybackState
|
|
64
|
+
played_ms: int = 0
|
|
65
|
+
reason: str = ""
|
|
66
|
+
connection_id: str = ""
|
spatialreal/logid.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Request/log id generation.
|
|
2
|
+
|
|
3
|
+
Format is shared with the Go backend and the retired avatarkit SDK:
|
|
4
|
+
"YYYYMMDDHHMMSS_<nanoid12>" (UTC). Every request gets a fresh id; ids are
|
|
5
|
+
never reused within a connection — the plugin's interrupt bookkeeping and the
|
|
6
|
+
backend's session mapping both rely on uniqueness.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
|
+
|
|
11
|
+
from nanoid import generate
|
|
12
|
+
|
|
13
|
+
LOG_ID_TIME_FORMAT = "%Y%m%d%H%M%S"
|
|
14
|
+
LOG_ID_NANOID_LENGTH = 12
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def generate_log_id() -> str:
|
|
18
|
+
timestamp = datetime.now(timezone.utc).strftime(LOG_ID_TIME_FORMAT)
|
|
19
|
+
return f"{timestamp}_{generate(size=LOG_ID_NANOID_LENGTH)}"
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: driveningress/v2/driveningress.proto
|
|
5
|
+
# Protobuf Python Version: 6.31.1
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
6,
|
|
15
|
+
31,
|
|
16
|
+
1,
|
|
17
|
+
'',
|
|
18
|
+
'driveningress/v2/driveningress.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$driveningress/v2/driveningress.proto\x12\x10\x64riveningress.v2\x1a\x1cgoogle/protobuf/struct.proto\"\xa7\x02\n\x13LiveKitEgressConfig\x12\x0b\n\x03url\x18\x01 \x01(\t\x12\x0f\n\x07\x61pi_key\x18\x02 \x01(\t\x12\x12\n\napi_secret\x18\x03 \x01(\t\x12\x11\n\troom_name\x18\x04 \x01(\t\x12\x14\n\x0cpublisher_id\x18\x05 \x01(\t\x12T\n\x10\x65xtra_attributes\x18\x06 \x03(\x0b\x32:.driveningress.v2.LiveKitEgressConfig.ExtraAttributesEntry\x12\x14\n\x0cidle_timeout\x18\x07 \x01(\x05\x12\x11\n\tapi_token\x18\x08 \x01(\t\x1a\x36\n\x14\x45xtraAttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"[\n\x11\x41goraEgressConfig\x12\x14\n\x0c\x63hannel_name\x18\x01 \x01(\t\x12\r\n\x05token\x18\x02 \x01(\t\x12\x0b\n\x03uid\x18\x03 \x01(\r\x12\x14\n\x0cpublisher_id\x18\x04 \x01(\t\"\xa4\x01\n\x13\x44rivenIngressConfig\x12\x11\n\tshape_npy\x18\x01 \x01(\x0c\x12\x11\n\tstyle_npy\x18\x02 \x01(\x0c\x12\x19\n\x11\x64riven_server_url\x18\x03 \x01(\t\x12/\n\x0emodel_settings\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x1b\n\x13\x65ncoder_start_frame\x18\x05 \x01(\x05\"\xe7\x02\n\x16\x43lientConfigureSession\x12\x13\n\x0bsample_rate\x18\x01 \x01(\x05\x12\x0f\n\x07\x62itrate\x18\x02 \x01(\x05\x12\x33\n\x0c\x61udio_format\x18\x03 \x01(\x0e\x32\x1d.driveningress.v2.AudioFormat\x12\x45\n\x15transport_compression\x18\x04 \x01(\x0e\x32&.driveningress.v2.TransportCompression\x12\x31\n\x0b\x65gress_type\x18\x05 \x01(\x0e\x32\x1c.driveningress.v2.EgressType\x12=\n\x0elivekit_egress\x18\x06 \x01(\x0b\x32%.driveningress.v2.LiveKitEgressConfig\x12\x39\n\x0c\x61gora_egress\x18\x07 \x01(\x0b\x32#.driveningress.v2.AgoraEgressConfig\"C\n\x14ServerConfirmSession\x12\x15\n\rconnection_id\x18\x01 \x01(\t\x12\x14\n\x0c\x63\x61pabilities\x18\x02 \x03(\t\">\n\x10\x43lientAudioInput\x12\x0e\n\x06req_id\x18\x01 \x01(\t\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x08\x12\r\n\x05\x61udio\x18\x03 \x01(\x0c\"S\n\x0bServerError\x12\x15\n\rconnection_id\x18\x01 \x01(\t\x12\x0e\n\x06req_id\x18\x02 \x01(\t\x12\x0c\n\x04\x63ode\x18\x03 \x01(\x05\x12\x0f\n\x07message\x18\x04 \x01(\t\"\xa6\x01\n\x05\x46lame\x12\x17\n\x0btranslation\x18\x01 \x03(\x02\x42\x02\x10\x01\x12\x14\n\x08rotation\x18\x02 \x03(\x02\x42\x02\x10\x01\x12\x15\n\tneck_pose\x18\x03 \x03(\x02\x42\x02\x10\x01\x12\x14\n\x08jaw_pose\x18\x04 \x03(\x02\x42\x02\x10\x01\x12\x14\n\x08\x65ye_pose\x18\x05 \x03(\x02\x42\x02\x10\x01\x12\x13\n\x07\x65ye_lid\x18\x06 \x03(\x02\x42\x02\x10\x01\x12\x16\n\nexpression\x18\x07 \x03(\x02\x42\x02\x10\x01\"<\n\x0e\x46lameAnimation\x12*\n\tkeyframes\x18\x01 \x03(\x0b\x32\x17.driveningress.v2.Flame\"\x95\x01\n\x17ServerResponseAnimation\x12\x15\n\rconnection_id\x18\x01 \x01(\t\x12\x0e\n\x06req_id\x18\x02 \x01(\t\x12\x0b\n\x03\x65nd\x18\x03 \x01(\x08\x12\x33\n\tanimation\x18\x04 \x01(\x0b\x32 .driveningress.v2.FlameAnimation\x12\x11\n\tavatar_id\x18\x05 \x01(\t\"!\n\x0f\x43lientInterrupt\x12\x0e\n\x06req_id\x18\x01 \x01(\t\"\x1d\n\x0b\x43lientPause\x12\x0e\n\x06req_id\x18\x01 \x01(\t\"\x1e\n\x0c\x43lientResume\x12\x0e\n\x06req_id\x18\x01 \x01(\t\"\xf0\x01\n\x13ServerPlaybackState\x12\x15\n\rconnection_id\x18\x01 \x01(\t\x12\x0e\n\x06req_id\x18\x02 \x01(\t\x12:\n\x05state\x18\x03 \x01(\x0e\x32+.driveningress.v2.ServerPlaybackState.State\x12\x11\n\tplayed_ms\x18\x04 \x01(\x03\x12\x0e\n\x06reason\x18\x05 \x01(\t\"S\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x0b\n\x07PLAYING\x10\x01\x12\n\n\x06PAUSED\x10\x02\x12\t\n\x05\x45NDED\x10\x03\x12\x0f\n\x0bINTERRUPTED\x10\x04\"\xd6\x05\n\x07Message\x12+\n\x04type\x18\x01 \x01(\x0e\x32\x1d.driveningress.v2.MessageType\x12L\n\x18\x63lient_configure_session\x18\x02 \x01(\x0b\x32(.driveningress.v2.ClientConfigureSessionH\x00\x12H\n\x16server_confirm_session\x18\x03 \x01(\x0b\x32&.driveningress.v2.ServerConfirmSessionH\x00\x12@\n\x12\x63lient_audio_input\x18\x04 \x01(\x0b\x32\".driveningress.v2.ClientAudioInputH\x00\x12\x35\n\x0cserver_error\x18\x05 \x01(\x0b\x32\x1d.driveningress.v2.ServerErrorH\x00\x12N\n\x19server_response_animation\x18\x06 \x01(\x0b\x32).driveningress.v2.ServerResponseAnimationH\x00\x12>\n\rdriven_config\x18\x07 \x01(\x0b\x32%.driveningress.v2.DrivenIngressConfigH\x00\x12=\n\x10\x63lient_interrupt\x18\x08 \x01(\x0b\x32!.driveningress.v2.ClientInterruptH\x00\x12\x35\n\x0c\x63lient_pause\x18\t \x01(\x0b\x32\x1d.driveningress.v2.ClientPauseH\x00\x12\x37\n\rclient_resume\x18\n \x01(\x0b\x32\x1e.driveningress.v2.ClientResumeH\x00\x12\x46\n\x15server_playback_state\x18\x0b \x01(\x0b\x32%.driveningress.v2.ServerPlaybackStateH\x00\x42\x06\n\x04\x64\x61ta*\xe9\x02\n\x0bMessageType\x12\x17\n\x13MESSAGE_UNSPECIFIED\x10\x00\x12$\n MESSAGE_CLIENT_CONFIGURE_SESSION\x10\x01\x12\"\n\x1eMESSAGE_SERVER_CONFIRM_SESSION\x10\x02\x12\x1e\n\x1aMESSAGE_CLIENT_AUDIO_INPUT\x10\x03\x12\x18\n\x14MESSAGE_SERVER_ERROR\x10\x04\x12%\n!MESSAGE_SERVER_RESPONSE_ANIMATION\x10\x05\x12 \n\x1cMESSAGE_CLIENT_DRIVEN_CONFIG\x10\x06\x12\x1c\n\x18MESSAGE_CLIENT_INTERRUPT\x10\x07\x12\x18\n\x14MESSAGE_CLIENT_PAUSE\x10\x08\x12\x19\n\x15MESSAGE_CLIENT_RESUME\x10\t\x12!\n\x1dMESSAGE_SERVER_PLAYBACK_STATE\x10\n*D\n\x0b\x41udioFormat\x12\x1a\n\x16\x41UDIO_FORMAT_PCM_S16LE\x10\x00\x12\x19\n\x15\x41UDIO_FORMAT_OGG_OPUS\x10\x01*6\n\x14TransportCompression\x12\x1e\n\x1aTRANSPORT_COMPRESSION_NONE\x10\x00*Y\n\nEgressType\x12\x1b\n\x17\x45GRESS_TYPE_UNSPECIFIED\x10\x00\x12\x17\n\x13\x45GRESS_TYPE_LIVEKIT\x10\x01\x12\x15\n\x11\x45GRESS_TYPE_AGORA\x10\x02*\xd1\x01\n\tCloseCode\x12\x1a\n\x16\x43LOSE_CODE_UNSPECIFIED\x10\x00\x12!\n\x1c\x43LOSE_CODE_CREDITS_EXHAUSTED\x10\xa1\x1f\x12\x1f\n\x1a\x43LOSE_CODE_SESSION_TIMEOUT\x10\xa2\x1f\x12!\n\x1c\x43LOSE_CODE_CONCURRENCY_LIMIT\x10\xa3\x1f\x12\x1b\n\x16\x43LOSE_CODE_AUTH_FAILED\x10\xaa\x1f\x12$\n\x1f\x43LOSE_CODE_UPSTREAM_UNAVAILABLE\x10\x97#BEZCgithub.com/SpatialReal-ai/backend-ng/api/generated/driveningress/v2b\x06proto3')
|
|
29
|
+
|
|
30
|
+
_globals = globals()
|
|
31
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
32
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'driveningress.v2.driveningress_pb2', _globals)
|
|
33
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
34
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
|
35
|
+
_globals['DESCRIPTOR']._serialized_options = b'ZCgithub.com/SpatialReal-ai/backend-ng/api/generated/driveningress/v2'
|
|
36
|
+
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._loaded_options = None
|
|
37
|
+
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._serialized_options = b'8\001'
|
|
38
|
+
_globals['_FLAME'].fields_by_name['translation']._loaded_options = None
|
|
39
|
+
_globals['_FLAME'].fields_by_name['translation']._serialized_options = b'\020\001'
|
|
40
|
+
_globals['_FLAME'].fields_by_name['rotation']._loaded_options = None
|
|
41
|
+
_globals['_FLAME'].fields_by_name['rotation']._serialized_options = b'\020\001'
|
|
42
|
+
_globals['_FLAME'].fields_by_name['neck_pose']._loaded_options = None
|
|
43
|
+
_globals['_FLAME'].fields_by_name['neck_pose']._serialized_options = b'\020\001'
|
|
44
|
+
_globals['_FLAME'].fields_by_name['jaw_pose']._loaded_options = None
|
|
45
|
+
_globals['_FLAME'].fields_by_name['jaw_pose']._serialized_options = b'\020\001'
|
|
46
|
+
_globals['_FLAME'].fields_by_name['eye_pose']._loaded_options = None
|
|
47
|
+
_globals['_FLAME'].fields_by_name['eye_pose']._serialized_options = b'\020\001'
|
|
48
|
+
_globals['_FLAME'].fields_by_name['eye_lid']._loaded_options = None
|
|
49
|
+
_globals['_FLAME'].fields_by_name['eye_lid']._serialized_options = b'\020\001'
|
|
50
|
+
_globals['_FLAME'].fields_by_name['expression']._loaded_options = None
|
|
51
|
+
_globals['_FLAME'].fields_by_name['expression']._serialized_options = b'\020\001'
|
|
52
|
+
_globals['_MESSAGETYPE']._serialized_start=2680
|
|
53
|
+
_globals['_MESSAGETYPE']._serialized_end=3041
|
|
54
|
+
_globals['_AUDIOFORMAT']._serialized_start=3043
|
|
55
|
+
_globals['_AUDIOFORMAT']._serialized_end=3111
|
|
56
|
+
_globals['_TRANSPORTCOMPRESSION']._serialized_start=3113
|
|
57
|
+
_globals['_TRANSPORTCOMPRESSION']._serialized_end=3167
|
|
58
|
+
_globals['_EGRESSTYPE']._serialized_start=3169
|
|
59
|
+
_globals['_EGRESSTYPE']._serialized_end=3258
|
|
60
|
+
_globals['_CLOSECODE']._serialized_start=3261
|
|
61
|
+
_globals['_CLOSECODE']._serialized_end=3470
|
|
62
|
+
_globals['_LIVEKITEGRESSCONFIG']._serialized_start=89
|
|
63
|
+
_globals['_LIVEKITEGRESSCONFIG']._serialized_end=384
|
|
64
|
+
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._serialized_start=330
|
|
65
|
+
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._serialized_end=384
|
|
66
|
+
_globals['_AGORAEGRESSCONFIG']._serialized_start=386
|
|
67
|
+
_globals['_AGORAEGRESSCONFIG']._serialized_end=477
|
|
68
|
+
_globals['_DRIVENINGRESSCONFIG']._serialized_start=480
|
|
69
|
+
_globals['_DRIVENINGRESSCONFIG']._serialized_end=644
|
|
70
|
+
_globals['_CLIENTCONFIGURESESSION']._serialized_start=647
|
|
71
|
+
_globals['_CLIENTCONFIGURESESSION']._serialized_end=1006
|
|
72
|
+
_globals['_SERVERCONFIRMSESSION']._serialized_start=1008
|
|
73
|
+
_globals['_SERVERCONFIRMSESSION']._serialized_end=1075
|
|
74
|
+
_globals['_CLIENTAUDIOINPUT']._serialized_start=1077
|
|
75
|
+
_globals['_CLIENTAUDIOINPUT']._serialized_end=1139
|
|
76
|
+
_globals['_SERVERERROR']._serialized_start=1141
|
|
77
|
+
_globals['_SERVERERROR']._serialized_end=1224
|
|
78
|
+
_globals['_FLAME']._serialized_start=1227
|
|
79
|
+
_globals['_FLAME']._serialized_end=1393
|
|
80
|
+
_globals['_FLAMEANIMATION']._serialized_start=1395
|
|
81
|
+
_globals['_FLAMEANIMATION']._serialized_end=1455
|
|
82
|
+
_globals['_SERVERRESPONSEANIMATION']._serialized_start=1458
|
|
83
|
+
_globals['_SERVERRESPONSEANIMATION']._serialized_end=1607
|
|
84
|
+
_globals['_CLIENTINTERRUPT']._serialized_start=1609
|
|
85
|
+
_globals['_CLIENTINTERRUPT']._serialized_end=1642
|
|
86
|
+
_globals['_CLIENTPAUSE']._serialized_start=1644
|
|
87
|
+
_globals['_CLIENTPAUSE']._serialized_end=1673
|
|
88
|
+
_globals['_CLIENTRESUME']._serialized_start=1675
|
|
89
|
+
_globals['_CLIENTRESUME']._serialized_end=1705
|
|
90
|
+
_globals['_SERVERPLAYBACKSTATE']._serialized_start=1708
|
|
91
|
+
_globals['_SERVERPLAYBACKSTATE']._serialized_end=1948
|
|
92
|
+
_globals['_SERVERPLAYBACKSTATE_STATE']._serialized_start=1865
|
|
93
|
+
_globals['_SERVERPLAYBACKSTATE_STATE']._serialized_end=1948
|
|
94
|
+
_globals['_MESSAGE']._serialized_start=1951
|
|
95
|
+
_globals['_MESSAGE']._serialized_end=2677
|
|
96
|
+
# @@protoc_insertion_point(module_scope)
|