spatialreal 0.2.2__tar.gz → 0.3.0__tar.gz
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-0.2.2 → spatialreal-0.3.0}/PKG-INFO +37 -4
- {spatialreal-0.2.2 → spatialreal-0.3.0}/README.md +34 -1
- {spatialreal-0.2.2 → spatialreal-0.3.0}/pyproject.toml +2 -2
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/__init__.py +4 -1
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/config.py +25 -1
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/errors.py +20 -0
- spatialreal-0.3.0/spatialreal/proto/generated/message_pb2.py +74 -0
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/proto/generated/message_pb2.pyi +14 -4
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/session.py +46 -5
- spatialreal-0.3.0/spatialreal/version.py +1 -0
- spatialreal-0.2.2/spatialreal/proto/generated/message_pb2.py +0 -72
- spatialreal-0.2.2/spatialreal/version.py +0 -1
- {spatialreal-0.2.2 → spatialreal-0.3.0}/.gitignore +0 -0
- {spatialreal-0.2.2 → spatialreal-0.3.0}/LICENSE +0 -0
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/environments.py +0 -0
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/events.py +0 -0
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/logid.py +0 -0
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/proto/__init__.py +0 -0
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/proto/generated/__init__.py +0 -0
- {spatialreal-0.2.2 → spatialreal-0.3.0}/spatialreal/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: spatialreal
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: SpatialReal Python SDK — realtime avatar sessions (audio in, animation/egress out)
|
|
5
5
|
Project-URL: Documentation, https://docs.spatialreal.ai
|
|
6
6
|
Project-URL: Website, https://www.spatialreal.ai/
|
|
@@ -22,10 +22,10 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
|
22
22
|
Requires-Python: >=3.10.0
|
|
23
23
|
Requires-Dist: aiohttp>=3.9
|
|
24
24
|
Requires-Dist: nanoid>=2.0
|
|
25
|
-
Requires-Dist: protobuf<8,>=
|
|
25
|
+
Requires-Dist: protobuf<8,>=5.29
|
|
26
26
|
Requires-Dist: websockets>=12
|
|
27
27
|
Provides-Extra: dev
|
|
28
|
-
Requires-Dist: grpcio-tools==1.
|
|
28
|
+
Requires-Dist: grpcio-tools==1.71.2; extra == 'dev'
|
|
29
29
|
Requires-Dist: pytest; extra == 'dev'
|
|
30
30
|
Requires-Dist: pytest-asyncio; extra == 'dev'
|
|
31
31
|
Requires-Dist: ruff; extra == 'dev'
|
|
@@ -46,8 +46,8 @@ from spatialreal import LiveKitEgressConfig, new_avatar_session
|
|
|
46
46
|
|
|
47
47
|
session = new_avatar_session(
|
|
48
48
|
api_key="...",
|
|
49
|
-
app_id="...",
|
|
50
49
|
avatar_id="...",
|
|
50
|
+
# app_id is optional: the app is derived from the API key server-side
|
|
51
51
|
expire_at=datetime.now(timezone.utc) + timedelta(hours=1),
|
|
52
52
|
sample_rate=16000,
|
|
53
53
|
livekit_egress=LiveKitEgressConfig(url=..., api_token=..., room_name=..., publisher_id=...),
|
|
@@ -64,6 +64,31 @@ await session.interrupt() # interrupts the latest request
|
|
|
64
64
|
await session.close()
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
+
### Agora source-timeline-only viewers
|
|
68
|
+
|
|
69
|
+
Set `AgoraEgressConfig(source_timeline_only=True, ...)` only when every viewer
|
|
70
|
+
plays the source-timeline audio and manages its own entry transition. The default
|
|
71
|
+
is `False`, which retains the existing RTC delivery policy. This setting does not
|
|
72
|
+
change input sample rates or audio data.
|
|
73
|
+
|
|
74
|
+
`start()` requires the server's `agora_source_timeline_only` capability when this
|
|
75
|
+
mode is requested. A confirmation without it raises `UnsupportedConfigurationError`
|
|
76
|
+
(`protocolError`, `websocket_handshake`, not retryable) and closes the connection
|
|
77
|
+
before audio is sent. A standard WebSocket policy rejection (`1008`) is also not
|
|
78
|
+
retryable. Other transport failures retain their normal retry behavior.
|
|
79
|
+
|
|
80
|
+
For the coordinated bounded-burst profile, also set
|
|
81
|
+
`source_playback_profile=RtcSourcePlaybackProfile.BOUNDED_BURST_V1` (import the
|
|
82
|
+
enum from `spatialreal`). It requires `source_timeline_only=True` and both
|
|
83
|
+
`agora_source_timeline_only` and `agora_source_burst_v1` in the server's actual
|
|
84
|
+
confirmation. `session.capabilities` is the read-only tuple from that handshake.
|
|
85
|
+
Missing acceptance closes the connection before the read loop or audio starts;
|
|
86
|
+
there is no silent fallback. The default `UNSPECIFIED`/0 is omitted on the wire
|
|
87
|
+
and retains existing behavior. Unknown values and booleans are rejected.
|
|
88
|
+
|
|
89
|
+
Every animation viewer must independently opt into the same profile using a
|
|
90
|
+
compatible viewer SDK; the publisher's handshake cannot negotiate room viewers.
|
|
91
|
+
|
|
67
92
|
### Pause / resume (egress mode)
|
|
68
93
|
|
|
69
94
|
When the server declares the `playback_control` capability, the current
|
|
@@ -102,6 +127,14 @@ implements the server's WebSocket close-code contract (40xx: don't retry,
|
|
|
102
127
|
|
|
103
128
|
## What's new
|
|
104
129
|
|
|
130
|
+
- 0.3.0: Agora source playback negotiation. `AgoraEgressConfig(source_timeline_only=True)`
|
|
131
|
+
requests source-timeline-only playback; `source_playback_profile=RtcSourcePlaybackProfile.BOUNDED_BURST_V1`
|
|
132
|
+
requests the bounded source playback profile. `start()` refuses the session
|
|
133
|
+
(`UnsupportedConfigurationError`, not retryable) before any audio is sent when the
|
|
134
|
+
server does not confirm the matching capabilities (`agora_source_timeline_only`,
|
|
135
|
+
`agora_source_burst_v1`). Defaults are unchanged.
|
|
136
|
+
- 0.2.3: `app_id` is optional (the API key identifies the app); protobuf floor lowered
|
|
137
|
+
to 5.29 so the SDK installs next to packages that pin protobuf 5.x (TEN Framework agents).
|
|
105
138
|
- `on_playback(PlaybackSignal)` — structured playback lifecycle; no protobuf
|
|
106
139
|
parsing in caller code (`transport_frames(raw, is_last)` still exists).
|
|
107
140
|
- `CloseCode` + `AvatarSDKError.retryable` — the reconnect contract as API.
|
|
@@ -13,8 +13,8 @@ from spatialreal import LiveKitEgressConfig, new_avatar_session
|
|
|
13
13
|
|
|
14
14
|
session = new_avatar_session(
|
|
15
15
|
api_key="...",
|
|
16
|
-
app_id="...",
|
|
17
16
|
avatar_id="...",
|
|
17
|
+
# app_id is optional: the app is derived from the API key server-side
|
|
18
18
|
expire_at=datetime.now(timezone.utc) + timedelta(hours=1),
|
|
19
19
|
sample_rate=16000,
|
|
20
20
|
livekit_egress=LiveKitEgressConfig(url=..., api_token=..., room_name=..., publisher_id=...),
|
|
@@ -31,6 +31,31 @@ await session.interrupt() # interrupts the latest request
|
|
|
31
31
|
await session.close()
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
### Agora source-timeline-only viewers
|
|
35
|
+
|
|
36
|
+
Set `AgoraEgressConfig(source_timeline_only=True, ...)` only when every viewer
|
|
37
|
+
plays the source-timeline audio and manages its own entry transition. The default
|
|
38
|
+
is `False`, which retains the existing RTC delivery policy. This setting does not
|
|
39
|
+
change input sample rates or audio data.
|
|
40
|
+
|
|
41
|
+
`start()` requires the server's `agora_source_timeline_only` capability when this
|
|
42
|
+
mode is requested. A confirmation without it raises `UnsupportedConfigurationError`
|
|
43
|
+
(`protocolError`, `websocket_handshake`, not retryable) and closes the connection
|
|
44
|
+
before audio is sent. A standard WebSocket policy rejection (`1008`) is also not
|
|
45
|
+
retryable. Other transport failures retain their normal retry behavior.
|
|
46
|
+
|
|
47
|
+
For the coordinated bounded-burst profile, also set
|
|
48
|
+
`source_playback_profile=RtcSourcePlaybackProfile.BOUNDED_BURST_V1` (import the
|
|
49
|
+
enum from `spatialreal`). It requires `source_timeline_only=True` and both
|
|
50
|
+
`agora_source_timeline_only` and `agora_source_burst_v1` in the server's actual
|
|
51
|
+
confirmation. `session.capabilities` is the read-only tuple from that handshake.
|
|
52
|
+
Missing acceptance closes the connection before the read loop or audio starts;
|
|
53
|
+
there is no silent fallback. The default `UNSPECIFIED`/0 is omitted on the wire
|
|
54
|
+
and retains existing behavior. Unknown values and booleans are rejected.
|
|
55
|
+
|
|
56
|
+
Every animation viewer must independently opt into the same profile using a
|
|
57
|
+
compatible viewer SDK; the publisher's handshake cannot negotiate room viewers.
|
|
58
|
+
|
|
34
59
|
### Pause / resume (egress mode)
|
|
35
60
|
|
|
36
61
|
When the server declares the `playback_control` capability, the current
|
|
@@ -69,6 +94,14 @@ implements the server's WebSocket close-code contract (40xx: don't retry,
|
|
|
69
94
|
|
|
70
95
|
## What's new
|
|
71
96
|
|
|
97
|
+
- 0.3.0: Agora source playback negotiation. `AgoraEgressConfig(source_timeline_only=True)`
|
|
98
|
+
requests source-timeline-only playback; `source_playback_profile=RtcSourcePlaybackProfile.BOUNDED_BURST_V1`
|
|
99
|
+
requests the bounded source playback profile. `start()` refuses the session
|
|
100
|
+
(`UnsupportedConfigurationError`, not retryable) before any audio is sent when the
|
|
101
|
+
server does not confirm the matching capabilities (`agora_source_timeline_only`,
|
|
102
|
+
`agora_source_burst_v1`). Defaults are unchanged.
|
|
103
|
+
- 0.2.3: `app_id` is optional (the API key identifies the app); protobuf floor lowered
|
|
104
|
+
to 5.29 so the SDK installs next to packages that pin protobuf 5.x (TEN Framework agents).
|
|
72
105
|
- `on_playback(PlaybackSignal)` — structured playback lifecycle; no protobuf
|
|
73
106
|
parsing in caller code (`transport_frames(raw, is_last)` still exists).
|
|
74
107
|
- `CloseCode` + `AvatarSDKError.retryable` — the reconnect contract as API.
|
|
@@ -26,12 +26,12 @@ classifiers = [
|
|
|
26
26
|
dependencies = [
|
|
27
27
|
"aiohttp>=3.9",
|
|
28
28
|
"websockets>=12",
|
|
29
|
-
"protobuf>=
|
|
29
|
+
"protobuf>=5.29,<8",
|
|
30
30
|
"nanoid>=2.0",
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
[project.optional-dependencies]
|
|
34
|
-
dev = ["pytest", "pytest-asyncio", "grpcio-tools==1.
|
|
34
|
+
dev = ["pytest", "pytest-asyncio", "grpcio-tools==1.71.2", "ruff"]
|
|
35
35
|
|
|
36
36
|
[project.urls]
|
|
37
37
|
Documentation = "https://docs.spatialreal.ai"
|
|
@@ -24,9 +24,10 @@ from .config import (
|
|
|
24
24
|
AgoraEgressConfig,
|
|
25
25
|
AudioFormat,
|
|
26
26
|
LiveKitEgressConfig,
|
|
27
|
+
RtcSourcePlaybackProfile,
|
|
27
28
|
SessionConfig,
|
|
28
29
|
)
|
|
29
|
-
from .errors import AvatarSDKError, AvatarSDKErrorCode, CloseCode, SessionTokenError
|
|
30
|
+
from .errors import AvatarSDKError, AvatarSDKErrorCode, CloseCode, SessionTokenError, UnsupportedConfigurationError
|
|
30
31
|
from .events import InterruptReason, PlaybackSignal, PlaybackState, PlaybackStateEvent
|
|
31
32
|
from .logid import generate_log_id
|
|
32
33
|
from .session import AvatarSession, new_avatar_session
|
|
@@ -40,12 +41,14 @@ __all__ = [
|
|
|
40
41
|
"AvatarSession",
|
|
41
42
|
"CloseCode",
|
|
42
43
|
"LiveKitEgressConfig",
|
|
44
|
+
"RtcSourcePlaybackProfile",
|
|
43
45
|
"PlaybackSignal",
|
|
44
46
|
"PlaybackStateEvent",
|
|
45
47
|
"PlaybackState",
|
|
46
48
|
"InterruptReason",
|
|
47
49
|
"SessionConfig",
|
|
48
50
|
"SessionTokenError",
|
|
51
|
+
"UnsupportedConfigurationError",
|
|
49
52
|
"__version__",
|
|
50
53
|
"generate_log_id",
|
|
51
54
|
"new_avatar_session",
|
|
@@ -5,10 +5,18 @@ from __future__ import annotations
|
|
|
5
5
|
from collections.abc import Callable
|
|
6
6
|
from dataclasses import dataclass, field
|
|
7
7
|
from datetime import datetime
|
|
8
|
-
from enum import Enum
|
|
8
|
+
from enum import Enum, IntEnum
|
|
9
9
|
|
|
10
10
|
from .environments import DEFAULT_ENVIRONMENT
|
|
11
11
|
from .events import PlaybackSignal, PlaybackStateEvent
|
|
12
|
+
from .proto.generated import message_pb2
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class RtcSourcePlaybackProfile(IntEnum):
|
|
16
|
+
"""Explicit source playback contract; independent RTC viewers must also opt in."""
|
|
17
|
+
|
|
18
|
+
UNSPECIFIED = message_pb2.RTC_SOURCE_PLAYBACK_PROFILE_UNSPECIFIED
|
|
19
|
+
BOUNDED_BURST_V1 = message_pb2.RTC_SOURCE_PLAYBACK_PROFILE_BOUNDED_BURST_V1
|
|
12
20
|
|
|
13
21
|
|
|
14
22
|
class AudioFormat(str, Enum):
|
|
@@ -52,6 +60,22 @@ class AgoraEgressConfig:
|
|
|
52
60
|
token: str = field(default="", repr=False)
|
|
53
61
|
uid: int = 0
|
|
54
62
|
publisher_id: str = ""
|
|
63
|
+
# Only for viewers that play source-timeline audio and manage entry locally.
|
|
64
|
+
# The server must explicitly acknowledge this mode during the handshake.
|
|
65
|
+
source_timeline_only: bool = False
|
|
66
|
+
source_playback_profile: RtcSourcePlaybackProfile = RtcSourcePlaybackProfile.UNSPECIFIED
|
|
67
|
+
|
|
68
|
+
def __post_init__(self) -> None:
|
|
69
|
+
if not isinstance(self.source_timeline_only, bool):
|
|
70
|
+
raise ValueError("source_timeline_only must be a boolean")
|
|
71
|
+
if isinstance(self.source_playback_profile, bool) or not isinstance(self.source_playback_profile, int):
|
|
72
|
+
raise ValueError("source_playback_profile must be a known RtcSourcePlaybackProfile")
|
|
73
|
+
try:
|
|
74
|
+
self.source_playback_profile = RtcSourcePlaybackProfile(self.source_playback_profile)
|
|
75
|
+
except ValueError as exc:
|
|
76
|
+
raise ValueError("source_playback_profile must be a known RtcSourcePlaybackProfile") from exc
|
|
77
|
+
if self.source_playback_profile and not self.source_timeline_only:
|
|
78
|
+
raise ValueError("source_playback_profile requires source_timeline_only=True")
|
|
55
79
|
|
|
56
80
|
|
|
57
81
|
@dataclass
|
|
@@ -12,6 +12,8 @@ from __future__ import annotations
|
|
|
12
12
|
|
|
13
13
|
from enum import Enum, IntEnum
|
|
14
14
|
|
|
15
|
+
from websockets.frames import CloseCode as WebSocketCloseCode
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
class AvatarSDKErrorCode(str, Enum):
|
|
17
19
|
"""Stable, log-friendly error codes surfaced by the SDK."""
|
|
@@ -117,6 +119,8 @@ class AvatarSDKError(Exception):
|
|
|
117
119
|
)
|
|
118
120
|
if self.close_code in _RETRYABLE_CLOSE_CODES:
|
|
119
121
|
return True
|
|
122
|
+
if self.close_code == WebSocketCloseCode.POLICY_VIOLATION:
|
|
123
|
+
return False
|
|
120
124
|
if 4000 <= self.close_code < 4500:
|
|
121
125
|
return False
|
|
122
126
|
return True
|
|
@@ -125,6 +129,22 @@ class AvatarSDKError(Exception):
|
|
|
125
129
|
return f"{self.code.value}: {self.message}"
|
|
126
130
|
|
|
127
131
|
|
|
132
|
+
class UnsupportedConfigurationError(AvatarSDKError):
|
|
133
|
+
"""The server confirmed a session without accepting a required mode.
|
|
134
|
+
|
|
135
|
+
This is a local handshake classification, not a new wire error code.
|
|
136
|
+
Retrying the same configuration cannot negotiate the missing capability.
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
def __init__(self, message: str, *, connection_id: str | None = None):
|
|
140
|
+
super().__init__(
|
|
141
|
+
code=AvatarSDKErrorCode.protocolError,
|
|
142
|
+
message=message,
|
|
143
|
+
phase="websocket_handshake",
|
|
144
|
+
connection_id=connection_id,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
128
148
|
class SessionTokenError(AvatarSDKError):
|
|
129
149
|
"""Raised when the session-token exchange with the console API fails."""
|
|
130
150
|
|
|
@@ -0,0 +1,74 @@
|
|
|
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: 5.29.0
|
|
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
|
+
5,
|
|
15
|
+
29,
|
|
16
|
+
0,
|
|
17
|
+
'',
|
|
18
|
+
'driveningress/v2/driveningress.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$driveningress/v2/driveningress.proto\x12\x10\x64riveningress.v2\"\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\"\xc6\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\x12\x1c\n\x14source_timeline_only\x18\x06 \x01(\x08\x12K\n\x17source_playback_profile\x18\x07 \x01(\x0e\x32*.driveningress.v2.RtcSourcePlaybackProfile\"\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\"s\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\x11\n\tanimation\x18\x04 \x01(\x0c\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\"\x9c\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\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\x61taJ\x04\x08\x07\x10\x08*\xcd\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\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\"\x04\x08\x06\x10\x06*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*y\n\x18RtcSourcePlaybackProfile\x12+\n\'RTC_SOURCE_PLAYBACK_PROFILE_UNSPECIFIED\x10\x00\x12\x30\n,RTC_SOURCE_PLAYBACK_PROFILE_BOUNDED_BURST_V1\x10\x01\x62\x06proto3')
|
|
28
|
+
|
|
29
|
+
_globals = globals()
|
|
30
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'driveningress.v2.driveningress_pb2', _globals)
|
|
32
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
|
+
DESCRIPTOR._loaded_options = None
|
|
34
|
+
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._loaded_options = None
|
|
35
|
+
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._serialized_options = b'8\001'
|
|
36
|
+
_globals['_MESSAGETYPE']._serialized_start=2267
|
|
37
|
+
_globals['_MESSAGETYPE']._serialized_end=2600
|
|
38
|
+
_globals['_AUDIOFORMAT']._serialized_start=2602
|
|
39
|
+
_globals['_AUDIOFORMAT']._serialized_end=2670
|
|
40
|
+
_globals['_TRANSPORTCOMPRESSION']._serialized_start=2672
|
|
41
|
+
_globals['_TRANSPORTCOMPRESSION']._serialized_end=2726
|
|
42
|
+
_globals['_EGRESSTYPE']._serialized_start=2728
|
|
43
|
+
_globals['_EGRESSTYPE']._serialized_end=2817
|
|
44
|
+
_globals['_RTCSOURCEPLAYBACKPROFILE']._serialized_start=2819
|
|
45
|
+
_globals['_RTCSOURCEPLAYBACKPROFILE']._serialized_end=2940
|
|
46
|
+
_globals['_LIVEKITEGRESSCONFIG']._serialized_start=59
|
|
47
|
+
_globals['_LIVEKITEGRESSCONFIG']._serialized_end=354
|
|
48
|
+
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._serialized_start=300
|
|
49
|
+
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._serialized_end=354
|
|
50
|
+
_globals['_AGORAEGRESSCONFIG']._serialized_start=357
|
|
51
|
+
_globals['_AGORAEGRESSCONFIG']._serialized_end=555
|
|
52
|
+
_globals['_CLIENTCONFIGURESESSION']._serialized_start=558
|
|
53
|
+
_globals['_CLIENTCONFIGURESESSION']._serialized_end=917
|
|
54
|
+
_globals['_SERVERCONFIRMSESSION']._serialized_start=919
|
|
55
|
+
_globals['_SERVERCONFIRMSESSION']._serialized_end=986
|
|
56
|
+
_globals['_CLIENTAUDIOINPUT']._serialized_start=988
|
|
57
|
+
_globals['_CLIENTAUDIOINPUT']._serialized_end=1050
|
|
58
|
+
_globals['_SERVERERROR']._serialized_start=1052
|
|
59
|
+
_globals['_SERVERERROR']._serialized_end=1135
|
|
60
|
+
_globals['_SERVERRESPONSEANIMATION']._serialized_start=1137
|
|
61
|
+
_globals['_SERVERRESPONSEANIMATION']._serialized_end=1252
|
|
62
|
+
_globals['_CLIENTINTERRUPT']._serialized_start=1254
|
|
63
|
+
_globals['_CLIENTINTERRUPT']._serialized_end=1287
|
|
64
|
+
_globals['_CLIENTPAUSE']._serialized_start=1289
|
|
65
|
+
_globals['_CLIENTPAUSE']._serialized_end=1318
|
|
66
|
+
_globals['_CLIENTRESUME']._serialized_start=1320
|
|
67
|
+
_globals['_CLIENTRESUME']._serialized_end=1350
|
|
68
|
+
_globals['_SERVERPLAYBACKSTATE']._serialized_start=1353
|
|
69
|
+
_globals['_SERVERPLAYBACKSTATE']._serialized_end=1593
|
|
70
|
+
_globals['_SERVERPLAYBACKSTATE_STATE']._serialized_start=1510
|
|
71
|
+
_globals['_SERVERPLAYBACKSTATE_STATE']._serialized_end=1593
|
|
72
|
+
_globals['_MESSAGE']._serialized_start=1596
|
|
73
|
+
_globals['_MESSAGE']._serialized_end=2264
|
|
74
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -2,8 +2,7 @@ from google.protobuf.internal import containers as _containers
|
|
|
2
2
|
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
|
3
3
|
from google.protobuf import descriptor as _descriptor
|
|
4
4
|
from google.protobuf import message as _message
|
|
5
|
-
from
|
|
6
|
-
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
|
5
|
+
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
|
7
6
|
|
|
8
7
|
DESCRIPTOR: _descriptor.FileDescriptor
|
|
9
8
|
|
|
@@ -34,6 +33,11 @@ class EgressType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
|
34
33
|
EGRESS_TYPE_UNSPECIFIED: _ClassVar[EgressType]
|
|
35
34
|
EGRESS_TYPE_LIVEKIT: _ClassVar[EgressType]
|
|
36
35
|
EGRESS_TYPE_AGORA: _ClassVar[EgressType]
|
|
36
|
+
|
|
37
|
+
class RtcSourcePlaybackProfile(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
38
|
+
__slots__ = ()
|
|
39
|
+
RTC_SOURCE_PLAYBACK_PROFILE_UNSPECIFIED: _ClassVar[RtcSourcePlaybackProfile]
|
|
40
|
+
RTC_SOURCE_PLAYBACK_PROFILE_BOUNDED_BURST_V1: _ClassVar[RtcSourcePlaybackProfile]
|
|
37
41
|
MESSAGE_UNSPECIFIED: MessageType
|
|
38
42
|
MESSAGE_CLIENT_CONFIGURE_SESSION: MessageType
|
|
39
43
|
MESSAGE_SERVER_CONFIRM_SESSION: MessageType
|
|
@@ -50,6 +54,8 @@ TRANSPORT_COMPRESSION_NONE: TransportCompression
|
|
|
50
54
|
EGRESS_TYPE_UNSPECIFIED: EgressType
|
|
51
55
|
EGRESS_TYPE_LIVEKIT: EgressType
|
|
52
56
|
EGRESS_TYPE_AGORA: EgressType
|
|
57
|
+
RTC_SOURCE_PLAYBACK_PROFILE_UNSPECIFIED: RtcSourcePlaybackProfile
|
|
58
|
+
RTC_SOURCE_PLAYBACK_PROFILE_BOUNDED_BURST_V1: RtcSourcePlaybackProfile
|
|
53
59
|
|
|
54
60
|
class LiveKitEgressConfig(_message.Message):
|
|
55
61
|
__slots__ = ("url", "api_key", "api_secret", "room_name", "publisher_id", "extra_attributes", "idle_timeout", "api_token")
|
|
@@ -79,16 +85,20 @@ class LiveKitEgressConfig(_message.Message):
|
|
|
79
85
|
def __init__(self, url: _Optional[str] = ..., api_key: _Optional[str] = ..., api_secret: _Optional[str] = ..., room_name: _Optional[str] = ..., publisher_id: _Optional[str] = ..., extra_attributes: _Optional[_Mapping[str, str]] = ..., idle_timeout: _Optional[int] = ..., api_token: _Optional[str] = ...) -> None: ...
|
|
80
86
|
|
|
81
87
|
class AgoraEgressConfig(_message.Message):
|
|
82
|
-
__slots__ = ("channel_name", "token", "uid", "publisher_id")
|
|
88
|
+
__slots__ = ("channel_name", "token", "uid", "publisher_id", "source_timeline_only", "source_playback_profile")
|
|
83
89
|
CHANNEL_NAME_FIELD_NUMBER: _ClassVar[int]
|
|
84
90
|
TOKEN_FIELD_NUMBER: _ClassVar[int]
|
|
85
91
|
UID_FIELD_NUMBER: _ClassVar[int]
|
|
86
92
|
PUBLISHER_ID_FIELD_NUMBER: _ClassVar[int]
|
|
93
|
+
SOURCE_TIMELINE_ONLY_FIELD_NUMBER: _ClassVar[int]
|
|
94
|
+
SOURCE_PLAYBACK_PROFILE_FIELD_NUMBER: _ClassVar[int]
|
|
87
95
|
channel_name: str
|
|
88
96
|
token: str
|
|
89
97
|
uid: int
|
|
90
98
|
publisher_id: str
|
|
91
|
-
|
|
99
|
+
source_timeline_only: bool
|
|
100
|
+
source_playback_profile: RtcSourcePlaybackProfile
|
|
101
|
+
def __init__(self, channel_name: _Optional[str] = ..., token: _Optional[str] = ..., uid: _Optional[int] = ..., publisher_id: _Optional[str] = ..., source_timeline_only: bool = ..., source_playback_profile: _Optional[_Union[RtcSourcePlaybackProfile, str]] = ...) -> None: ...
|
|
92
102
|
|
|
93
103
|
class ClientConfigureSession(_message.Message):
|
|
94
104
|
__slots__ = ("sample_rate", "bitrate", "audio_format", "transport_compression", "egress_type", "livekit_egress", "agora_egress")
|
|
@@ -27,6 +27,7 @@ from .errors import (
|
|
|
27
27
|
AvatarSDKError,
|
|
28
28
|
AvatarSDKErrorCode,
|
|
29
29
|
SessionTokenError,
|
|
30
|
+
UnsupportedConfigurationError,
|
|
30
31
|
error_code_for_close_code,
|
|
31
32
|
)
|
|
32
33
|
from .events import PlaybackSignal, PlaybackState, PlaybackStateEvent
|
|
@@ -40,6 +41,11 @@ SESSION_TOKEN_PATH = "/v1/auth/session-token"
|
|
|
40
41
|
LEGACY_CONSOLE_SUFFIX = "/v1/console"
|
|
41
42
|
DRIVENINGRESS_PATH = "/v2/driveningress"
|
|
42
43
|
INGRESS_WEBSOCKET_PATH = "/websocket"
|
|
44
|
+
# A configuration rejection may carry an unclassified ServerError followed by
|
|
45
|
+
# the authoritative standard close. Bound the wait; no close retains the error.
|
|
46
|
+
CONFIGURE_CLOSE_GRACE_SECONDS = 1.0
|
|
47
|
+
_SOURCE_TIMELINE_CAPABILITY = "agora_source_timeline_only"
|
|
48
|
+
_SOURCE_BURST_CAPABILITY = "agora_source_burst_v1"
|
|
43
49
|
|
|
44
50
|
logger = logging.getLogger(__name__)
|
|
45
51
|
|
|
@@ -155,8 +161,6 @@ class AvatarSession:
|
|
|
155
161
|
raise ValueError("Session not initialized (call init() first)")
|
|
156
162
|
if not self._config.avatar_id:
|
|
157
163
|
raise ValueError("Missing avatar ID")
|
|
158
|
-
if not self._config.app_id:
|
|
159
|
-
raise ValueError("Missing app ID")
|
|
160
164
|
if self._config.livekit_egress is not None and self._config.agora_egress is not None:
|
|
161
165
|
raise ValueError("Cannot configure both livekit_egress and agora_egress")
|
|
162
166
|
|
|
@@ -192,12 +196,17 @@ class AvatarSession:
|
|
|
192
196
|
|
|
193
197
|
query = parse_qs(parsed.query)
|
|
194
198
|
query["id"] = [self._config.avatar_id]
|
|
199
|
+
# The app is derived server-side from the API key; ``app_id`` is optional and only
|
|
200
|
+
# forwarded when set (the server ignores an absent X-App-ID / appId).
|
|
195
201
|
headers: dict[str, str] = {}
|
|
196
202
|
if self._config.use_query_auth:
|
|
197
|
-
|
|
203
|
+
if self._config.app_id:
|
|
204
|
+
query["appId"] = [self._config.app_id]
|
|
198
205
|
query["sessionKey"] = [self._session_token or ""]
|
|
199
206
|
else:
|
|
200
|
-
headers = {"X-
|
|
207
|
+
headers = {"X-Session-Key": self._session_token or ""}
|
|
208
|
+
if self._config.app_id:
|
|
209
|
+
headers["X-App-ID"] = self._config.app_id
|
|
201
210
|
|
|
202
211
|
return (
|
|
203
212
|
urlunparse((ws_scheme, parsed.netloc, parsed.path, parsed.params, urlencode(query, doseq=True), "")),
|
|
@@ -237,6 +246,8 @@ class AvatarSession:
|
|
|
237
246
|
s.agora_egress.token = ag.token
|
|
238
247
|
s.agora_egress.uid = ag.uid
|
|
239
248
|
s.agora_egress.publisher_id = ag.publisher_id
|
|
249
|
+
s.agora_egress.source_timeline_only = ag.source_timeline_only
|
|
250
|
+
s.agora_egress.source_playback_profile = ag.source_playback_profile
|
|
240
251
|
|
|
241
252
|
try:
|
|
242
253
|
await self._connection.send(msg.SerializeToString())
|
|
@@ -277,10 +288,40 @@ class AvatarSession:
|
|
|
277
288
|
# Forward-compatible: the field lands with server-side playback
|
|
278
289
|
# control; older protos simply don't have it.
|
|
279
290
|
self._capabilities = tuple(getattr(confirm, "capabilities", ()) or ())
|
|
291
|
+
if (
|
|
292
|
+
self._config.agora_egress is not None
|
|
293
|
+
and self._config.agora_egress.source_timeline_only
|
|
294
|
+
and _SOURCE_TIMELINE_CAPABILITY not in self._capabilities
|
|
295
|
+
):
|
|
296
|
+
raise UnsupportedConfigurationError(
|
|
297
|
+
"Server did not accept the requested Agora source-timeline-only mode",
|
|
298
|
+
connection_id=confirm.connection_id,
|
|
299
|
+
)
|
|
300
|
+
if (
|
|
301
|
+
self._config.agora_egress is not None
|
|
302
|
+
and self._config.agora_egress.source_playback_profile
|
|
303
|
+
and _SOURCE_BURST_CAPABILITY not in self._capabilities
|
|
304
|
+
):
|
|
305
|
+
raise UnsupportedConfigurationError(
|
|
306
|
+
"Server did not accept the requested Agora source playback profile",
|
|
307
|
+
connection_id=confirm.connection_id,
|
|
308
|
+
)
|
|
280
309
|
return confirm.connection_id
|
|
281
310
|
|
|
282
311
|
if envelope.type == message_pb2.MESSAGE_SERVER_ERROR:
|
|
283
|
-
|
|
312
|
+
error = _server_error(envelope.server_error, phase="websocket_handshake")
|
|
313
|
+
if (
|
|
314
|
+
self._config.agora_egress is not None
|
|
315
|
+
and self._config.agora_egress.source_timeline_only
|
|
316
|
+
and error.close_code is None
|
|
317
|
+
):
|
|
318
|
+
try:
|
|
319
|
+
await asyncio.wait_for(self._connection.wait_closed(), timeout=CONFIGURE_CLOSE_GRACE_SECONDS)
|
|
320
|
+
except asyncio.TimeoutError:
|
|
321
|
+
pass
|
|
322
|
+
else:
|
|
323
|
+
error.close_code = self._connection.close_code
|
|
324
|
+
raise error
|
|
284
325
|
|
|
285
326
|
raise AvatarSDKError(
|
|
286
327
|
code=AvatarSDKErrorCode.protocolError,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.0"
|
|
@@ -1,72 +0,0 @@
|
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$driveningress/v2/driveningress.proto\x12\x10\x64riveningress.v2\"\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\"\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\"s\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\x11\n\tanimation\x18\x04 \x01(\x0c\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\"\x9c\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\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\x61taJ\x04\x08\x07\x10\x08*\xcd\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\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\"\x04\x08\x06\x10\x06*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\x62\x06proto3')
|
|
28
|
-
|
|
29
|
-
_globals = globals()
|
|
30
|
-
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
31
|
-
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'driveningress.v2.driveningress_pb2', _globals)
|
|
32
|
-
if not _descriptor._USE_C_DESCRIPTORS:
|
|
33
|
-
DESCRIPTOR._loaded_options = None
|
|
34
|
-
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._loaded_options = None
|
|
35
|
-
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._serialized_options = b'8\001'
|
|
36
|
-
_globals['_MESSAGETYPE']._serialized_start=2159
|
|
37
|
-
_globals['_MESSAGETYPE']._serialized_end=2492
|
|
38
|
-
_globals['_AUDIOFORMAT']._serialized_start=2494
|
|
39
|
-
_globals['_AUDIOFORMAT']._serialized_end=2562
|
|
40
|
-
_globals['_TRANSPORTCOMPRESSION']._serialized_start=2564
|
|
41
|
-
_globals['_TRANSPORTCOMPRESSION']._serialized_end=2618
|
|
42
|
-
_globals['_EGRESSTYPE']._serialized_start=2620
|
|
43
|
-
_globals['_EGRESSTYPE']._serialized_end=2709
|
|
44
|
-
_globals['_LIVEKITEGRESSCONFIG']._serialized_start=59
|
|
45
|
-
_globals['_LIVEKITEGRESSCONFIG']._serialized_end=354
|
|
46
|
-
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._serialized_start=300
|
|
47
|
-
_globals['_LIVEKITEGRESSCONFIG_EXTRAATTRIBUTESENTRY']._serialized_end=354
|
|
48
|
-
_globals['_AGORAEGRESSCONFIG']._serialized_start=356
|
|
49
|
-
_globals['_AGORAEGRESSCONFIG']._serialized_end=447
|
|
50
|
-
_globals['_CLIENTCONFIGURESESSION']._serialized_start=450
|
|
51
|
-
_globals['_CLIENTCONFIGURESESSION']._serialized_end=809
|
|
52
|
-
_globals['_SERVERCONFIRMSESSION']._serialized_start=811
|
|
53
|
-
_globals['_SERVERCONFIRMSESSION']._serialized_end=878
|
|
54
|
-
_globals['_CLIENTAUDIOINPUT']._serialized_start=880
|
|
55
|
-
_globals['_CLIENTAUDIOINPUT']._serialized_end=942
|
|
56
|
-
_globals['_SERVERERROR']._serialized_start=944
|
|
57
|
-
_globals['_SERVERERROR']._serialized_end=1027
|
|
58
|
-
_globals['_SERVERRESPONSEANIMATION']._serialized_start=1029
|
|
59
|
-
_globals['_SERVERRESPONSEANIMATION']._serialized_end=1144
|
|
60
|
-
_globals['_CLIENTINTERRUPT']._serialized_start=1146
|
|
61
|
-
_globals['_CLIENTINTERRUPT']._serialized_end=1179
|
|
62
|
-
_globals['_CLIENTPAUSE']._serialized_start=1181
|
|
63
|
-
_globals['_CLIENTPAUSE']._serialized_end=1210
|
|
64
|
-
_globals['_CLIENTRESUME']._serialized_start=1212
|
|
65
|
-
_globals['_CLIENTRESUME']._serialized_end=1242
|
|
66
|
-
_globals['_SERVERPLAYBACKSTATE']._serialized_start=1245
|
|
67
|
-
_globals['_SERVERPLAYBACKSTATE']._serialized_end=1485
|
|
68
|
-
_globals['_SERVERPLAYBACKSTATE_STATE']._serialized_start=1402
|
|
69
|
-
_globals['_SERVERPLAYBACKSTATE_STATE']._serialized_end=1485
|
|
70
|
-
_globals['_MESSAGE']._serialized_start=1488
|
|
71
|
-
_globals['_MESSAGE']._serialized_end=2156
|
|
72
|
-
# @@protoc_insertion_point(module_scope)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|