agora-python-server-sdk 2.3.4__tar.gz → 2.4.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.3.4 → agora_python_server_sdk-2.4.1}/PKG-INFO +41 -7
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/README.md +40 -6
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/__init__.py +48 -11
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/__init__.py +6 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/_ctypes_handle/_ctypes_data.py +46 -1
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/_ctypes_handle/_local_user_observer.py +2 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/agora_base.py +63 -1
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/agora_service.py +59 -1
- agora_python_server_sdk-2.4.1/agora/rtc/external_audio_processor.py +222 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/local_user.py +8 -4
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/rtc_connection.py +27 -1
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/utils/vad_dump.py +78 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/voice_detection.py +55 -21
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora_python_server_sdk.egg-info/PKG-INFO +41 -7
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora_python_server_sdk.egg-info/SOURCES.txt +1 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/setup.py +20 -1
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/MANIFEST.in +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/_ctypes_handle/_audio_frame_observer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/_ctypes_handle/_rtc_connection_observer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/_ctypes_handle/_video_encoded_frame_observer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/_ctypes_handle/_video_frame_observer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/_utils/globals.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/agora_parameter.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/audio_encoded_frame_sender.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/audio_frame_observer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/audio_pcm_data_sender.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/audio_sessionctrl.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/audio_vad_manager.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/local_audio_track.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/local_user_observer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/local_video_track.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/media_node_factory.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/remote_audio_track.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/remote_video_track.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/rtc_connection_observer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/utils/audio_consumer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/video_encoded_frame_observer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/video_encoded_image_sender.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/video_frame_observer.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtc/video_frame_sender.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtm/__init__.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtm/_ctypes_handle/_ctypes_data.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtm/rtm_base.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtm/rtm_client.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora/rtm/rtm_event_handler.py +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora_python_server_sdk.egg-info/dependency_links.txt +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/agora_python_server_sdk.egg-info/top_level.txt +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/pyproject.toml +0 -0
- {agora_python_server_sdk-2.3.4 → agora_python_server_sdk-2.4.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: agora_python_server_sdk
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.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
|
|
@@ -38,7 +38,7 @@ Description-Content-Type: text/markdown
|
|
|
38
38
|
# Required Operating Systems and Python Versions
|
|
39
39
|
- Supported Linux versions:
|
|
40
40
|
- Ubuntu 18.04 LTS and above
|
|
41
|
-
- CentOS
|
|
41
|
+
- CentOS 8.0 and above
|
|
42
42
|
|
|
43
43
|
- Supported Mac versions:
|
|
44
44
|
- MacOS 13 and above(only for coding and testing)
|
|
@@ -57,21 +57,55 @@ pip install agora_python_server_sdk
|
|
|
57
57
|
- Download and unzip [test_data.zip](https://download.agora.io/demo/test/test_data_202408221437.zip) to the Agora-Python-Server-SDK directory.
|
|
58
58
|
|
|
59
59
|
## Executing Test Script
|
|
60
|
-
|
|
60
|
+
for linux os, should set env to :/site_packages/agora/agora_sdk/, like:
|
|
61
61
|
export LD_LIBRARY_PATH=/site_packages/agora/agora_sdk/
|
|
62
62
|
```
|
|
63
63
|
python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx --userId=xxx --audioFile=./test_data/demo.pcm --sampleRate=16000 --numOfChannels=1
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
# Change log
|
|
67
|
+
## 2025.12.17 Release 2.4.1
|
|
68
|
+
|
|
69
|
+
- Updated RTC SDK to version 154.
|
|
70
|
+
- Added support for VAD (Voice Activity Detection) for external audio sources, including:
|
|
71
|
+
- **Background voice removal**
|
|
72
|
+
- **Noise suppression**
|
|
73
|
+
- **Echo cancellation**
|
|
74
|
+
- **Automatic gain control**
|
|
75
|
+
- **Other 3A algorithms**
|
|
76
|
+
All supported via the `external_Audio_Processor`.
|
|
77
|
+
- Modified LocalUser return values for clearer SDK error code distinction.
|
|
78
|
+
- Added `example_external_Audio_Processor.py` to demonstrate external audio data processing.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 2025.11.18 Release 2.4.0
|
|
83
|
+
|
|
84
|
+
- Updated SDK to APM version: `4.4.32/1025`
|
|
85
|
+
- Added configuration support to enable/disable APM.
|
|
86
|
+
- Updated methods in `setup.py` and `__init__.py`, including version/URL and MD5 processing.
|
|
87
|
+
- Completed main code pipeline (**further testing recommended**).
|
|
88
|
+
- Added RTM support: one SDK now supports both RTC and RTM.
|
|
89
|
+
|
|
90
|
+
**To-Do Items:**
|
|
91
|
+
- [x] Add VAD algorithm update
|
|
92
|
+
- [x] Add vad_dump modifications
|
|
93
|
+
- [x] Add APM algorithm VAD switch support
|
|
94
|
+
- [x] Add VAD configuration parameter setting
|
|
95
|
+
- [x] Download and check for MD5 mismatch on every download
|
|
96
|
+
|
|
97
|
+
**Notes:**
|
|
98
|
+
- **APM features** include server-side echo cancellation, noise suppression, automatic gain control, background voice removal, and more.
|
|
99
|
+
- Typically, AEC/AINS/AGC, etc., are handled on the client; server-side activation is only necessary for specific requirements.
|
|
100
|
+
- If you need to enable APM, please contact Agora technical support.
|
|
101
|
+
|
|
102
|
+
**Usage Examples:**
|
|
103
|
+
- [RTC usage example](https://github.com/AgoraIO-Extensions/Agora-Python-Server-SDK/tree/main/agora_rtc/examples)
|
|
104
|
+
- [RTM usage example](https://github.com/AgoraIO-Extensions/Agora-Python-Server-SDK/tree/main/agora_rtc/rtm_examples)
|
|
67
105
|
# 2025.11.07 release 2.3.3
|
|
68
106
|
-- update: to support rtm
|
|
69
107
|
-- adjust sdk's directory structure
|
|
70
108
|
-- change requests to urllib
|
|
71
|
-
# 2025.10.23 release 2.3.2: support rtc and rtm in one package
|
|
72
|
-
-- update: to support rtm.can support both rtc and rtm in one package.
|
|
73
|
-
-- adjust sdk's directory structure
|
|
74
|
-
-- update rtc sdk
|
|
75
109
|
# 2025.10.09 release 2.3.1
|
|
76
110
|
-- update arm64 rtc sdk:Fixed a JNI referencing issue in the previous arm64 build. This issue only outputs logs to the console and does not affect functionality.
|
|
77
111
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
# Required Operating Systems and Python Versions
|
|
24
24
|
- Supported Linux versions:
|
|
25
25
|
- Ubuntu 18.04 LTS and above
|
|
26
|
-
- CentOS
|
|
26
|
+
- CentOS 8.0 and above
|
|
27
27
|
|
|
28
28
|
- Supported Mac versions:
|
|
29
29
|
- MacOS 13 and above(only for coding and testing)
|
|
@@ -42,21 +42,55 @@ pip install agora_python_server_sdk
|
|
|
42
42
|
- Download and unzip [test_data.zip](https://download.agora.io/demo/test/test_data_202408221437.zip) to the Agora-Python-Server-SDK directory.
|
|
43
43
|
|
|
44
44
|
## Executing Test Script
|
|
45
|
-
|
|
45
|
+
for linux os, should set env to :/site_packages/agora/agora_sdk/, like:
|
|
46
46
|
export LD_LIBRARY_PATH=/site_packages/agora/agora_sdk/
|
|
47
47
|
```
|
|
48
48
|
python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx --userId=xxx --audioFile=./test_data/demo.pcm --sampleRate=16000 --numOfChannels=1
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
# Change log
|
|
52
|
+
## 2025.12.17 Release 2.4.1
|
|
53
|
+
|
|
54
|
+
- Updated RTC SDK to version 154.
|
|
55
|
+
- Added support for VAD (Voice Activity Detection) for external audio sources, including:
|
|
56
|
+
- **Background voice removal**
|
|
57
|
+
- **Noise suppression**
|
|
58
|
+
- **Echo cancellation**
|
|
59
|
+
- **Automatic gain control**
|
|
60
|
+
- **Other 3A algorithms**
|
|
61
|
+
All supported via the `external_Audio_Processor`.
|
|
62
|
+
- Modified LocalUser return values for clearer SDK error code distinction.
|
|
63
|
+
- Added `example_external_Audio_Processor.py` to demonstrate external audio data processing.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 2025.11.18 Release 2.4.0
|
|
68
|
+
|
|
69
|
+
- Updated SDK to APM version: `4.4.32/1025`
|
|
70
|
+
- Added configuration support to enable/disable APM.
|
|
71
|
+
- Updated methods in `setup.py` and `__init__.py`, including version/URL and MD5 processing.
|
|
72
|
+
- Completed main code pipeline (**further testing recommended**).
|
|
73
|
+
- Added RTM support: one SDK now supports both RTC and RTM.
|
|
74
|
+
|
|
75
|
+
**To-Do Items:**
|
|
76
|
+
- [x] Add VAD algorithm update
|
|
77
|
+
- [x] Add vad_dump modifications
|
|
78
|
+
- [x] Add APM algorithm VAD switch support
|
|
79
|
+
- [x] Add VAD configuration parameter setting
|
|
80
|
+
- [x] Download and check for MD5 mismatch on every download
|
|
81
|
+
|
|
82
|
+
**Notes:**
|
|
83
|
+
- **APM features** include server-side echo cancellation, noise suppression, automatic gain control, background voice removal, and more.
|
|
84
|
+
- Typically, AEC/AINS/AGC, etc., are handled on the client; server-side activation is only necessary for specific requirements.
|
|
85
|
+
- If you need to enable APM, please contact Agora technical support.
|
|
86
|
+
|
|
87
|
+
**Usage Examples:**
|
|
88
|
+
- [RTC usage example](https://github.com/AgoraIO-Extensions/Agora-Python-Server-SDK/tree/main/agora_rtc/examples)
|
|
89
|
+
- [RTM usage example](https://github.com/AgoraIO-Extensions/Agora-Python-Server-SDK/tree/main/agora_rtc/rtm_examples)
|
|
52
90
|
# 2025.11.07 release 2.3.3
|
|
53
91
|
-- update: to support rtm
|
|
54
92
|
-- adjust sdk's directory structure
|
|
55
93
|
-- change requests to urllib
|
|
56
|
-
# 2025.10.23 release 2.3.2: support rtc and rtm in one package
|
|
57
|
-
-- update: to support rtm.can support both rtc and rtm in one package.
|
|
58
|
-
-- adjust sdk's directory structure
|
|
59
|
-
-- update rtc sdk
|
|
60
94
|
# 2025.10.09 release 2.3.1
|
|
61
95
|
-- update arm64 rtc sdk:Fixed a JNI referencing issue in the previous arm64 build. This issue only outputs logs to the console and does not affect functionality.
|
|
62
96
|
|
|
@@ -95,7 +95,16 @@ def report_progress(blocknum, blocksize, totalsize):
|
|
|
95
95
|
downloaded = blocknum * blocksize
|
|
96
96
|
print(f"\rDownloading: ----{downloaded} bytes-----", end='', flush=True)
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
def _get_url_from_version_file(path: str):
|
|
99
|
+
if not os.path.exists(path):
|
|
100
|
+
return ""
|
|
101
|
+
try:
|
|
102
|
+
with open(path, 'r') as f:
|
|
103
|
+
lines = f.readline()
|
|
104
|
+
return lines
|
|
105
|
+
except Exception as e:
|
|
106
|
+
logger.error(f"Failed to read version file: {e}")
|
|
107
|
+
return ""
|
|
99
108
|
def _check_download_and_extract_sdk():
|
|
100
109
|
agora_service_path = os.path.dirname(os.path.abspath(__file__))
|
|
101
110
|
# change from dir like: /home/xxx/agora_rtc/agora/rtc/agora_sdk to
|
|
@@ -122,11 +131,28 @@ def _check_download_and_extract_sdk():
|
|
|
122
131
|
#fusion version: 20251023
|
|
123
132
|
|
|
124
133
|
url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.32-20250829_160340-860733-aed_20251107_1642.zip"
|
|
134
|
+
#20251110 Fusion version: with apm filter
|
|
135
|
+
mac_sdk="https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.30_25869_FULL_20251030_1836_953684-aed.zip"
|
|
136
|
+
linux_sdk = "https://download.agora.io/sdk/release/agora_rtc_sdk_x86_64-linux-gnu-v4.4.32.150_26715_SERVER_20251030_1807-aed.zip"
|
|
137
|
+
|
|
138
|
+
linux_sdk = "https://download.agora.io/sdk/release/agora_rtc_sdk_x86_64-linux-gnu-Agora_Native_SDK_for_Linux_x64_zhourui_26895_SERVER_20251121_1628_987405_20251021_1427-3a.zip"
|
|
139
|
+
mac_sdk="https://download.agora.io/sdk/release/agora_sdk_mac_Agora_Native_SDK_for_Mac_zhourui_26101_FULL_20251121_2135_987705_20251021_1427-3a.zip"
|
|
140
|
+
|
|
141
|
+
linux_sdk="https://download.agora.io/sdk/release/agora_rtc_sdk_x86_64-linux-gnu-v4.4.32.154_26982_SERVER_20251210_1745_994155_20251021_1427-3a.zip"
|
|
142
|
+
mac_sdk="https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.32.154_26308_FULL_20251210_1756_994156_20251021_1427-3a.zip"
|
|
143
|
+
|
|
125
144
|
|
|
145
|
+
|
|
126
146
|
|
|
127
|
-
|
|
147
|
+
linux_libfile_path = os.path.join(sdk_library_dir, "libagora_rtc_sdk.so")
|
|
148
|
+
mac_libfile_path = os.path.join(sdk_library_dir, "libAgoraRtcKit.dylib")
|
|
149
|
+
linux_md5 = "e89043f0db667c207d9308d3515a67ed"
|
|
150
|
+
mac_md5 = "f63e8af2047a53643a1ceb0a4b24b802"
|
|
151
|
+
|
|
128
152
|
#rtc_md5 = "7031dd10d1681cd88fd89d68c5b54282"
|
|
129
|
-
|
|
153
|
+
url = linux_sdk
|
|
154
|
+
rtc_md5 = linux_md5
|
|
155
|
+
rtc_libfile_path = linux_libfile_path
|
|
130
156
|
if sys.platform == 'darwin':
|
|
131
157
|
#url = "https://download.agora.io/sdk/release/agora_rtc_sdk_mac_rel.v4.4.30_22472_FULL_20241024_1224_398653.zip"
|
|
132
158
|
# version 2.2.0 for mac
|
|
@@ -134,13 +160,12 @@ def _check_download_and_extract_sdk():
|
|
|
134
160
|
#url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.32_24915_FULL_20250715_1710_791284.zip"
|
|
135
161
|
#url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.32_25418_FULL_20250829_1647_860754.zip"
|
|
136
162
|
#20251023 Fusion version: one sdk package include rtc and rtm
|
|
137
|
-
url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.32_25418_FULL_20250829_1647_860754-aed_20251107_1639.zip"
|
|
138
|
-
|
|
139
|
-
|
|
163
|
+
#url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.32_25418_FULL_20250829_1647_860754-aed_20251107_1639.zip"
|
|
164
|
+
url = mac_sdk
|
|
140
165
|
|
|
141
|
-
rtc_libfile_path =
|
|
166
|
+
rtc_libfile_path = mac_libfile_path
|
|
142
167
|
#rtc_md5 = "ca3ca14f9e2b7d97eb2594d1f32dab9f"
|
|
143
|
-
rtc_md5 =
|
|
168
|
+
rtc_md5 = mac_md5
|
|
144
169
|
if arch == "aarch64" and sys.platform == 'linux':
|
|
145
170
|
#url = "https://download.agora.io/sdk/release/Agora-RTC-aarch64-linux-gnu-v4.4.31-20250307_175457-603878.zip"
|
|
146
171
|
#url = "https://download.agora.io/sdk/release/Agora-RTC-aarch64-linux-gnu-v4.4.32-20250425_150503-675674.zip"
|
|
@@ -148,6 +173,7 @@ def _check_download_and_extract_sdk():
|
|
|
148
173
|
url = "https://download.agora.io/sdk/release/Agora-RTC-aarch64-linux-gnu-v4.4.32-20251009_145437-921455_20251023_1538.zip"
|
|
149
174
|
rtc_md5 = "5c002f25d2b381e353082da4f835b4f2"
|
|
150
175
|
|
|
176
|
+
'''
|
|
151
177
|
is_file_exist = os.path.exists(rtc_libfile_path)
|
|
152
178
|
if is_file_exist:
|
|
153
179
|
md5_value = get_file_md5(rtc_libfile_path)
|
|
@@ -155,8 +181,15 @@ def _check_download_and_extract_sdk():
|
|
|
155
181
|
md5_value = ""
|
|
156
182
|
if md5_value == rtc_md5:
|
|
157
183
|
return
|
|
184
|
+
'''
|
|
185
|
+
is_file_exist = os.path.exists(rtc_libfile_path)
|
|
186
|
+
version_url = _get_url_from_version_file(os.path.join(sdk_root_dir, "version.txt"))
|
|
187
|
+
if version_url == url and is_file_exist:
|
|
188
|
+
return
|
|
189
|
+
|
|
190
|
+
#change from md5 check to url check
|
|
158
191
|
|
|
159
|
-
logger.error(f"missing agora sdk, now download it, please wait for a while...: {rtc_libfile_path} {
|
|
192
|
+
logger.error(f"missing agora sdk, now download it, please wait for a while...: {rtc_libfile_path} {version_url} {url} {is_file_exist}")
|
|
160
193
|
if os.path.exists(sdk_library_dir):
|
|
161
194
|
os.system(f"rm -rf {sdk_library_dir}")
|
|
162
195
|
os.makedirs(sdk_library_dir, exist_ok=True)
|
|
@@ -176,6 +209,9 @@ def _check_download_and_extract_sdk():
|
|
|
176
209
|
|
|
177
210
|
if os.path.exists(zip_path):
|
|
178
211
|
os.remove(zip_path)
|
|
212
|
+
#write version url to version.txt
|
|
213
|
+
with open(os.path.join(sdk_root_dir, "version.txt"), "w") as f:
|
|
214
|
+
f.write(url)
|
|
179
215
|
logger.error("download done, continue...")
|
|
180
216
|
|
|
181
217
|
|
|
@@ -198,5 +234,6 @@ else:
|
|
|
198
234
|
if not os.path.exists(rtc_libfile_path):
|
|
199
235
|
logger.error(f"library {rtc_libfile_path} not found")
|
|
200
236
|
sys.exit(1)
|
|
201
|
-
|
|
202
|
-
|
|
237
|
+
|
|
238
|
+
# Explicitly export these variables to ensure that submodules can import them
|
|
239
|
+
__all__ = ['sdk_library_dir', 'sdk_rtc_dir', 'sdk_rtm_dir', 'sdk_root_dir']
|
|
@@ -22,11 +22,17 @@ try:
|
|
|
22
22
|
if sys.platform == 'darwin':
|
|
23
23
|
lib_agora_rtc_path = os.path.join(lib_dir, 'libAgoraRtcKit.dylib')
|
|
24
24
|
agora_lib = ctypes.CDLL(lib_agora_rtc_path)
|
|
25
|
+
ctypes.CDLL(os.path.join(lib_dir, 'libAgoraAiNoiseSuppressionExtension.dylib'))
|
|
25
26
|
|
|
26
27
|
elif sys.platform == 'linux':
|
|
27
28
|
lib_agora_rtc_path = os.path.join(lib_dir, 'libagora_rtc_sdk.so')
|
|
28
29
|
ctypes.CDLL(os.path.join(lib_dir, 'libagora-fdkaac.so'))
|
|
30
|
+
#ctypes.CDLL(os.path.join(lib_dir, 'libagora_ai_noise_suppression_extension.so'))
|
|
31
|
+
ctypes.CDLL(os.path.join(lib_dir, 'libagora-ffmpeg.so'))
|
|
32
|
+
ctypes.CDLL(os.path.join(lib_dir, 'libagora-soundtouch.so'))
|
|
29
33
|
agora_lib = ctypes.CDLL(lib_agora_rtc_path)
|
|
34
|
+
# should load it or the ains can not work
|
|
35
|
+
ctypes.CDLL(os.path.join(lib_dir, 'libagora_ai_noise_suppression_extension.so'))
|
|
30
36
|
except OSError as e:
|
|
31
37
|
logger.error(f"Error loading the library: {e}")
|
|
32
38
|
logger.error(f"Attempted to load from: {lib_agora_rtc_path}")
|
|
@@ -1368,4 +1368,49 @@ class CapabilitiesItemMapInner(ctypes.Structure):
|
|
|
1368
1368
|
return CapabilitiesItemMap(
|
|
1369
1369
|
item=self.item,
|
|
1370
1370
|
size=self.size
|
|
1371
|
-
)
|
|
1371
|
+
)
|
|
1372
|
+
|
|
1373
|
+
class AudioSinkWantesInner(ctypes.Structure):
|
|
1374
|
+
_fields_ = [
|
|
1375
|
+
("samples_per_sec", ctypes.c_int),
|
|
1376
|
+
("channels", ctypes.c_uint32),
|
|
1377
|
+
]
|
|
1378
|
+
pass
|
|
1379
|
+
class AudioLabelInner(ctypes.Structure):
|
|
1380
|
+
_fields_ = [
|
|
1381
|
+
("far_filed_flag", ctypes.c_int),
|
|
1382
|
+
("rms", ctypes.c_int),
|
|
1383
|
+
("voice_prob", ctypes.c_int),
|
|
1384
|
+
("music_prob", ctypes.c_int),
|
|
1385
|
+
("pitch", ctypes.c_int),
|
|
1386
|
+
]
|
|
1387
|
+
class AudioPcmFrameInner(ctypes.Structure):
|
|
1388
|
+
_fields_ = [
|
|
1389
|
+
("capture_timestamp", ctypes.c_uint32),
|
|
1390
|
+
("samples_per_channel", ctypes.c_uint32),
|
|
1391
|
+
("sample_rate_hz", ctypes.c_int),
|
|
1392
|
+
("num_channels", ctypes.c_uint32),
|
|
1393
|
+
("bytes_per_sample", ctypes.c_uint32),
|
|
1394
|
+
("data", ctypes.c_int16*3840),
|
|
1395
|
+
("audio_label", AudioLabelInner),
|
|
1396
|
+
]
|
|
1397
|
+
def get(self):
|
|
1398
|
+
return AudioFrame(
|
|
1399
|
+
type=0,
|
|
1400
|
+
samples_per_channel=self.samples_per_channel,
|
|
1401
|
+
bytes_per_sample=self.bytes_per_sample,
|
|
1402
|
+
channels=self.num_channels,
|
|
1403
|
+
samples_per_sec=self.sample_rate_hz,
|
|
1404
|
+
buffer=bytearray(ctypes.string_at(self.data, self.samples_per_channel * self.bytes_per_sample * self.num_channels)),
|
|
1405
|
+
render_time_ms=self.capture_timestamp,
|
|
1406
|
+
avsync_type=0,
|
|
1407
|
+
presentation_ms=0,
|
|
1408
|
+
audio_track_number=0,
|
|
1409
|
+
rtp_timestamp=0,
|
|
1410
|
+
far_field_flag=self.audio_label.far_filed_flag,
|
|
1411
|
+
rms=self.audio_label.rms,
|
|
1412
|
+
voice_prob=self.audio_label.voice_prob,
|
|
1413
|
+
music_prob=self.audio_label.music_prob,
|
|
1414
|
+
pitch=self.audio_label.pitch
|
|
1415
|
+
)
|
|
1416
|
+
pass
|
|
@@ -186,6 +186,8 @@ class RTCLocalUserObserverInner(ctypes.Structure):
|
|
|
186
186
|
def _on_user_audio_track_subscribed(self, local_user_handle, user_id, remote_audio_track_handle):
|
|
187
187
|
logger.debug(f"LocalUserCB _on_user_audio_track_subscribed: {local_user_handle}, {user_id}, {remote_audio_track_handle}")
|
|
188
188
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
189
|
+
#add apm filter for remote audio track
|
|
190
|
+
self.local_user._set_apm_filter_properties(remote_audio_track_handle,user_id_str)
|
|
189
191
|
# note: this is a pointer to agora::rtc::IRemoteAudioTrack
|
|
190
192
|
remote_audio_track = RemoteAudioTrack(remote_audio_track_handle, user_id_str)
|
|
191
193
|
# map to localuser to save reference
|
|
@@ -297,6 +297,63 @@ class VideoFrame():
|
|
|
297
297
|
alpha_buffer: bytearray = None
|
|
298
298
|
alpha_mode: int = 0
|
|
299
299
|
|
|
300
|
+
@dataclass(kw_only=True)
|
|
301
|
+
class AiNsConfig:
|
|
302
|
+
ns_enabled: bool = True
|
|
303
|
+
ai_ns_enabled: bool = True
|
|
304
|
+
ai_ns_model_pref: int = 10
|
|
305
|
+
nsng_alg_route: int = 12
|
|
306
|
+
nsng_predef_agg: int = 11
|
|
307
|
+
@dataclass(kw_only=True)
|
|
308
|
+
class AiAecConfig:
|
|
309
|
+
enabled: bool = False
|
|
310
|
+
split_srate_for_48k: int = 16000
|
|
311
|
+
|
|
312
|
+
@dataclass(kw_only=True)
|
|
313
|
+
class BghvsCConfig:
|
|
314
|
+
enabled: bool = True
|
|
315
|
+
vad_thr: float = 0.8
|
|
316
|
+
|
|
317
|
+
@dataclass(kw_only=True)
|
|
318
|
+
class AgcConfig:
|
|
319
|
+
enabled: bool = False
|
|
320
|
+
|
|
321
|
+
@dataclass(kw_only=True)
|
|
322
|
+
class APMConfig:
|
|
323
|
+
ai_ns_config: AiNsConfig = field(default_factory=AiNsConfig)
|
|
324
|
+
ai_aec_config: AiAecConfig = field(default_factory=AiAecConfig)
|
|
325
|
+
bghvs_c_config: BghvsCConfig = field(default_factory=BghvsCConfig)
|
|
326
|
+
agc_config: AgcConfig = field(default_factory=AgcConfig)
|
|
327
|
+
enable_dump: bool = False
|
|
328
|
+
|
|
329
|
+
def _to_json_string(self):
|
|
330
|
+
import json
|
|
331
|
+
config_dict = {
|
|
332
|
+
"aec": {
|
|
333
|
+
"enabled": self.ai_aec_config.enabled,
|
|
334
|
+
"split_srate_for_48k": self.ai_aec_config.split_srate_for_48k
|
|
335
|
+
},
|
|
336
|
+
"bghvs": {
|
|
337
|
+
"enabled": self.bghvs_c_config.enabled,
|
|
338
|
+
"vadThr": self.bghvs_c_config.vad_thr
|
|
339
|
+
},
|
|
340
|
+
"agc": {
|
|
341
|
+
"enabled": self.agc_config.enabled
|
|
342
|
+
},
|
|
343
|
+
"ans": {
|
|
344
|
+
"enabled": self.ai_ns_config.ns_enabled
|
|
345
|
+
},
|
|
346
|
+
"sf_st_cfg": {
|
|
347
|
+
"enabled": self.ai_ns_config.ai_ns_enabled,
|
|
348
|
+
"ainsModelPref": self.ai_ns_config.ai_ns_model_pref
|
|
349
|
+
},
|
|
350
|
+
"sf_ext_cfg": {
|
|
351
|
+
"nsngAlgRoute": self.ai_ns_config.nsng_alg_route,
|
|
352
|
+
"nsngPredefAgg": self.ai_ns_config.nsng_predef_agg
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return json.dumps(config_dict, separators=(',', ':'))
|
|
356
|
+
|
|
300
357
|
|
|
301
358
|
@dataclass(kw_only=True)
|
|
302
359
|
class AgoraServiceConfig:
|
|
@@ -324,6 +381,11 @@ class AgoraServiceConfig:
|
|
|
324
381
|
log_file_size_kb: int = 5*1024
|
|
325
382
|
data_dir: str = ""
|
|
326
383
|
config_dir: str = "" #format like: "./agora_rtc_log"
|
|
384
|
+
#20251110 Fusion version: with apm filter
|
|
385
|
+
enable_apm: bool = False
|
|
386
|
+
apm_config: APMConfig = None
|
|
387
|
+
|
|
388
|
+
|
|
327
389
|
|
|
328
390
|
|
|
329
391
|
@dataclass(kw_only=True)
|
|
@@ -566,4 +628,4 @@ class CapabilityItemMap:
|
|
|
566
628
|
@dataclass(kw_only=True)
|
|
567
629
|
class Capabilities:
|
|
568
630
|
item_map: CapabilityItemMap = None
|
|
569
|
-
capability_type: int = 0
|
|
631
|
+
capability_type: int = 0
|
|
@@ -65,6 +65,14 @@ agora_service_set_log_filter = agora_lib.agora_service_set_log_filter
|
|
|
65
65
|
agora_service_set_log_filter.restype = AGORA_API_C_INT
|
|
66
66
|
agora_service_set_log_filter.argtypes = [AGORA_HANDLE, ctypes.c_uint]
|
|
67
67
|
|
|
68
|
+
agora_audio_track_enable_audio_filter = agora_lib.agora_audio_track_enable_audio_filter
|
|
69
|
+
agora_audio_track_enable_audio_filter.restype = ctypes.c_int
|
|
70
|
+
agora_audio_track_enable_audio_filter.argtypes = [AGORA_HANDLE, ctypes.c_char_p, ctypes.c_int, ctypes.c_int]
|
|
71
|
+
|
|
72
|
+
agora_audio_track_set_filter_property = agora_lib.agora_audio_track_set_filter_property
|
|
73
|
+
agora_audio_track_set_filter_property.restype = ctypes.c_int
|
|
74
|
+
agora_audio_track_set_filter_property.argtypes = [AGORA_HANDLE, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p, ctypes.c_int]
|
|
75
|
+
|
|
68
76
|
|
|
69
77
|
class AgoraService:
|
|
70
78
|
def __init__(self) -> None:
|
|
@@ -74,6 +82,8 @@ class AgoraService:
|
|
|
74
82
|
self.inited = False
|
|
75
83
|
#default to None, and never create it manually by developer from ver2.3.0
|
|
76
84
|
self.media_node_factory = None
|
|
85
|
+
self.enable_apm = False
|
|
86
|
+
self.apm_config = None
|
|
77
87
|
|
|
78
88
|
def initialize(self, config: AgoraServiceConfig):
|
|
79
89
|
if self.inited == True:
|
|
@@ -101,7 +111,20 @@ class AgoraService:
|
|
|
101
111
|
|
|
102
112
|
# force audio vad v2 to be enabled
|
|
103
113
|
agora_parameter.set_parameters("{\"che.audio.label.enable\": true}")
|
|
104
|
-
|
|
114
|
+
# for apm filter: to enable apm filter
|
|
115
|
+
generator = "audio_processing_remote_playback"
|
|
116
|
+
cgenerator = generator.encode('utf-8')
|
|
117
|
+
ctrak = ctypes.c_char_p(None)
|
|
118
|
+
result = agora_service_enable_extension(self.service_handle, cprovider, cgenerator, ctrak, 1)
|
|
119
|
+
if result != 0:
|
|
120
|
+
logger.error(f"Failed to enable audio processing remote playback filter. Error code: {result}")
|
|
121
|
+
if config.enable_apm:
|
|
122
|
+
generator = "audio_processing_pcm_source"
|
|
123
|
+
cgenerator = generator.encode('utf-8')
|
|
124
|
+
result = agora_service_enable_extension(self.service_handle, cprovider, cgenerator, ctrak, 1)
|
|
125
|
+
if result != 0:
|
|
126
|
+
logger.error(f"Failed to enable audio processing pcm source filter. Error code: {result}")
|
|
127
|
+
|
|
105
128
|
#versio 2.2.0 for callback when muted
|
|
106
129
|
if config.should_callbck_when_muted > 0:
|
|
107
130
|
agora_parameter.set_parameters("{\"rtc.audio.enable_user_silence_packet\": true}")
|
|
@@ -112,6 +135,17 @@ class AgoraService:
|
|
|
112
135
|
'''
|
|
113
136
|
agora_parameter.set_parameters("{\"che.video.min_enc_level\": 0}")
|
|
114
137
|
|
|
138
|
+
#keep & save apm config
|
|
139
|
+
self.enable_apm = config.enable_apm
|
|
140
|
+
if self.enable_apm:
|
|
141
|
+
if config.apm_config is None:
|
|
142
|
+
self.apm_config = APMConfig()
|
|
143
|
+
else:
|
|
144
|
+
self.apm_config = config.apm_config
|
|
145
|
+
else:
|
|
146
|
+
self.apm_config = None
|
|
147
|
+
|
|
148
|
+
|
|
115
149
|
return result
|
|
116
150
|
|
|
117
151
|
def release(self):
|
|
@@ -210,3 +244,27 @@ class AgoraService:
|
|
|
210
244
|
else:
|
|
211
245
|
logger.error(f"Failed to set log file. Error code: {result}")
|
|
212
246
|
return result
|
|
247
|
+
#apm related:
|
|
248
|
+
#apm related api
|
|
249
|
+
def _get_audio_filter_position(is_local_track: bool = False) -> int:
|
|
250
|
+
if is_local_track:
|
|
251
|
+
return 3
|
|
252
|
+
return 2
|
|
253
|
+
|
|
254
|
+
def _enable_audio_filter_by_track(track: any, name: str, enable: bool, is_local_track: bool) -> int:
|
|
255
|
+
if track is None:
|
|
256
|
+
return -1000
|
|
257
|
+
c_name = ctypes.c_char_p(name.encode('utf-8'))
|
|
258
|
+
c_enable = ctypes.c_int(0)
|
|
259
|
+
if enable:
|
|
260
|
+
c_enable = ctypes.c_int(1)
|
|
261
|
+
position = _get_audio_filter_position(is_local_track)
|
|
262
|
+
return int(agora_audio_track_enable_audio_filter(track, c_name, c_enable, ctypes.c_int(position)))
|
|
263
|
+
def _set_filter_property_by_track(track: any, name: str, key: str, value: str, is_local_track: bool) -> int:
|
|
264
|
+
if track is None:
|
|
265
|
+
return -1000
|
|
266
|
+
c_name = ctypes.c_char_p(name.encode('utf-8'))
|
|
267
|
+
c_key = ctypes.c_char_p(key.encode('utf-8'))
|
|
268
|
+
c_value = ctypes.c_char_p(value.encode('utf-8'))
|
|
269
|
+
position = _get_audio_filter_position(is_local_track)
|
|
270
|
+
return int(agora_audio_track_set_filter_property(track, c_name, c_key, c_value, ctypes.c_int(position)))
|