agora-python-server-sdk 2.1.7__tar.gz → 2.2.1__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.
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/PKG-INFO +28 -2
- agora_python_server_sdk-2.1.7/agora_python_server_sdk.egg-info/PKG-INFO → agora_python_server_sdk-2.2.1/README.md +21 -16
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/__init__.py +14 -4
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/_ctypes_handle/_ctypes_data.py +37 -7
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/_ctypes_handle/_local_user_observer.py +9 -1
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/agora_base.py +17 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/agora_service.py +4 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/local_user.py +18 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/local_user_observer.py +3 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/utils/audio_consumer.py +30 -4
- agora_python_server_sdk-2.1.7/README.md → agora_python_server_sdk-2.2.1/agora_python_server_sdk.egg-info/PKG-INFO +42 -1
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/setup.py +9 -4
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/MANIFEST.in +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/_ctypes_handle/_audio_frame_observer.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/_ctypes_handle/_rtc_connection_observer.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/_ctypes_handle/_video_encoded_frame_observer.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/_ctypes_handle/_video_frame_observer.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/_utils/globals.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/agora_parameter.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/audio_encoded_frame_sender.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/audio_frame_observer.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/audio_pcm_data_sender.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/audio_sessionctrl.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/audio_vad_manager.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/local_audio_track.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/local_video_track.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/media_node_factory.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/remote_audio_track.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/remote_video_track.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/rtc_connection.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/rtc_connection_observer.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/utils/vad_dump.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/video_encoded_frame_observer.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/video_encoded_image_sender.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/video_frame_observer.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/video_frame_sender.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/voice_detection.py +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora_python_server_sdk.egg-info/SOURCES.txt +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora_python_server_sdk.egg-info/dependency_links.txt +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora_python_server_sdk.egg-info/top_level.txt +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/pyproject.toml +0 -0
- {agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: agora_python_server_sdk
|
|
3
|
-
Version: 2.1
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: A Python SDK for Agora Server
|
|
5
5
|
Home-page: https://github.com/AgoraIO-Extensions/Agora-Python-Server-SDK
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -12,6 +12,12 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
12
12
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
13
|
Requires-Python: >=3.10
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
|
+
Dynamic: classifier
|
|
16
|
+
Dynamic: description
|
|
17
|
+
Dynamic: description-content-type
|
|
18
|
+
Dynamic: home-page
|
|
19
|
+
Dynamic: requires-python
|
|
20
|
+
Dynamic: summary
|
|
15
21
|
|
|
16
22
|
# Note
|
|
17
23
|
- This is a Python SDK wrapper for the Agora RTC SDK.
|
|
@@ -50,6 +56,26 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
|
|
|
50
56
|
```
|
|
51
57
|
|
|
52
58
|
# Change log
|
|
59
|
+
2025.02.26 Release 2.2.1
|
|
60
|
+
--Update:
|
|
61
|
+
- Reduced buffer size from 180ms to 100ms to minimize latency.
|
|
62
|
+
-- Added:
|
|
63
|
+
- AudioConsumer::is_push_to_rtc_completed: Add audio consumer support for playback state notifications.
|
|
64
|
+
-- Bug fix:
|
|
65
|
+
- Fixed incorrect _samples_per_channel calculation in stereo mode.
|
|
66
|
+
|
|
67
|
+
2025.01.08 Release 2.2.0
|
|
68
|
+
-- Updates:
|
|
69
|
+
- Update the SDK version from 4.4.30 to 4.4.31. Done.
|
|
70
|
+
-- FEAT:
|
|
71
|
+
- Add serviceconfigure.
|
|
72
|
+
- Add domain_limit. Done.
|
|
73
|
+
- Add should_callback_when_muted. Done.
|
|
74
|
+
- Add colorspacetype to ExternalVideoFrame to support the encoding of solid-color backgrounds in virtual human scenarios. Done.
|
|
75
|
+
-- FEAT:
|
|
76
|
+
- Add the AudioMetaData interface: localuser::send_audio_meta_data. Done.
|
|
77
|
+
- Add the OnAudioMetaDataReceived callback to localuserObserver::on_audio_meta_data_received. Done.
|
|
78
|
+
-- Sample modifications.
|
|
53
79
|
|
|
54
80
|
2024.12.17 Release 2.1.7
|
|
55
81
|
--Changes:
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: agora_python_server_sdk
|
|
3
|
-
Version: 2.1.7
|
|
4
|
-
Summary: A Python SDK for Agora Server
|
|
5
|
-
Home-page: https://github.com/AgoraIO-Extensions/Agora-Python-Server-SDK
|
|
6
|
-
Classifier: Intended Audience :: Developers
|
|
7
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
-
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
9
|
-
Classifier: Topic :: Multimedia :: Video
|
|
10
|
-
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
-
Requires-Python: >=3.10
|
|
14
|
-
Description-Content-Type: text/markdown
|
|
15
|
-
|
|
16
1
|
# Note
|
|
17
2
|
- This is a Python SDK wrapper for the Agora RTC SDK.
|
|
18
3
|
- It supports Linux and Mac platforms.
|
|
@@ -50,6 +35,26 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
|
|
|
50
35
|
```
|
|
51
36
|
|
|
52
37
|
# Change log
|
|
38
|
+
2025.02.26 Release 2.2.1
|
|
39
|
+
--Update:
|
|
40
|
+
- Reduced buffer size from 180ms to 100ms to minimize latency.
|
|
41
|
+
-- Added:
|
|
42
|
+
- AudioConsumer::is_push_to_rtc_completed: Add audio consumer support for playback state notifications.
|
|
43
|
+
-- Bug fix:
|
|
44
|
+
- Fixed incorrect _samples_per_channel calculation in stereo mode.
|
|
45
|
+
|
|
46
|
+
2025.01.08 Release 2.2.0
|
|
47
|
+
-- Updates:
|
|
48
|
+
- Update the SDK version from 4.4.30 to 4.4.31. Done.
|
|
49
|
+
-- FEAT:
|
|
50
|
+
- Add serviceconfigure.
|
|
51
|
+
- Add domain_limit. Done.
|
|
52
|
+
- Add should_callback_when_muted. Done.
|
|
53
|
+
- Add colorspacetype to ExternalVideoFrame to support the encoding of solid-color backgrounds in virtual human scenarios. Done.
|
|
54
|
+
-- FEAT:
|
|
55
|
+
- Add the AudioMetaData interface: localuser::send_audio_meta_data. Done.
|
|
56
|
+
- Add the OnAudioMetaDataReceived callback to localuserObserver::on_audio_meta_data_received. Done.
|
|
57
|
+
-- Sample modifications.
|
|
53
58
|
|
|
54
59
|
2024.12.17 Release 2.1.7
|
|
55
60
|
--Changes:
|
|
@@ -322,4 +327,4 @@ VAD: Good afternoon, what are some fun places to visit in Beijing?
|
|
|
322
327
|
|
|
323
328
|
|
|
324
329
|
|
|
325
|
-
If latency is a concern, you can lower this value, or consult with the development team to determine how to manage latency while ensuring semantic continuity in speech recognition. This will help avoid the AI being interrupted too sensitively.
|
|
330
|
+
If latency is a concern, you can lower this value, or consult with the development team to determine how to manage latency while ensuring semantic continuity in speech recognition. This will help avoid the AI being interrupted too sensitively.
|
|
@@ -26,13 +26,23 @@ def _check_download_and_extract_sdk():
|
|
|
26
26
|
sdk_dir = os.path.join(agora_service_path, "agora_sdk")
|
|
27
27
|
zip_path = os.path.join(agora_service_path, "agora_rtc_sdk.zip")
|
|
28
28
|
|
|
29
|
-
url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.30-20241024_101940-398537.zip"
|
|
29
|
+
#url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.30-20241024_101940-398537.zip"
|
|
30
|
+
# version 2.2.0 for linux
|
|
31
|
+
url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.31-20241223_111509-491956.zip"
|
|
32
|
+
|
|
33
|
+
|
|
30
34
|
libagora_rtc_sdk_path = os.path.join(sdk_dir, "libagora_rtc_sdk.so")
|
|
31
|
-
rtc_md5 = "7031dd10d1681cd88fd89d68c5b54282"
|
|
35
|
+
#rtc_md5 = "7031dd10d1681cd88fd89d68c5b54282"
|
|
36
|
+
rtc_md5 = "f2a9e3ed15f872cb7e3b62d1528ac5cb"
|
|
32
37
|
if sys.platform == 'darwin':
|
|
33
|
-
url = "https://download.agora.io/sdk/release/agora_rtc_sdk_mac_rel.v4.4.30_22472_FULL_20241024_1224_398653.zip"
|
|
38
|
+
#url = "https://download.agora.io/sdk/release/agora_rtc_sdk_mac_rel.v4.4.30_22472_FULL_20241024_1224_398653.zip"
|
|
39
|
+
# version 2.2.0 for mac
|
|
40
|
+
url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.31_23136_FULL_20241223_1245_492039.zip"
|
|
41
|
+
|
|
34
42
|
libagora_rtc_sdk_path = os.path.join(sdk_dir, "libAgoraRtcKit.dylib")
|
|
35
|
-
rtc_md5 = "ca3ca14f9e2b7d97eb2594d1f32dab9f"
|
|
43
|
+
#rtc_md5 = "ca3ca14f9e2b7d97eb2594d1f32dab9f"
|
|
44
|
+
rtc_md5 = "6821cae218c8f31f8d720ac0c77edab0"
|
|
45
|
+
|
|
36
46
|
|
|
37
47
|
if os.path.exists(libagora_rtc_sdk_path) and get_file_md5(libagora_rtc_sdk_path) == rtc_md5:
|
|
38
48
|
return
|
|
@@ -718,6 +718,29 @@ class RemoteVideoTrackStatsInner(ctypes.Structure):
|
|
|
718
718
|
stats.total_active_time,
|
|
719
719
|
stats.publish_duration
|
|
720
720
|
)
|
|
721
|
+
|
|
722
|
+
class ColorSpaceTypeInner(ctypes.Structure):
|
|
723
|
+
_fields_ = [
|
|
724
|
+
("primaries_id", ctypes.c_int),
|
|
725
|
+
("transfer_id", ctypes.c_int),
|
|
726
|
+
("matrix_id", ctypes.c_int),
|
|
727
|
+
("range_id", ctypes.c_int)
|
|
728
|
+
]
|
|
729
|
+
def get(self):
|
|
730
|
+
return ColorSpaceType(
|
|
731
|
+
primaries_id=self.primaries_id,
|
|
732
|
+
transfer_id=self.transfer_id,
|
|
733
|
+
matrix_id=self.matrix_id,
|
|
734
|
+
range_id=self.range_id
|
|
735
|
+
)
|
|
736
|
+
@staticmethod
|
|
737
|
+
def create(colorspace:ColorSpaceType) -> 'ColorSpaceTypeInner':
|
|
738
|
+
return ColorSpaceTypeInner(
|
|
739
|
+
primaries_id=colorspace.primaries_id,
|
|
740
|
+
transfer_id=colorspace.transfer_id,
|
|
741
|
+
matrix_id=colorspace.matrix_id,
|
|
742
|
+
range_id=colorspace.range_id
|
|
743
|
+
)
|
|
721
744
|
|
|
722
745
|
|
|
723
746
|
class ExternalVideoFrameInner(ctypes.Structure):
|
|
@@ -741,7 +764,8 @@ class ExternalVideoFrameInner(ctypes.Structure):
|
|
|
741
764
|
("metadata_size", ctypes.c_int),
|
|
742
765
|
("alpha_buffer", ctypes.c_void_p),
|
|
743
766
|
("fill_alpha_buffer", ctypes.c_uint8),
|
|
744
|
-
("alpha_mode", ctypes.c_int)
|
|
767
|
+
("alpha_mode", ctypes.c_int),
|
|
768
|
+
("color_space", ColorSpaceTypeInner)
|
|
745
769
|
]
|
|
746
770
|
|
|
747
771
|
def get(self):
|
|
@@ -765,7 +789,8 @@ class ExternalVideoFrameInner(ctypes.Structure):
|
|
|
765
789
|
metadata_size=self.metadata_size,
|
|
766
790
|
alpha_buffer=self.alpha_buffer,
|
|
767
791
|
fill_alpha_buffer=self.fill_alpha_buffer,
|
|
768
|
-
alpha_mode=self.alpha_mode
|
|
792
|
+
alpha_mode=self.alpha_mode,
|
|
793
|
+
color_space=self.color_space.get()
|
|
769
794
|
)
|
|
770
795
|
|
|
771
796
|
@staticmethod
|
|
@@ -784,12 +809,13 @@ class ExternalVideoFrameInner(ctypes.Structure):
|
|
|
784
809
|
else:
|
|
785
810
|
c_alpha_buffer_ptr = ctypes.c_void_p(0)
|
|
786
811
|
|
|
787
|
-
c_metadata_size = len (frame.metadata)
|
|
812
|
+
c_metadata_size = len (frame.metadata) if frame.metadata is not None else 0
|
|
788
813
|
if frame.metadata is not None and c_metadata_size > 0:
|
|
789
814
|
c_metadata_ptr = (ctypes.c_uint8 * len(frame.metadata)).from_buffer(frame.metadata)
|
|
790
815
|
c_metadata_size = len(frame.metadata)
|
|
791
816
|
else:
|
|
792
|
-
c_metadata_ptr = ctypes.c_void_p(0)
|
|
817
|
+
#c_metadata_ptr = ctypes.c_void_p(0)
|
|
818
|
+
c_metadata_ptr = ctypes.POINTER(ctypes.c_uint8)()
|
|
793
819
|
c_metadata_size = 0
|
|
794
820
|
|
|
795
821
|
|
|
@@ -815,7 +841,8 @@ class ExternalVideoFrameInner(ctypes.Structure):
|
|
|
815
841
|
c_metadata_size,
|
|
816
842
|
c_alpha_buffer_ptr,
|
|
817
843
|
frame.fill_alpha_buffer,
|
|
818
|
-
frame.alpha_mode
|
|
844
|
+
frame.alpha_mode,
|
|
845
|
+
ColorSpaceTypeInner.create(frame.color_space)
|
|
819
846
|
)
|
|
820
847
|
|
|
821
848
|
|
|
@@ -1105,6 +1132,7 @@ class AgoraServiceConfigInner(ctypes.Structure):
|
|
|
1105
1132
|
('audio_scenario', ctypes.c_int),
|
|
1106
1133
|
|
|
1107
1134
|
('use_string_uid', ctypes.c_int),
|
|
1135
|
+
('domain_limit', ctypes.c_int),
|
|
1108
1136
|
]
|
|
1109
1137
|
|
|
1110
1138
|
def get(self):
|
|
@@ -1117,7 +1145,8 @@ class AgoraServiceConfigInner(ctypes.Structure):
|
|
|
1117
1145
|
area_code=self.area_code,
|
|
1118
1146
|
channel_profile=self.channel_profile,
|
|
1119
1147
|
audio_scenario=self.audio_scenario,
|
|
1120
|
-
use_string_uid=self.use_string_uid
|
|
1148
|
+
use_string_uid=self.use_string_uid,
|
|
1149
|
+
domain_limit=self.domain_limit
|
|
1121
1150
|
)
|
|
1122
1151
|
|
|
1123
1152
|
@staticmethod
|
|
@@ -1131,7 +1160,8 @@ class AgoraServiceConfigInner(ctypes.Structure):
|
|
|
1131
1160
|
config.area_code,
|
|
1132
1161
|
config.channel_profile,
|
|
1133
1162
|
config.audio_scenario,
|
|
1134
|
-
config.use_string_uid
|
|
1163
|
+
config.use_string_uid,
|
|
1164
|
+
config.domain_limit
|
|
1135
1165
|
)
|
|
1136
1166
|
|
|
1137
1167
|
|
|
@@ -44,6 +44,7 @@ ON_INTRA_REQUEST_RECEIVED_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE)
|
|
|
44
44
|
ON_REMOTE_SUBSCRIBE_FALLBACK_TO_AUDIO_ONLY_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE, user_id_t, ctypes.c_int)
|
|
45
45
|
ON_STREAM_MESSAGE_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE, user_id_t, ctypes.c_int, ctypes.c_char_p, ctypes.c_size_t)
|
|
46
46
|
ON_USER_STATE_CHANGED_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE, user_id_t, ctypes.c_uint32)
|
|
47
|
+
ON_AUDIO_META_DATA_RECEIVED_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE, user_id_t, ctypes.c_char_p, ctypes.c_size_t)
|
|
47
48
|
|
|
48
49
|
|
|
49
50
|
class RTCLocalUserObserverInner(ctypes.Structure):
|
|
@@ -85,7 +86,8 @@ class RTCLocalUserObserverInner(ctypes.Structure):
|
|
|
85
86
|
("on_intra_request_received", ON_INTRA_REQUEST_RECEIVED_CALLBACK),
|
|
86
87
|
("on_remote_subscribe_fallback_to_audio_only", ON_REMOTE_SUBSCRIBE_FALLBACK_TO_AUDIO_ONLY_CALLBACK),
|
|
87
88
|
("on_stream_message", ON_STREAM_MESSAGE_CALLBACK),
|
|
88
|
-
("on_user_state_changed", ON_USER_STATE_CHANGED_CALLBACK)
|
|
89
|
+
("on_user_state_changed", ON_USER_STATE_CHANGED_CALLBACK),
|
|
90
|
+
("on_audio_meta_data_received", ON_AUDIO_META_DATA_RECEIVED_CALLBACK)
|
|
89
91
|
]
|
|
90
92
|
|
|
91
93
|
def __init__(self, local_user_observer: IRTCLocalUserObserver, local_user: 'LocalUser') -> None:
|
|
@@ -128,6 +130,7 @@ class RTCLocalUserObserverInner(ctypes.Structure):
|
|
|
128
130
|
self.on_remote_subscribe_fallback_to_audio_only = ON_REMOTE_SUBSCRIBE_FALLBACK_TO_AUDIO_ONLY_CALLBACK(self._on_remote_subscribe_fallback_to_audio_only)
|
|
129
131
|
self.on_stream_message = ON_STREAM_MESSAGE_CALLBACK(self._on_stream_message)
|
|
130
132
|
self.on_user_state_changed = ON_USER_STATE_CHANGED_CALLBACK(self._on_user_state_changed)
|
|
133
|
+
self.on_audio_meta_data_received = ON_AUDIO_META_DATA_RECEIVED_CALLBACK(self._on_audio_meta_data_received)
|
|
131
134
|
|
|
132
135
|
"""
|
|
133
136
|
it seems that this interface does not provide much value to the user's business,
|
|
@@ -348,3 +351,8 @@ class RTCLocalUserObserverInner(ctypes.Structure):
|
|
|
348
351
|
logger.debug(f"LocalUserCB _on_user_state_changed: {local_user_handle}, {user_id}, {state}")
|
|
349
352
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
350
353
|
self.local_user_observer.on_user_state_changed(self.local_user, user_id_str, state)
|
|
354
|
+
def _on_audio_meta_data_received(self, local_user_handle, user_id, audio_meta_data, size):
|
|
355
|
+
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
356
|
+
bytes_from_c = bytearray(ctypes.string_at(audio_meta_data, size))
|
|
357
|
+
|
|
358
|
+
self.local_user_observer.on_audio_meta_data_received(self.local_user, user_id_str, bytes_from_c)
|
|
@@ -307,6 +307,15 @@ class AgoraServiceConfig:
|
|
|
307
307
|
channel_profile: ChannelProfileType = ChannelProfileType.CHANNEL_PROFILE_LIVE_BROADCASTING
|
|
308
308
|
audio_scenario: AudioScenarioType = AudioScenarioType.AUDIO_SCENARIO_CHORUS
|
|
309
309
|
use_string_uid: int = 0
|
|
310
|
+
#version 2.2.0
|
|
311
|
+
# default to 0
|
|
312
|
+
domain_limit: int = 0
|
|
313
|
+
'''
|
|
314
|
+
// if >0, when remote user muted itself, the onplaybackbeforemixing will be still called badk with active pacakage
|
|
315
|
+
// if <=0, when remote user muted itself, the onplaybackbeforemixing will be no longer called back
|
|
316
|
+
// default to 0, i.e when muted, no callback will be triggered
|
|
317
|
+
'''
|
|
318
|
+
should_callbck_when_muted: int = 0
|
|
310
319
|
|
|
311
320
|
|
|
312
321
|
@dataclass(kw_only=True)
|
|
@@ -423,6 +432,13 @@ class VideoEncoderConfiguration:
|
|
|
423
432
|
mirror_mode: int = 0
|
|
424
433
|
encode_alpha: int = 0
|
|
425
434
|
|
|
435
|
+
@dataclass(kw_only=True)
|
|
436
|
+
class ColorSpaceType:
|
|
437
|
+
primaries_id: int = 0
|
|
438
|
+
transfer_id: int = 0
|
|
439
|
+
matrix_id: int = 0
|
|
440
|
+
range_id: int = 0
|
|
441
|
+
|
|
426
442
|
|
|
427
443
|
@dataclass(kw_only=True)
|
|
428
444
|
class ExternalVideoFrame:
|
|
@@ -445,6 +461,7 @@ class ExternalVideoFrame:
|
|
|
445
461
|
alpha_buffer: bytearray = None
|
|
446
462
|
fill_alpha_buffer: int = 0
|
|
447
463
|
alpha_mode: int = 0
|
|
464
|
+
color_space: ColorSpaceType = field(default_factory=ColorSpaceType)
|
|
448
465
|
|
|
449
466
|
|
|
450
467
|
@dataclass(kw_only=True)
|
|
@@ -92,6 +92,10 @@ class AgoraService:
|
|
|
92
92
|
# force audio vad v2 to be enabled
|
|
93
93
|
agora_parameter.set_parameters("{\"che.audio.label.enable\": true}")
|
|
94
94
|
|
|
95
|
+
#versio 2.2.0 for callback when muted
|
|
96
|
+
if config.should_callbck_when_muted > 0:
|
|
97
|
+
agora_parameter.set_parameters("{\"rtc.audio.enable_user_silence_packet\": true}")
|
|
98
|
+
|
|
95
99
|
if config.log_path:
|
|
96
100
|
log_size = 512 * 1024
|
|
97
101
|
if config.log_size > 0:
|
|
@@ -223,6 +223,15 @@ agora_local_user_set_audio_scenario = agora_lib.agora_local_user_set_audio_scena
|
|
|
223
223
|
agora_local_user_set_audio_scenario.restype = AGORA_API_C_INT
|
|
224
224
|
agora_local_user_set_audio_scenario.argtypes = [AGORA_HANDLE, ctypes.c_int]
|
|
225
225
|
|
|
226
|
+
#verison 2.2.0
|
|
227
|
+
|
|
228
|
+
#AGORA_API_C_INT agora_local_user_send_audio_meta_data(AGORA_HANDLE agora_local_user, const char* meta_data, size_t length);
|
|
229
|
+
agora_local_user_send_aduio_meta_data = agora_lib.agora_local_user_send_audio_meta_data
|
|
230
|
+
agora_local_user_send_aduio_meta_data.restype = AGORA_API_C_INT
|
|
231
|
+
agora_local_user_send_aduio_meta_data.argtypes = [AGORA_HANDLE, ctypes.c_char_p, ctypes.c_size_t]
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
226
235
|
|
|
227
236
|
class LocalUser:
|
|
228
237
|
def __init__(self, local_user_handle, connection):
|
|
@@ -594,3 +603,12 @@ class LocalUser:
|
|
|
594
603
|
def set_audio_scenario(self, scenario_type: AudioScenarioType):
|
|
595
604
|
ret = agora_local_user_set_audio_scenario(self.user_handle, scenario_type.value)
|
|
596
605
|
return ret
|
|
606
|
+
# data can be str or bytes/bytearray object,is diff to send_sream_message which is a str object
|
|
607
|
+
def send_audio_meta_data(self, data):
|
|
608
|
+
# chang to ctypes.c_char_p
|
|
609
|
+
if isinstance(data, str):
|
|
610
|
+
data = data.encode('utf-8')
|
|
611
|
+
c_data = ctypes.create_string_buffer(bytes(data))
|
|
612
|
+
size = len(data)
|
|
613
|
+
ret = agora_local_user_send_aduio_meta_data(self.user_handle, c_data, ctypes.c_size_t(size))
|
|
614
|
+
return ret
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/local_user_observer.py
RENAMED
|
@@ -117,3 +117,6 @@ class IRTCLocalUserObserver():
|
|
|
117
117
|
|
|
118
118
|
def on_user_state_changed(self, agora_local_user, user_id, state):
|
|
119
119
|
pass
|
|
120
|
+
# data is bytearray object, is diff to on_stream_msg which is str object
|
|
121
|
+
def on_audio_meta_data_received(self, agora_local_user, user_id, data):
|
|
122
|
+
pass
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/utils/audio_consumer.py
RENAMED
|
@@ -31,6 +31,8 @@ AudioConsumer调用方式:
|
|
|
31
31
|
E 退出的时候,调用release()方法,释放资源
|
|
32
32
|
"""
|
|
33
33
|
class AudioConsumer:
|
|
34
|
+
MIN_BUFFER_SIZE = 10
|
|
35
|
+
RTC_E2E_DELAY = 200 # e2e delay 90ms for iphone, 120ms for android;150ms for web. so we use 200ms here
|
|
34
36
|
def __init__(self, pcm_sender: AudioPcmDataSender, sample_rate: int, channels: int) -> None:
|
|
35
37
|
self._lock = threading.Lock()
|
|
36
38
|
self._start_time = 0
|
|
@@ -45,11 +47,12 @@ class AudioConsumer:
|
|
|
45
47
|
#audio parame
|
|
46
48
|
self._frame.bytes_per_sample = 2
|
|
47
49
|
self._bytes_per_frame = sample_rate // 100 * channels * 2
|
|
48
|
-
self._samples_per_channel = sample_rate // 100
|
|
50
|
+
self._samples_per_channel = sample_rate // 100
|
|
49
51
|
#init pcmaudioframe
|
|
50
52
|
self._frame.timestamp = 0
|
|
51
53
|
|
|
52
54
|
self._init = True
|
|
55
|
+
self._last_consume_time = 0
|
|
53
56
|
|
|
54
57
|
pass
|
|
55
58
|
def push_pcm_data(self, data) ->None:
|
|
@@ -64,6 +67,7 @@ class AudioConsumer:
|
|
|
64
67
|
return
|
|
65
68
|
self._start_time = time.time()*1000
|
|
66
69
|
self._consumed_packages = 0
|
|
70
|
+
self._last_consume_time = self._start_time
|
|
67
71
|
pass
|
|
68
72
|
|
|
69
73
|
def consume(self):
|
|
@@ -75,13 +79,16 @@ class AudioConsumer:
|
|
|
75
79
|
expected_total_packages = int(elapsed_time//10)
|
|
76
80
|
besent_packages = expected_total_packages - self._consumed_packages
|
|
77
81
|
data_len = len(self._data)
|
|
82
|
+
#if data is not empty, to update last consume time
|
|
83
|
+
if data_len > 0:
|
|
84
|
+
self._last_consume_time = now
|
|
78
85
|
|
|
79
|
-
if besent_packages >
|
|
86
|
+
if besent_packages > AudioConsumer.MIN_BUFFER_SIZE and data_len //self._bytes_per_frame < AudioConsumer.MIN_BUFFER_SIZE: #for fist time, if data_len is not enough, just return and wait for next time
|
|
80
87
|
#print("-----underflow data")
|
|
81
88
|
return -2
|
|
82
|
-
if besent_packages >
|
|
89
|
+
if besent_packages > AudioConsumer.MIN_BUFFER_SIZE: #rest to start state, push 18 packs in Start_STATE
|
|
83
90
|
self._reset()
|
|
84
|
-
besent_packages = min(
|
|
91
|
+
besent_packages = min(AudioConsumer.MIN_BUFFER_SIZE, data_len//self._bytes_per_frame)
|
|
85
92
|
self._consumed_packages = -besent_packages
|
|
86
93
|
|
|
87
94
|
|
|
@@ -113,6 +120,25 @@ class AudioConsumer:
|
|
|
113
120
|
return 0
|
|
114
121
|
with self._lock:
|
|
115
122
|
return len(self._data)
|
|
123
|
+
|
|
124
|
+
#判断AudioConsumer中的数据是否已经完全推送给了RTC 频道
|
|
125
|
+
#因为audioconsumer内部有一定的缓存机制,所以当get_remaining_data_size 返回是0的时候,还有数据没有推送给
|
|
126
|
+
#rtc 频道。如果要判断数据是否完全推送给了rtc 频道,需要调用这个api来做判断。
|
|
127
|
+
#return value:1--push to rtc completed, 0--push to rtc not completed -1--error
|
|
128
|
+
def is_push_to_rtc_completed(self)->int:
|
|
129
|
+
if self._init == False:
|
|
130
|
+
return -1
|
|
131
|
+
with self._lock:
|
|
132
|
+
remain_size = len(self._data)
|
|
133
|
+
if remain_size == 0:
|
|
134
|
+
now = time.time()*1000
|
|
135
|
+
diff = now - self._last_consume_time
|
|
136
|
+
|
|
137
|
+
if diff > AudioConsumer.MIN_BUFFER_SIZE*10 + AudioConsumer.RTC_E2E_DELAY:
|
|
138
|
+
return 1
|
|
139
|
+
|
|
140
|
+
return 0
|
|
141
|
+
pass
|
|
116
142
|
def clear(self):
|
|
117
143
|
if self._init == False:
|
|
118
144
|
return
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: agora_python_server_sdk
|
|
3
|
+
Version: 2.2.1
|
|
4
|
+
Summary: A Python SDK for Agora Server
|
|
5
|
+
Home-page: https://github.com/AgoraIO-Extensions/Agora-Python-Server-SDK
|
|
6
|
+
Classifier: Intended Audience :: Developers
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
9
|
+
Classifier: Topic :: Multimedia :: Video
|
|
10
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
Dynamic: classifier
|
|
16
|
+
Dynamic: description
|
|
17
|
+
Dynamic: description-content-type
|
|
18
|
+
Dynamic: home-page
|
|
19
|
+
Dynamic: requires-python
|
|
20
|
+
Dynamic: summary
|
|
21
|
+
|
|
1
22
|
# Note
|
|
2
23
|
- This is a Python SDK wrapper for the Agora RTC SDK.
|
|
3
24
|
- It supports Linux and Mac platforms.
|
|
@@ -35,6 +56,26 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
|
|
|
35
56
|
```
|
|
36
57
|
|
|
37
58
|
# Change log
|
|
59
|
+
2025.02.26 Release 2.2.1
|
|
60
|
+
--Update:
|
|
61
|
+
- Reduced buffer size from 180ms to 100ms to minimize latency.
|
|
62
|
+
-- Added:
|
|
63
|
+
- AudioConsumer::is_push_to_rtc_completed: Add audio consumer support for playback state notifications.
|
|
64
|
+
-- Bug fix:
|
|
65
|
+
- Fixed incorrect _samples_per_channel calculation in stereo mode.
|
|
66
|
+
|
|
67
|
+
2025.01.08 Release 2.2.0
|
|
68
|
+
-- Updates:
|
|
69
|
+
- Update the SDK version from 4.4.30 to 4.4.31. Done.
|
|
70
|
+
-- FEAT:
|
|
71
|
+
- Add serviceconfigure.
|
|
72
|
+
- Add domain_limit. Done.
|
|
73
|
+
- Add should_callback_when_muted. Done.
|
|
74
|
+
- Add colorspacetype to ExternalVideoFrame to support the encoding of solid-color backgrounds in virtual human scenarios. Done.
|
|
75
|
+
-- FEAT:
|
|
76
|
+
- Add the AudioMetaData interface: localuser::send_audio_meta_data. Done.
|
|
77
|
+
- Add the OnAudioMetaDataReceived callback to localuserObserver::on_audio_meta_data_received. Done.
|
|
78
|
+
-- Sample modifications.
|
|
38
79
|
|
|
39
80
|
2024.12.17 Release 2.1.7
|
|
40
81
|
--Changes:
|
|
@@ -307,4 +348,4 @@ VAD: Good afternoon, what are some fun places to visit in Beijing?
|
|
|
307
348
|
|
|
308
349
|
|
|
309
350
|
|
|
310
|
-
If latency is a concern, you can lower this value, or consult with the development team to determine how to manage latency while ensuring semantic continuity in speech recognition. This will help avoid the AI being interrupted too sensitively.
|
|
351
|
+
If latency is a concern, you can lower this value, or consult with the development team to determine how to manage latency while ensuring semantic continuity in speech recognition. This will help avoid the AI being interrupted too sensitively.
|
|
@@ -20,10 +20,15 @@ class CustomInstallCommand(install):
|
|
|
20
20
|
agora_service_path = os.path.join(site.getsitepackages()[0], 'agora', 'rtc')
|
|
21
21
|
sdk_dir = os.path.join(agora_service_path, "agora_sdk")
|
|
22
22
|
zip_path = os.path.join(agora_service_path, "agora_rtc_sdk.zip")
|
|
23
|
-
|
|
24
|
-
url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.30-20241024_101940-398537.zip"
|
|
23
|
+
'''# version before 2.2.0
|
|
24
|
+
#url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.30-20241024_101940-398537.zip"
|
|
25
|
+
#url = "https://download.agora.io/sdk/release/agora_rtc_sdk_mac_rel.v4.4.30_22472_FULL_20241024_1224_398653.zip"
|
|
26
|
+
'''
|
|
27
|
+
# verison 2.2.0
|
|
28
|
+
url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.31-20241223_111509-491956.zip"
|
|
25
29
|
if sys.platform == 'darwin':
|
|
26
|
-
url = "https://download.agora.io/sdk/release/
|
|
30
|
+
url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.31_23136_FULL_20241223_1245_492039.zip"
|
|
31
|
+
|
|
27
32
|
|
|
28
33
|
if os.path.exists(sdk_dir):
|
|
29
34
|
os.system(f"rm -rf {sdk_dir}")
|
|
@@ -45,7 +50,7 @@ class CustomInstallCommand(install):
|
|
|
45
50
|
|
|
46
51
|
setup(
|
|
47
52
|
name='agora_python_server_sdk',
|
|
48
|
-
version='2.1
|
|
53
|
+
version='2.2.1',
|
|
49
54
|
description='A Python SDK for Agora Server',
|
|
50
55
|
long_description=open('README.md').read(),
|
|
51
56
|
long_description_content_type='text/markdown',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/agora_parameter.py
RENAMED
|
File without changes
|
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/audio_frame_observer.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/audio_pcm_data_sender.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/audio_sessionctrl.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/audio_vad_manager.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/local_audio_track.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/local_video_track.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/media_node_factory.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/remote_audio_track.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/remote_video_track.py
RENAMED
|
File without changes
|
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/rtc_connection_observer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/video_frame_observer.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/video_frame_sender.py
RENAMED
|
File without changes
|
{agora_python_server_sdk-2.1.7 → agora_python_server_sdk-2.2.1}/agora/rtc/voice_detection.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|