camera-ui-common 1.0.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.
- camera_ui_common-1.0.0/LICENSE.txt +22 -0
- camera_ui_common-1.0.0/PKG-INFO +196 -0
- camera_ui_common-1.0.0/README.md +169 -0
- camera_ui_common-1.0.0/camera_ui_common/__init__.py +28 -0
- camera_ui_common-1.0.0/camera_ui_common/camera_utils/__init__.py +5 -0
- camera_ui_common-1.0.0/camera_ui_common/camera_utils/utils.py +75 -0
- camera_ui_common-1.0.0/camera_ui_common/common_utils/__init__.py +22 -0
- camera_ui_common-1.0.0/camera_ui_common/common_utils/object_path.py +211 -0
- camera_ui_common-1.0.0/camera_ui_common/common_utils/promise.py +41 -0
- camera_ui_common-1.0.0/camera_ui_common/common_utils/reactive.py +47 -0
- camera_ui_common-1.0.0/camera_ui_common/common_utils/signal_handler.py +100 -0
- camera_ui_common-1.0.0/camera_ui_common/common_utils/subscribed.py +34 -0
- camera_ui_common-1.0.0/camera_ui_common/common_utils/task.py +45 -0
- camera_ui_common-1.0.0/camera_ui_common/common_utils/thread.py +18 -0
- camera_ui_common-1.0.0/camera_ui_common/common_utils/utils.py +99 -0
- camera_ui_common-1.0.0/camera_ui_common/logger_service/__init__.py +0 -0
- camera_ui_common-1.0.0/camera_ui_common/logger_service/ansicolor.py +62 -0
- camera_ui_common-1.0.0/camera_ui_common/logger_service/logger.py +316 -0
- camera_ui_common-1.0.0/camera_ui_common/py.typed +0 -0
- camera_ui_common-1.0.0/camera_ui_common.egg-info/PKG-INFO +196 -0
- camera_ui_common-1.0.0/camera_ui_common.egg-info/SOURCES.txt +24 -0
- camera_ui_common-1.0.0/camera_ui_common.egg-info/dependency_links.txt +1 -0
- camera_ui_common-1.0.0/camera_ui_common.egg-info/requires.txt +3 -0
- camera_ui_common-1.0.0/camera_ui_common.egg-info/top_level.txt +1 -0
- camera_ui_common-1.0.0/pyproject.toml +38 -0
- camera_ui_common-1.0.0/setup.cfg +4 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020-2024 seydx <dev@seydx.com>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: camera-ui-common
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: camera.ui python utilities
|
|
5
|
+
Author-email: seydx <dev@seydx.com>
|
|
6
|
+
Maintainer-email: seydx <dev@seydx.com>
|
|
7
|
+
Project-URL: Homepage, https://github.com/seydx/camera.ui
|
|
8
|
+
Project-URL: Documentation, https://github.com/seydx/camera.ui
|
|
9
|
+
Project-URL: Repository, https://github.com/seydx/camera.ui
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/seydx/camera.ui/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/seydx/camera.ui/blob/master/CHANGELOG.md
|
|
12
|
+
Keywords: camera.ui,python,utilities
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE.txt
|
|
23
|
+
Requires-Dist: typing_extensions>=4.12.2
|
|
24
|
+
Requires-Dist: reactivex>=4.0.4
|
|
25
|
+
Requires-Dist: camera-ui-sdk>=1.0.0
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# camera-ui-python-common
|
|
29
|
+
|
|
30
|
+
Shared utilities for Python-based camera.ui plugins including logging, reactive programming, and common helpers.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install camera-ui-python-common
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Core Features
|
|
39
|
+
|
|
40
|
+
- **Logging** - Colored, structured logging
|
|
41
|
+
- **Reactive Programming** - Observable properties
|
|
42
|
+
- **Signal Handling** - Graceful shutdown
|
|
43
|
+
- **Object Utilities** - Deep object manipulation
|
|
44
|
+
- **Async Helpers** - Task and thread management
|
|
45
|
+
|
|
46
|
+
## Logging
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from camera_ui_python_common import LoggerService
|
|
50
|
+
|
|
51
|
+
logger = LoggerService({
|
|
52
|
+
"prefix": "MyPlugin",
|
|
53
|
+
"debug_enabled": True
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
logger.log("Plugin started")
|
|
57
|
+
logger.error("Something went wrong")
|
|
58
|
+
logger.success("Operation completed")
|
|
59
|
+
logger.debug("Debug information")
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Reactive Programming
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from camera_ui_python_common import ReactiveProperty
|
|
66
|
+
|
|
67
|
+
# Create reactive state
|
|
68
|
+
state = ReactiveProperty({"count": 0, "active": True})
|
|
69
|
+
|
|
70
|
+
# Subscribe to changes
|
|
71
|
+
state.observable.subscribe(lambda value: print(f"State: {value}"))
|
|
72
|
+
|
|
73
|
+
# Update state
|
|
74
|
+
state.next({"count": 1, "active": True})
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Signal Handling
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from camera_ui_python_common import SignalHandler
|
|
81
|
+
|
|
82
|
+
async def cleanup():
|
|
83
|
+
print("Cleaning up...")
|
|
84
|
+
|
|
85
|
+
signal_handler = SignalHandler({
|
|
86
|
+
"display_name": "MyPlugin",
|
|
87
|
+
"logger": logger,
|
|
88
|
+
"close_function": cleanup
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
signal_handler.setup_handlers()
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Object Path Operations
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from camera_ui_python_common import ObjectPath
|
|
98
|
+
|
|
99
|
+
data = {"camera": {"settings": {"resolution": "1080p"}}}
|
|
100
|
+
|
|
101
|
+
# Get nested values
|
|
102
|
+
resolution = ObjectPath.get(data, "camera.settings.resolution")
|
|
103
|
+
|
|
104
|
+
# Set nested values
|
|
105
|
+
ObjectPath.set(data, "camera.settings.bitrate", 5000)
|
|
106
|
+
|
|
107
|
+
# Check if path exists
|
|
108
|
+
has_setting = ObjectPath.has(data, "camera.settings.fps")
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Async Utilities
|
|
112
|
+
|
|
113
|
+
### Task Management
|
|
114
|
+
```python
|
|
115
|
+
from camera_ui_python_common import TaskSet
|
|
116
|
+
|
|
117
|
+
tasks = TaskSet("MyTasks")
|
|
118
|
+
tasks.add(my_async_function())
|
|
119
|
+
await tasks
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Thread Operations
|
|
123
|
+
```python
|
|
124
|
+
from camera_ui_python_common import to_thread
|
|
125
|
+
|
|
126
|
+
# Run blocking operation in thread
|
|
127
|
+
result = await to_thread(blocking_function)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Sync/Async Bridge
|
|
131
|
+
```python
|
|
132
|
+
from camera_ui_python_common import make_sync
|
|
133
|
+
|
|
134
|
+
# Convert async function to sync
|
|
135
|
+
sync_version = make_sync(async_function)
|
|
136
|
+
result = sync_version(args)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## RTSP Utilities
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from camera_ui_python_common import build_target_url
|
|
143
|
+
|
|
144
|
+
url = build_target_url("rtsp://camera.local/stream", {
|
|
145
|
+
"video": True,
|
|
146
|
+
"audio": ["pcma", "opus"],
|
|
147
|
+
"timeout": 30
|
|
148
|
+
})
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Complete Example
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
import asyncio
|
|
155
|
+
from camera_ui_python_common import LoggerService, ReactiveProperty, SignalHandler
|
|
156
|
+
|
|
157
|
+
class MyPlugin:
|
|
158
|
+
def __init__(self):
|
|
159
|
+
self.logger = LoggerService({"prefix": "MyPlugin"})
|
|
160
|
+
self.state = ReactiveProperty({"active": False})
|
|
161
|
+
|
|
162
|
+
self.signal_handler = SignalHandler({
|
|
163
|
+
"display_name": "MyPlugin",
|
|
164
|
+
"logger": self.logger,
|
|
165
|
+
"close_function": self.cleanup
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
async def start(self):
|
|
169
|
+
self.logger.log("Starting plugin...")
|
|
170
|
+
self.signal_handler.setup_handlers()
|
|
171
|
+
|
|
172
|
+
# Update state
|
|
173
|
+
self.state.next({"active": True})
|
|
174
|
+
|
|
175
|
+
# Keep running
|
|
176
|
+
await asyncio.Future()
|
|
177
|
+
|
|
178
|
+
async def cleanup(self):
|
|
179
|
+
self.logger.log("Stopping plugin...")
|
|
180
|
+
|
|
181
|
+
# Usage
|
|
182
|
+
plugin = MyPlugin()
|
|
183
|
+
asyncio.run(plugin.start())
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Contributing
|
|
187
|
+
|
|
188
|
+
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
MIT
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
*Part of the camera.ui ecosystem - A comprehensive camera management solution.*
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# camera-ui-python-common
|
|
2
|
+
|
|
3
|
+
Shared utilities for Python-based camera.ui plugins including logging, reactive programming, and common helpers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install camera-ui-python-common
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Core Features
|
|
12
|
+
|
|
13
|
+
- **Logging** - Colored, structured logging
|
|
14
|
+
- **Reactive Programming** - Observable properties
|
|
15
|
+
- **Signal Handling** - Graceful shutdown
|
|
16
|
+
- **Object Utilities** - Deep object manipulation
|
|
17
|
+
- **Async Helpers** - Task and thread management
|
|
18
|
+
|
|
19
|
+
## Logging
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from camera_ui_python_common import LoggerService
|
|
23
|
+
|
|
24
|
+
logger = LoggerService({
|
|
25
|
+
"prefix": "MyPlugin",
|
|
26
|
+
"debug_enabled": True
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
logger.log("Plugin started")
|
|
30
|
+
logger.error("Something went wrong")
|
|
31
|
+
logger.success("Operation completed")
|
|
32
|
+
logger.debug("Debug information")
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Reactive Programming
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from camera_ui_python_common import ReactiveProperty
|
|
39
|
+
|
|
40
|
+
# Create reactive state
|
|
41
|
+
state = ReactiveProperty({"count": 0, "active": True})
|
|
42
|
+
|
|
43
|
+
# Subscribe to changes
|
|
44
|
+
state.observable.subscribe(lambda value: print(f"State: {value}"))
|
|
45
|
+
|
|
46
|
+
# Update state
|
|
47
|
+
state.next({"count": 1, "active": True})
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Signal Handling
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from camera_ui_python_common import SignalHandler
|
|
54
|
+
|
|
55
|
+
async def cleanup():
|
|
56
|
+
print("Cleaning up...")
|
|
57
|
+
|
|
58
|
+
signal_handler = SignalHandler({
|
|
59
|
+
"display_name": "MyPlugin",
|
|
60
|
+
"logger": logger,
|
|
61
|
+
"close_function": cleanup
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
signal_handler.setup_handlers()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Object Path Operations
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from camera_ui_python_common import ObjectPath
|
|
71
|
+
|
|
72
|
+
data = {"camera": {"settings": {"resolution": "1080p"}}}
|
|
73
|
+
|
|
74
|
+
# Get nested values
|
|
75
|
+
resolution = ObjectPath.get(data, "camera.settings.resolution")
|
|
76
|
+
|
|
77
|
+
# Set nested values
|
|
78
|
+
ObjectPath.set(data, "camera.settings.bitrate", 5000)
|
|
79
|
+
|
|
80
|
+
# Check if path exists
|
|
81
|
+
has_setting = ObjectPath.has(data, "camera.settings.fps")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Async Utilities
|
|
85
|
+
|
|
86
|
+
### Task Management
|
|
87
|
+
```python
|
|
88
|
+
from camera_ui_python_common import TaskSet
|
|
89
|
+
|
|
90
|
+
tasks = TaskSet("MyTasks")
|
|
91
|
+
tasks.add(my_async_function())
|
|
92
|
+
await tasks
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Thread Operations
|
|
96
|
+
```python
|
|
97
|
+
from camera_ui_python_common import to_thread
|
|
98
|
+
|
|
99
|
+
# Run blocking operation in thread
|
|
100
|
+
result = await to_thread(blocking_function)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Sync/Async Bridge
|
|
104
|
+
```python
|
|
105
|
+
from camera_ui_python_common import make_sync
|
|
106
|
+
|
|
107
|
+
# Convert async function to sync
|
|
108
|
+
sync_version = make_sync(async_function)
|
|
109
|
+
result = sync_version(args)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## RTSP Utilities
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from camera_ui_python_common import build_target_url
|
|
116
|
+
|
|
117
|
+
url = build_target_url("rtsp://camera.local/stream", {
|
|
118
|
+
"video": True,
|
|
119
|
+
"audio": ["pcma", "opus"],
|
|
120
|
+
"timeout": 30
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Complete Example
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
import asyncio
|
|
128
|
+
from camera_ui_python_common import LoggerService, ReactiveProperty, SignalHandler
|
|
129
|
+
|
|
130
|
+
class MyPlugin:
|
|
131
|
+
def __init__(self):
|
|
132
|
+
self.logger = LoggerService({"prefix": "MyPlugin"})
|
|
133
|
+
self.state = ReactiveProperty({"active": False})
|
|
134
|
+
|
|
135
|
+
self.signal_handler = SignalHandler({
|
|
136
|
+
"display_name": "MyPlugin",
|
|
137
|
+
"logger": self.logger,
|
|
138
|
+
"close_function": self.cleanup
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
async def start(self):
|
|
142
|
+
self.logger.log("Starting plugin...")
|
|
143
|
+
self.signal_handler.setup_handlers()
|
|
144
|
+
|
|
145
|
+
# Update state
|
|
146
|
+
self.state.next({"active": True})
|
|
147
|
+
|
|
148
|
+
# Keep running
|
|
149
|
+
await asyncio.Future()
|
|
150
|
+
|
|
151
|
+
async def cleanup(self):
|
|
152
|
+
self.logger.log("Stopping plugin...")
|
|
153
|
+
|
|
154
|
+
# Usage
|
|
155
|
+
plugin = MyPlugin()
|
|
156
|
+
asyncio.run(plugin.start())
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Contributing
|
|
160
|
+
|
|
161
|
+
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
*Part of the camera.ui ecosystem - A comprehensive camera management solution.*
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from .common_utils.object_path import ObjectPath, Path
|
|
2
|
+
from .common_utils.promise import Deferred
|
|
3
|
+
from .common_utils.reactive import ReactiveProperty
|
|
4
|
+
from .common_utils.signal_handler import SignalHandler, SignalHandlerOptions
|
|
5
|
+
from .common_utils.subscribed import Subscribed
|
|
6
|
+
from .common_utils.task import TaskSet
|
|
7
|
+
from .common_utils.thread import to_thread
|
|
8
|
+
from .common_utils.utils import make_sync, merge, merge_with
|
|
9
|
+
from .logger_service.ansicolor import Ansicolor
|
|
10
|
+
from .logger_service.logger import LoggerOptions, LoggerService
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"Deferred",
|
|
14
|
+
"ObjectPath",
|
|
15
|
+
"Path",
|
|
16
|
+
"SignalHandler",
|
|
17
|
+
"SignalHandlerOptions",
|
|
18
|
+
"Subscribed",
|
|
19
|
+
"TaskSet",
|
|
20
|
+
"to_thread",
|
|
21
|
+
"make_sync",
|
|
22
|
+
"merge",
|
|
23
|
+
"merge_with",
|
|
24
|
+
"ReactiveProperty",
|
|
25
|
+
"Ansicolor",
|
|
26
|
+
"LoggerOptions",
|
|
27
|
+
"LoggerService",
|
|
28
|
+
]
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Camera utility functions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from urllib.parse import urlparse
|
|
6
|
+
|
|
7
|
+
from camera_ui_python_types import RTSPUrlOptions
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def build_target_url(rtsp_url: str, options: RTSPUrlOptions | None = None) -> str:
|
|
11
|
+
"""
|
|
12
|
+
Build a target URL with streaming options.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
rtsp_url: The base RTSP URL
|
|
16
|
+
options: Optional streaming options
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
The constructed URL with query parameters
|
|
20
|
+
"""
|
|
21
|
+
if options is None:
|
|
22
|
+
options = {}
|
|
23
|
+
|
|
24
|
+
parsed = urlparse(rtsp_url)
|
|
25
|
+
base_url = f"{parsed.scheme}://{parsed.netloc}{parsed.path}"
|
|
26
|
+
|
|
27
|
+
# Extract options with defaults
|
|
28
|
+
video = options.get("video", True)
|
|
29
|
+
audio = options.get("audio", True)
|
|
30
|
+
audio_single_track = options.get("audioSingleTrack", True)
|
|
31
|
+
backchannel = options.get("backchannel", False)
|
|
32
|
+
timeout = options.get("timeout", 15)
|
|
33
|
+
gop = options.get("gop", True)
|
|
34
|
+
prebuffer = options.get("prebuffer", False)
|
|
35
|
+
|
|
36
|
+
# Validate timeout (5-30 seconds)
|
|
37
|
+
validated_timeout = min(max(5, timeout), 30)
|
|
38
|
+
|
|
39
|
+
params: list[str] = []
|
|
40
|
+
|
|
41
|
+
# Video parameter
|
|
42
|
+
if video:
|
|
43
|
+
params.append("video")
|
|
44
|
+
|
|
45
|
+
# Audio parameter
|
|
46
|
+
if audio:
|
|
47
|
+
if isinstance(audio, bool):
|
|
48
|
+
params.append("audio")
|
|
49
|
+
elif isinstance(audio, list):
|
|
50
|
+
if audio_single_track:
|
|
51
|
+
# Single track with multiple codecs
|
|
52
|
+
params.append(f"audio={','.join(audio)}")
|
|
53
|
+
else:
|
|
54
|
+
# Multiple tracks
|
|
55
|
+
for codec in audio:
|
|
56
|
+
params.append(f"audio={codec}")
|
|
57
|
+
else:
|
|
58
|
+
params.append(f"audio={audio}")
|
|
59
|
+
|
|
60
|
+
# Backchannel parameter
|
|
61
|
+
if backchannel:
|
|
62
|
+
params.append("backchannel=1")
|
|
63
|
+
|
|
64
|
+
# GOP parameter
|
|
65
|
+
if gop:
|
|
66
|
+
params.append("gop=1")
|
|
67
|
+
|
|
68
|
+
# Prebuffer parameter
|
|
69
|
+
if prebuffer:
|
|
70
|
+
params.append("prebuffer=5")
|
|
71
|
+
|
|
72
|
+
# Timeout parameter
|
|
73
|
+
params.append(f"timeout={validated_timeout}")
|
|
74
|
+
|
|
75
|
+
return f"{base_url}?{'&'.join(params)}"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .object_path import ObjectPath, Path
|
|
2
|
+
from .promise import Deferred
|
|
3
|
+
from .reactive import ReactiveProperty
|
|
4
|
+
from .signal_handler import SignalHandler
|
|
5
|
+
from .subscribed import Subscribed
|
|
6
|
+
from .task import TaskSet
|
|
7
|
+
from .thread import to_thread
|
|
8
|
+
from .utils import make_sync, merge, merge_with
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"Deferred",
|
|
12
|
+
"make_sync",
|
|
13
|
+
"merge",
|
|
14
|
+
"merge_with",
|
|
15
|
+
"ObjectPath",
|
|
16
|
+
"Path",
|
|
17
|
+
"ReactiveProperty",
|
|
18
|
+
"SignalHandler",
|
|
19
|
+
"Subscribed",
|
|
20
|
+
"TaskSet",
|
|
21
|
+
"to_thread",
|
|
22
|
+
]
|