spatialreal 0.2.3__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.3 → spatialreal-0.3.0}/PKG-INFO +32 -1
- {spatialreal-0.2.3 → spatialreal-0.3.0}/README.md +31 -0
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/__init__.py +4 -1
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/config.py +25 -1
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/errors.py +20 -0
- spatialreal-0.3.0/spatialreal/proto/generated/message_pb2.py +74 -0
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/proto/generated/message_pb2.pyi +13 -2
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/session.py +39 -1
- spatialreal-0.3.0/spatialreal/version.py +1 -0
- spatialreal-0.2.3/spatialreal/proto/generated/message_pb2.py +0 -72
- spatialreal-0.2.3/spatialreal/version.py +0 -1
- {spatialreal-0.2.3 → spatialreal-0.3.0}/.gitignore +0 -0
- {spatialreal-0.2.3 → spatialreal-0.3.0}/LICENSE +0 -0
- {spatialreal-0.2.3 → spatialreal-0.3.0}/pyproject.toml +0 -0
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/environments.py +0 -0
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/events.py +0 -0
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/logid.py +0 -0
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/proto/__init__.py +0 -0
- {spatialreal-0.2.3 → spatialreal-0.3.0}/spatialreal/proto/generated/__init__.py +0 -0
- {spatialreal-0.2.3 → 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/
|
|
@@ -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,12 @@ 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.
|
|
105
136
|
- 0.2.3: `app_id` is optional (the API key identifies the app); protobuf floor lowered
|
|
106
137
|
to 5.29 so the SDK installs next to packages that pin protobuf 5.x (TEN Framework agents).
|
|
107
138
|
- `on_playback(PlaybackSignal)` — structured playback lifecycle; no protobuf
|
|
@@ -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,12 @@ 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.
|
|
72
103
|
- 0.2.3: `app_id` is optional (the API key identifies the app); protobuf floor lowered
|
|
73
104
|
to 5.29 so the SDK installs next to packages that pin protobuf 5.x (TEN Framework agents).
|
|
74
105
|
- `on_playback(PlaybackSignal)` — structured playback lifecycle; no protobuf
|
|
@@ -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)
|
|
@@ -33,6 +33,11 @@ class EgressType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
|
|
33
33
|
EGRESS_TYPE_UNSPECIFIED: _ClassVar[EgressType]
|
|
34
34
|
EGRESS_TYPE_LIVEKIT: _ClassVar[EgressType]
|
|
35
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]
|
|
36
41
|
MESSAGE_UNSPECIFIED: MessageType
|
|
37
42
|
MESSAGE_CLIENT_CONFIGURE_SESSION: MessageType
|
|
38
43
|
MESSAGE_SERVER_CONFIRM_SESSION: MessageType
|
|
@@ -49,6 +54,8 @@ TRANSPORT_COMPRESSION_NONE: TransportCompression
|
|
|
49
54
|
EGRESS_TYPE_UNSPECIFIED: EgressType
|
|
50
55
|
EGRESS_TYPE_LIVEKIT: EgressType
|
|
51
56
|
EGRESS_TYPE_AGORA: EgressType
|
|
57
|
+
RTC_SOURCE_PLAYBACK_PROFILE_UNSPECIFIED: RtcSourcePlaybackProfile
|
|
58
|
+
RTC_SOURCE_PLAYBACK_PROFILE_BOUNDED_BURST_V1: RtcSourcePlaybackProfile
|
|
52
59
|
|
|
53
60
|
class LiveKitEgressConfig(_message.Message):
|
|
54
61
|
__slots__ = ("url", "api_key", "api_secret", "room_name", "publisher_id", "extra_attributes", "idle_timeout", "api_token")
|
|
@@ -78,16 +85,20 @@ class LiveKitEgressConfig(_message.Message):
|
|
|
78
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: ...
|
|
79
86
|
|
|
80
87
|
class AgoraEgressConfig(_message.Message):
|
|
81
|
-
__slots__ = ("channel_name", "token", "uid", "publisher_id")
|
|
88
|
+
__slots__ = ("channel_name", "token", "uid", "publisher_id", "source_timeline_only", "source_playback_profile")
|
|
82
89
|
CHANNEL_NAME_FIELD_NUMBER: _ClassVar[int]
|
|
83
90
|
TOKEN_FIELD_NUMBER: _ClassVar[int]
|
|
84
91
|
UID_FIELD_NUMBER: _ClassVar[int]
|
|
85
92
|
PUBLISHER_ID_FIELD_NUMBER: _ClassVar[int]
|
|
93
|
+
SOURCE_TIMELINE_ONLY_FIELD_NUMBER: _ClassVar[int]
|
|
94
|
+
SOURCE_PLAYBACK_PROFILE_FIELD_NUMBER: _ClassVar[int]
|
|
86
95
|
channel_name: str
|
|
87
96
|
token: str
|
|
88
97
|
uid: int
|
|
89
98
|
publisher_id: str
|
|
90
|
-
|
|
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: ...
|
|
91
102
|
|
|
92
103
|
class ClientConfigureSession(_message.Message):
|
|
93
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
|
|
|
@@ -240,6 +246,8 @@ class AvatarSession:
|
|
|
240
246
|
s.agora_egress.token = ag.token
|
|
241
247
|
s.agora_egress.uid = ag.uid
|
|
242
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
|
|
243
251
|
|
|
244
252
|
try:
|
|
245
253
|
await self._connection.send(msg.SerializeToString())
|
|
@@ -280,10 +288,40 @@ class AvatarSession:
|
|
|
280
288
|
# Forward-compatible: the field lands with server-side playback
|
|
281
289
|
# control; older protos simply don't have it.
|
|
282
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
|
+
)
|
|
283
309
|
return confirm.connection_id
|
|
284
310
|
|
|
285
311
|
if envelope.type == message_pb2.MESSAGE_SERVER_ERROR:
|
|
286
|
-
|
|
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
|
|
287
325
|
|
|
288
326
|
raise AvatarSDKError(
|
|
289
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: 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\"[\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.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|