agora-python-server-sdk 2.2.4__tar.gz → 2.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.

Potentially problematic release.


This version of agora-python-server-sdk might be problematic. Click here for more details.

Files changed (43) hide show
  1. {agora_python_server_sdk-2.2.4/agora_python_server_sdk.egg-info → agora_python_server_sdk-2.3.0}/PKG-INFO +166 -6
  2. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/README.md +165 -5
  3. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/__init__.py +8 -4
  4. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/_ctypes_handle/_ctypes_data.py +129 -9
  5. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/_ctypes_handle/_local_user_observer.py +2 -2
  6. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/_ctypes_handle/_rtc_connection_observer.py +44 -1
  7. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/agora_base.py +61 -13
  8. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/agora_service.py +27 -21
  9. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/audio_encoded_frame_sender.py +12 -0
  10. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/audio_pcm_data_sender.py +5 -3
  11. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/local_user.py +27 -15
  12. agora_python_server_sdk-2.3.0/agora/rtc/rtc_connection.py +519 -0
  13. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/rtc_connection_observer.py +20 -0
  14. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/utils/audio_consumer.py +41 -0
  15. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/video_encoded_image_sender.py +8 -0
  16. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0/agora_python_server_sdk.egg-info}/PKG-INFO +166 -6
  17. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/setup.py +19 -2
  18. agora_python_server_sdk-2.2.4/agora/rtc/rtc_connection.py +0 -164
  19. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/MANIFEST.in +0 -0
  20. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/_ctypes_handle/_audio_frame_observer.py +0 -0
  21. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/_ctypes_handle/_video_encoded_frame_observer.py +0 -0
  22. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/_ctypes_handle/_video_frame_observer.py +0 -0
  23. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/_utils/globals.py +0 -0
  24. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/agora_parameter.py +0 -0
  25. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/audio_frame_observer.py +0 -0
  26. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/audio_sessionctrl.py +0 -0
  27. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/audio_vad_manager.py +0 -0
  28. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/local_audio_track.py +0 -0
  29. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/local_user_observer.py +0 -0
  30. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/local_video_track.py +0 -0
  31. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/media_node_factory.py +0 -0
  32. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/remote_audio_track.py +0 -0
  33. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/remote_video_track.py +0 -0
  34. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/utils/vad_dump.py +0 -0
  35. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/video_encoded_frame_observer.py +0 -0
  36. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/video_frame_observer.py +0 -0
  37. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/video_frame_sender.py +0 -0
  38. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora/rtc/voice_detection.py +0 -0
  39. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora_python_server_sdk.egg-info/SOURCES.txt +0 -0
  40. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora_python_server_sdk.egg-info/dependency_links.txt +0 -0
  41. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/agora_python_server_sdk.egg-info/top_level.txt +0 -0
  42. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/pyproject.toml +0 -0
  43. {agora_python_server_sdk-2.2.4 → agora_python_server_sdk-2.3.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: agora_python_server_sdk
3
- Version: 2.2.4
3
+ Version: 2.3.0
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
@@ -19,9 +19,19 @@ Description-Content-Type: text/markdown
19
19
  - The examples are provided as very simple demonstrations and are not recommended for use in production environments.
20
20
 
21
21
  # Very Important Notice !!!
22
- - A process can only have one instance.
22
+ - A process can only have one instance,and the instance created in process startup is the global instance,and released in process shutdown.
23
23
  - An instance can have multiple connections.
24
24
  - In all observers or callbacks, you must not call the SDK's own APIs, nor perform CPU-intensive tasks in the callbacks; data copying is allowed.
25
+ - supported video codec:
26
+ - H264: support both encoding and decoding
27
+ - VP8: support both encoding and decoding
28
+ - VP9: support both encoding and decoding
29
+ - H265: only decoding is supported, encoding willl support in the future
30
+ - AV1: both encoding and decoding are suported but if video image's solution is less than 360p, the codec will be changed to H264
31
+ - if you want to recive the encoded video data:
32
+ - set: video_subscription_options.encodedFrameOnly = 1
33
+ - and then register: set_encoded_video_frame_observer
34
+
25
35
 
26
36
  # Required Operating Systems and Python Versions
27
37
  - Supported Linux versions:
@@ -50,6 +60,157 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
50
60
  ```
51
61
 
52
62
  # Change log
63
+ #2025.09.01 release 2.3.0
64
+
65
+ Overview
66
+
67
+ Agora Python SDK version 2.3.0 introduces significant enhancements for real-time audio and video communication, with particular optimizations for AI server scenarios. This release includes API improvements, automation of previously manual processes, and increased flexibility in connection configuration.
68
+
69
+ New Features
70
+
71
+ 1. AudioScenarioAiServer Support
72
+
73
+ • Added support for the AudioScenarioAiServer scenario type, now set as the default AudioScenario.
74
+
75
+ • Enables configuration of different scenarios and profiles for connections within the same process.
76
+
77
+ • Important: When using AI server scenario, client-side must use AIClient scenario to avoid audio abnormalities. Please consult Agora support for SDK versions supporting AIClient scenario.
78
+
79
+ 2. Enhanced Connection Configuration
80
+
81
+ • Introduced PublishConfigure parameter in connection creation for setting:
82
+
83
+ • Scenario and profile configurations
84
+
85
+ • Audio/Video publication settings
86
+
87
+ • Other publication parameters
88
+
89
+ • Added multiple observer registration methods to connections:
90
+
91
+ • RegisterLocalUserObserver
92
+
93
+ • RegisterAudioFrameObserver
94
+
95
+ • RegisterVideoFrameObserver
96
+
97
+ • RegisterVideoEncodedFrameObserver
98
+
99
+ 3. Stream Management Improvements
100
+
101
+ • Added publication control methods:
102
+
103
+ • PublishAudio/UnpublishAudio
104
+
105
+ • PublishVideo/UnpublishVideo
106
+
107
+ • Added data pushing methods:
108
+
109
+ • PushAudioPcmData/PushAudioEncodedData
110
+
111
+ • PushVideoFrame/PushVideoEncodedData
112
+
113
+ • Added InterruptAudio method for supporting interruption functionality
114
+
115
+ • Added IsPushToRTCCompleted method for checking push status
116
+
117
+ • Added SendAudioMetaData method for audio metadata transmission
118
+
119
+ 4. Automation Enhancements
120
+
121
+ • Eliminated manual CreateDataStream calls - now handled automatically
122
+
123
+ • Automatic observer unregistration on Release() instead of manual unregistering
124
+
125
+ • Internal handling of media node factory creation:
126
+
127
+ • No longer requires manual calls to newMediaNodeFactory
128
+
129
+ • Automatic handling of track creation (NewCustomAudioTrackPcm, NewCustomAudioTrackEncoded, NewCustomVideoTrack)
130
+
131
+ • Automatic management of audio data senders (NewAudioPcmDataSender)
132
+
133
+ Integration Process
134
+
135
+ The updated integration workflow is as follows:
136
+
137
+ 1. Initialize Agora Service (once per process startup):
138
+ config = AgoraServiceConfig()
139
+ agora_service = AgoraService()
140
+ agora_service.initialize(config)
141
+
142
+
143
+ 2. Connection Management (can be looped for multiple connections):
144
+ # Create connection with configuration
145
+ con = agora_service.create_rtc_connection(con_config, publish_config)
146
+
147
+ # Register observers
148
+ con.register_observer(conHandler)
149
+ con.register_audio_frame_observer(audioFrameObserver)
150
+ con.register_local_user_observer(localUserObserver)
151
+
152
+ # Connect and publish
153
+ con.connect(token, channelName, userId)
154
+ con.publish_audio() # or con.publish_video()
155
+
156
+ # Push data
157
+ con.push_audio_pcm_data() # or push_audio_encoded_data()
158
+ # or con.push_video_frame()/push_video_encoded_data()
159
+
160
+ # Disconnect and release
161
+ con.disconnect()
162
+ con.release()
163
+
164
+
165
+ 3. Release Agora Service (once during process termination):
166
+ agora_service.release()
167
+
168
+
169
+ Performance Recommendations
170
+
171
+ 1. For AI Scenarios:
172
+ • Use AudioScenarioAIServer for server-side applications
173
+
174
+ • Provides optimized performance with lower latency (20-30ms reduction on iPhone compared to chorus)
175
+
176
+ • Enhanced experience in weak network conditions
177
+
178
+ • Mandatory: Client must use AIClient scenario
179
+
180
+ 2. For Non-AI Scenarios:
181
+ • Consult Agora technical support for appropriate scenario configuration
182
+
183
+ • Ensure configuration matches specific business use cases
184
+
185
+ Bug Fixes
186
+
187
+ • Updated RTC SDK with 2 bug fixes
188
+
189
+ Important Notes
190
+
191
+ • Backward Compatibility: Review integration code for manual calls that are now automated
192
+
193
+ • Scenario Matching: Ensure client-server scenario compatibility (AIServer requires AIClient)
194
+
195
+ • Resource Management: Connection release now automatically handles observer unregistration
196
+
197
+ • Consult Support: For specific integration guidance and upgrade assistance, contact Agora SA
198
+
199
+ Summary of Core Changes
200
+
201
+ Before After 2.3.0
202
+
203
+ Manual CreateDataStream ✅ Automatic
204
+
205
+ Manual observer unregistration ✅ Automatic on Release()
206
+
207
+ Fixed per-process scenario ✅ Multi-scenario per process
208
+
209
+ Client/Server scenario mismatch ❗ AIClient mandatory for AI use
210
+
211
+ For detailed implementation guidance and version-specific support, please consult Agora technical support.
212
+
213
+
53
214
  ## 2025.04.28 Release 2.2.4
54
215
  -- Update: update rtc sdk from 4.4.31 to 4.4.32
55
216
  ## 2025.04.14 Release 2.2.3
@@ -69,6 +230,7 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
69
230
  - Added connection::agora_rtc_conn_enable_encryption.
70
231
  -- Additions:
71
232
  - Added connectionObserver::on_encryption_error (but not working for now, need to fix in the next monthly version 4.4.32).
233
+
72
234
  2025.02.26 Release 2.2.1
73
235
  --Update:
74
236
  ​- Reduced buffer size from ​180ms​ to ​100ms​ to minimize latency.
@@ -89,7 +251,6 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
89
251
  - Add the AudioMetaData interface: localuser::send_audio_meta_data. Done.
90
252
  - Add the OnAudioMetaDataReceived callback to localuserObserver::on_audio_meta_data_received. Done.
91
253
  -- Sample modifications.
92
-
93
254
  2024.12.17 Release 2.1.7
94
255
  --Changes:
95
256
 
@@ -117,7 +278,6 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
117
278
  -- Replaced the use of pacer with AudioConsumer for pushing PCM audio.
118
279
  - Updates:
119
280
  -- Updated the samples related to Pacer and VAD.
120
-
121
281
  ## 2024.12.03 release Version 2.1.5
122
282
  - Modifications:
123
283
  - LocalUser/audioTrack:
@@ -173,7 +333,6 @@ Fixed some bug.
173
333
  - Handle business operations.
174
334
  - When a user logs out, execute con.disconnect() and release the audio/video tracks and observers associated with the connection, but do not call con.release(); then put the connection back into the connection pool.
175
335
  - When the process exits, release the connection pool (release each con.release()), service/media_node_factory, and the connection pool (release each con.release()) to ensure resource release and optimal performance.
176
-
177
336
  ## Use of VAD
178
337
  # Source code: voice_detection.py
179
338
  # Sample code: example_audio_vad.py
@@ -204,7 +363,8 @@ Judge the value of state according to the returned state, and do corresponding p
204
363
  ### How to push the audio generated by TTS into the channel?
205
364
  # Source code: audio_consumer.py
206
365
  # Sample code: example_audio_consumer.py
207
- ### How to release resources?
366
+
367
+ ### How to release resource?
208
368
  ## 如何释放资源?
209
369
  localuser.unpublish_audio(audio_track)
210
370
  localuser.unpublish_video(video_track)
@@ -4,9 +4,19 @@
4
4
  - The examples are provided as very simple demonstrations and are not recommended for use in production environments.
5
5
 
6
6
  # Very Important Notice !!!
7
- - A process can only have one instance.
7
+ - A process can only have one instance,and the instance created in process startup is the global instance,and released in process shutdown.
8
8
  - An instance can have multiple connections.
9
9
  - In all observers or callbacks, you must not call the SDK's own APIs, nor perform CPU-intensive tasks in the callbacks; data copying is allowed.
10
+ - supported video codec:
11
+ - H264: support both encoding and decoding
12
+ - VP8: support both encoding and decoding
13
+ - VP9: support both encoding and decoding
14
+ - H265: only decoding is supported, encoding willl support in the future
15
+ - AV1: both encoding and decoding are suported but if video image's solution is less than 360p, the codec will be changed to H264
16
+ - if you want to recive the encoded video data:
17
+ - set: video_subscription_options.encodedFrameOnly = 1
18
+ - and then register: set_encoded_video_frame_observer
19
+
10
20
 
11
21
  # Required Operating Systems and Python Versions
12
22
  - Supported Linux versions:
@@ -35,6 +45,157 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
35
45
  ```
36
46
 
37
47
  # Change log
48
+ #2025.09.01 release 2.3.0
49
+
50
+ Overview
51
+
52
+ Agora Python SDK version 2.3.0 introduces significant enhancements for real-time audio and video communication, with particular optimizations for AI server scenarios. This release includes API improvements, automation of previously manual processes, and increased flexibility in connection configuration.
53
+
54
+ New Features
55
+
56
+ 1. AudioScenarioAiServer Support
57
+
58
+ • Added support for the AudioScenarioAiServer scenario type, now set as the default AudioScenario.
59
+
60
+ • Enables configuration of different scenarios and profiles for connections within the same process.
61
+
62
+ • Important: When using AI server scenario, client-side must use AIClient scenario to avoid audio abnormalities. Please consult Agora support for SDK versions supporting AIClient scenario.
63
+
64
+ 2. Enhanced Connection Configuration
65
+
66
+ • Introduced PublishConfigure parameter in connection creation for setting:
67
+
68
+ • Scenario and profile configurations
69
+
70
+ • Audio/Video publication settings
71
+
72
+ • Other publication parameters
73
+
74
+ • Added multiple observer registration methods to connections:
75
+
76
+ • RegisterLocalUserObserver
77
+
78
+ • RegisterAudioFrameObserver
79
+
80
+ • RegisterVideoFrameObserver
81
+
82
+ • RegisterVideoEncodedFrameObserver
83
+
84
+ 3. Stream Management Improvements
85
+
86
+ • Added publication control methods:
87
+
88
+ • PublishAudio/UnpublishAudio
89
+
90
+ • PublishVideo/UnpublishVideo
91
+
92
+ • Added data pushing methods:
93
+
94
+ • PushAudioPcmData/PushAudioEncodedData
95
+
96
+ • PushVideoFrame/PushVideoEncodedData
97
+
98
+ • Added InterruptAudio method for supporting interruption functionality
99
+
100
+ • Added IsPushToRTCCompleted method for checking push status
101
+
102
+ • Added SendAudioMetaData method for audio metadata transmission
103
+
104
+ 4. Automation Enhancements
105
+
106
+ • Eliminated manual CreateDataStream calls - now handled automatically
107
+
108
+ • Automatic observer unregistration on Release() instead of manual unregistering
109
+
110
+ • Internal handling of media node factory creation:
111
+
112
+ • No longer requires manual calls to newMediaNodeFactory
113
+
114
+ • Automatic handling of track creation (NewCustomAudioTrackPcm, NewCustomAudioTrackEncoded, NewCustomVideoTrack)
115
+
116
+ • Automatic management of audio data senders (NewAudioPcmDataSender)
117
+
118
+ Integration Process
119
+
120
+ The updated integration workflow is as follows:
121
+
122
+ 1. Initialize Agora Service (once per process startup):
123
+ config = AgoraServiceConfig()
124
+ agora_service = AgoraService()
125
+ agora_service.initialize(config)
126
+
127
+
128
+ 2. Connection Management (can be looped for multiple connections):
129
+ # Create connection with configuration
130
+ con = agora_service.create_rtc_connection(con_config, publish_config)
131
+
132
+ # Register observers
133
+ con.register_observer(conHandler)
134
+ con.register_audio_frame_observer(audioFrameObserver)
135
+ con.register_local_user_observer(localUserObserver)
136
+
137
+ # Connect and publish
138
+ con.connect(token, channelName, userId)
139
+ con.publish_audio() # or con.publish_video()
140
+
141
+ # Push data
142
+ con.push_audio_pcm_data() # or push_audio_encoded_data()
143
+ # or con.push_video_frame()/push_video_encoded_data()
144
+
145
+ # Disconnect and release
146
+ con.disconnect()
147
+ con.release()
148
+
149
+
150
+ 3. Release Agora Service (once during process termination):
151
+ agora_service.release()
152
+
153
+
154
+ Performance Recommendations
155
+
156
+ 1. For AI Scenarios:
157
+ • Use AudioScenarioAIServer for server-side applications
158
+
159
+ • Provides optimized performance with lower latency (20-30ms reduction on iPhone compared to chorus)
160
+
161
+ • Enhanced experience in weak network conditions
162
+
163
+ • Mandatory: Client must use AIClient scenario
164
+
165
+ 2. For Non-AI Scenarios:
166
+ • Consult Agora technical support for appropriate scenario configuration
167
+
168
+ • Ensure configuration matches specific business use cases
169
+
170
+ Bug Fixes
171
+
172
+ • Updated RTC SDK with 2 bug fixes
173
+
174
+ Important Notes
175
+
176
+ • Backward Compatibility: Review integration code for manual calls that are now automated
177
+
178
+ • Scenario Matching: Ensure client-server scenario compatibility (AIServer requires AIClient)
179
+
180
+ • Resource Management: Connection release now automatically handles observer unregistration
181
+
182
+ • Consult Support: For specific integration guidance and upgrade assistance, contact Agora SA
183
+
184
+ Summary of Core Changes
185
+
186
+ Before After 2.3.0
187
+
188
+ Manual CreateDataStream ✅ Automatic
189
+
190
+ Manual observer unregistration ✅ Automatic on Release()
191
+
192
+ Fixed per-process scenario ✅ Multi-scenario per process
193
+
194
+ Client/Server scenario mismatch ❗ AIClient mandatory for AI use
195
+
196
+ For detailed implementation guidance and version-specific support, please consult Agora technical support.
197
+
198
+
38
199
  ## 2025.04.28 Release 2.2.4
39
200
  -- Update: update rtc sdk from 4.4.31 to 4.4.32
40
201
  ## 2025.04.14 Release 2.2.3
@@ -54,6 +215,7 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
54
215
  - Added connection::agora_rtc_conn_enable_encryption.
55
216
  -- Additions:
56
217
  - Added connectionObserver::on_encryption_error (but not working for now, need to fix in the next monthly version 4.4.32).
218
+
57
219
  2025.02.26 Release 2.2.1
58
220
  --Update:
59
221
  ​- Reduced buffer size from ​180ms​ to ​100ms​ to minimize latency.
@@ -74,7 +236,6 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
74
236
  - Add the AudioMetaData interface: localuser::send_audio_meta_data. Done.
75
237
  - Add the OnAudioMetaDataReceived callback to localuserObserver::on_audio_meta_data_received. Done.
76
238
  -- Sample modifications.
77
-
78
239
  2024.12.17 Release 2.1.7
79
240
  --Changes:
80
241
 
@@ -102,7 +263,6 @@ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx
102
263
  -- Replaced the use of pacer with AudioConsumer for pushing PCM audio.
103
264
  - Updates:
104
265
  -- Updated the samples related to Pacer and VAD.
105
-
106
266
  ## 2024.12.03 release Version 2.1.5
107
267
  - Modifications:
108
268
  - LocalUser/audioTrack:
@@ -158,7 +318,6 @@ Fixed some bug.
158
318
  - Handle business operations.
159
319
  - When a user logs out, execute con.disconnect() and release the audio/video tracks and observers associated with the connection, but do not call con.release(); then put the connection back into the connection pool.
160
320
  - When the process exits, release the connection pool (release each con.release()), service/media_node_factory, and the connection pool (release each con.release()) to ensure resource release and optimal performance.
161
-
162
321
  ## Use of VAD
163
322
  # Source code: voice_detection.py
164
323
  # Sample code: example_audio_vad.py
@@ -189,7 +348,8 @@ Judge the value of state according to the returned state, and do corresponding p
189
348
  ### How to push the audio generated by TTS into the channel?
190
349
  # Source code: audio_consumer.py
191
350
  # Sample code: example_audio_consumer.py
192
- ### How to release resources?
351
+
352
+ ### How to release resource?
193
353
  ## 如何释放资源?
194
354
  localuser.unpublish_audio(audio_track)
195
355
  localuser.unpublish_video(video_track)
@@ -36,21 +36,25 @@ def _check_download_and_extract_sdk():
36
36
  #url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.30-20241024_101940-398537.zip"
37
37
  # version 2.2.0 for linux
38
38
  #url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.31-20241223_111509-491956.zip"
39
- url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.32-20250425_144419-675648.zip"
39
+ #url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.32-20250715_161625-791246.zip"
40
+ url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.32-20250829_160340-860733.zip"
41
+
40
42
 
41
43
 
42
44
  libagora_rtc_sdk_path = os.path.join(sdk_dir, "libagora_rtc_sdk.so")
43
45
  #rtc_md5 = "7031dd10d1681cd88fd89d68c5b54282"
44
- rtc_md5 = "0d6c96bbebdd9b0a84b9cdf01ba6aa7f"
46
+ rtc_md5 = "7eb8042e43246f95f188549d8711d1bf"
45
47
  if sys.platform == 'darwin':
46
48
  #url = "https://download.agora.io/sdk/release/agora_rtc_sdk_mac_rel.v4.4.30_22472_FULL_20241024_1224_398653.zip"
47
49
  # version 2.2.0 for mac
48
50
  #url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.31_23136_FULL_20241223_1245_492039.zip"
49
- url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.32_24257_FULL_20250425_1609_675722.zip"
51
+ #url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.32_24915_FULL_20250715_1710_791284.zip"
52
+ url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.32_25418_FULL_20250829_1647_860754.zip"
53
+
50
54
 
51
55
  libagora_rtc_sdk_path = os.path.join(sdk_dir, "libAgoraRtcKit.dylib")
52
56
  #rtc_md5 = "ca3ca14f9e2b7d97eb2594d1f32dab9f"
53
- rtc_md5 = "358be32c5dfc72192402cf49838ea942"
57
+ rtc_md5 = "df0ec3b5073d17dee76cc4d97c13699a"
54
58
  if arch == "aarch64" and sys.platform == 'linux':
55
59
  #url = "https://download.agora.io/sdk/release/Agora-RTC-aarch64-linux-gnu-v4.4.31-20250307_175457-603878.zip"
56
60
  url = "https://download.agora.io/sdk/release/Agora-RTC-aarch64-linux-gnu-v4.4.32-20250425_150503-675674.zip"
@@ -1000,7 +1000,6 @@ class RemoteAudioTrackStatsInner(ctypes.Structure):
1000
1000
  stats.received_bytes
1001
1001
  )
1002
1002
 
1003
-
1004
1003
  class EncodedAudioFrameInfoInner(ctypes.Structure):
1005
1004
  _fields_ = [
1006
1005
  ('speech', ctypes.c_int),
@@ -1008,7 +1007,8 @@ class EncodedAudioFrameInfoInner(ctypes.Structure):
1008
1007
  ('sample_rate_hz', ctypes.c_int),
1009
1008
  ('samples_per_channel', ctypes.c_int),
1010
1009
  ('send_even_if_empty', ctypes.c_int),
1011
- ('number_of_channels', ctypes.c_int)
1010
+ ('number_of_channels', ctypes.c_int),
1011
+ ('capture_time_ms', ctypes.c_int64)
1012
1012
  ]
1013
1013
 
1014
1014
  @staticmethod
@@ -1019,7 +1019,8 @@ class EncodedAudioFrameInfoInner(ctypes.Structure):
1019
1019
  info.sample_rate,
1020
1020
  info.samples_per_channel,
1021
1021
  info.send_even_if_empty,
1022
- info.number_of_channels
1022
+ info.number_of_channels,
1023
+ info.capture_time_ms
1023
1024
  )
1024
1025
 
1025
1026
 
@@ -1067,6 +1068,10 @@ class AudioFrameInner(ctypes.Structure):
1067
1068
  ("buffer", ctypes.c_void_p),
1068
1069
  ("render_time_ms", ctypes.c_int64),
1069
1070
  ("avsync_type", ctypes.c_int),
1071
+ ("presentation_ms", ctypes.c_int64),
1072
+ ("audio_track_number", ctypes.c_int),
1073
+ ("rtp_timestamp", ctypes.c_uint32),
1074
+
1070
1075
  ("far_field_flag", ctypes.c_int),
1071
1076
  ("rms", ctypes.c_int),
1072
1077
  ("voice_prob", ctypes.c_int),
@@ -1084,6 +1089,9 @@ class AudioFrameInner(ctypes.Structure):
1084
1089
  buffer=bytearray(ctypes.string_at(self.buffer, self.samples_per_channel * self.bytes_per_sample * self.channels)),
1085
1090
  render_time_ms=self.render_time_ms,
1086
1091
  avsync_type=self.avsync_type,
1092
+ presentation_ms=self.presentation_ms,
1093
+ audio_track_number=self.audio_track_number,
1094
+ rtp_timestamp=self.rtp_timestamp,
1087
1095
  far_field_flag=self.far_field_flag,
1088
1096
  rms=self.rms,
1089
1097
  voice_prob=self.voice_prob,
@@ -1102,6 +1110,9 @@ class AudioFrameInner(ctypes.Structure):
1102
1110
  ctypes.cast(frame.buffer, ctypes.c_void_p),
1103
1111
  frame.render_time_ms,
1104
1112
  frame.avsync_type,
1113
+ frame.presentation_ms,
1114
+ frame.audio_track_number,
1115
+ frame.rtp_timestamp,
1105
1116
  frame.far_field_flag,
1106
1117
  frame.rms,
1107
1118
  frame.voice_prob,
@@ -1133,6 +1144,11 @@ class AgoraServiceConfigInner(ctypes.Structure):
1133
1144
 
1134
1145
  ('use_string_uid', ctypes.c_int),
1135
1146
  ('domain_limit', ctypes.c_int),
1147
+ ('log_level', ctypes.c_int),
1148
+ ('log_file_path', ctypes.c_char_p),
1149
+ ('log_file_size_kb', ctypes.c_uint32),
1150
+ ('data_dir', ctypes.c_char_p),
1151
+ ('config_dir', ctypes.c_char_p),
1136
1152
  ]
1137
1153
 
1138
1154
  def get(self):
@@ -1146,7 +1162,12 @@ class AgoraServiceConfigInner(ctypes.Structure):
1146
1162
  channel_profile=self.channel_profile,
1147
1163
  audio_scenario=self.audio_scenario,
1148
1164
  use_string_uid=self.use_string_uid,
1149
- domain_limit=self.domain_limit
1165
+ domain_limit=self.domain_limit,
1166
+ log_level=self.log_level,
1167
+ log_path=self.log_file_path.decode() if self.log_file_path else "",
1168
+ log_file_size_kb=self.log_file_size_kb,
1169
+ data_dir=self.data_dir.decode() if self.data_dir else "",
1170
+ config_dir=self.config_dir.decode() if self.config_dir else ""
1150
1171
  )
1151
1172
 
1152
1173
  @staticmethod
@@ -1156,12 +1177,17 @@ class AgoraServiceConfigInner(ctypes.Structure):
1156
1177
  config.enable_audio_device,
1157
1178
  config.enable_video,
1158
1179
  config.context,
1159
- config.appid.encode(),
1180
+ config.appid.encode() if config.appid else None,
1160
1181
  config.area_code,
1161
1182
  config.channel_profile,
1162
1183
  config.audio_scenario,
1163
1184
  config.use_string_uid,
1164
- config.domain_limit
1185
+ config.domain_limit,
1186
+ config.log_level,
1187
+ config.log_path.encode() if config.log_path else None,
1188
+ config.log_file_size_kb,
1189
+ config.data_dir.encode() if config.data_dir else None,
1190
+ config.config_dir.encode() if config.config_dir else None
1165
1191
  )
1166
1192
 
1167
1193
 
@@ -1177,7 +1203,8 @@ class EncodedVideoFrameInfoInner(ctypes.Structure):
1177
1203
  ("capture_time_ms", ctypes.c_int64),
1178
1204
  ("decode_time_ms", ctypes.c_int64),
1179
1205
  ("uid", ctypes.c_uint),
1180
- ("stream_type", ctypes.c_int)
1206
+ ("stream_type", ctypes.c_int),
1207
+ ("presentation_ms", ctypes.c_int64)
1181
1208
  ]
1182
1209
 
1183
1210
  def get(self):
@@ -1192,7 +1219,8 @@ class EncodedVideoFrameInfoInner(ctypes.Structure):
1192
1219
  capture_time_ms=self.capture_time_ms,
1193
1220
  decode_time_ms=self.decode_time_ms,
1194
1221
  uid=self.uid,
1195
- stream_type=self.stream_type
1222
+ stream_type=self.stream_type,
1223
+ presentation_ms=self.presentation_ms
1196
1224
  )
1197
1225
 
1198
1226
  @staticmethod
@@ -1208,7 +1236,8 @@ class EncodedVideoFrameInfoInner(ctypes.Structure):
1208
1236
  info.capture_time_ms,
1209
1237
  info.decode_time_ms,
1210
1238
  info.uid,
1211
- info.stream_type
1239
+ info.stream_type,
1240
+ info.presentation_ms
1212
1241
  )
1213
1242
 
1214
1243
 
@@ -1249,3 +1278,94 @@ class EncryptionConfigInner(ctypes.Structure):
1249
1278
  encryption_key,
1250
1279
  encryption_kdf_salt
1251
1280
  )
1281
+
1282
+
1283
+ class CapabilityItemInner(ctypes.Structure):
1284
+ _fields_ = [
1285
+ ("id", ctypes.c_uint8),
1286
+ ("name", ctypes.c_char_p)
1287
+ ]
1288
+
1289
+ def get(self):
1290
+ return CapabilityItem(
1291
+ id=self.id,
1292
+ name=self.name.decode() if self.name else ""
1293
+ )
1294
+
1295
+ @staticmethod
1296
+ def create(item: CapabilityItem) -> 'CapabilityItemInner':
1297
+ return CapabilityItemInner(
1298
+ item.id,
1299
+ item.name.encode() if item.name else None
1300
+ )
1301
+
1302
+
1303
+ class CapabilityItemMapInner(ctypes.Structure):
1304
+ _fields_ = [
1305
+ ("item", ctypes.POINTER(CapabilityItemInner)),
1306
+ ("size", ctypes.c_size_t)
1307
+ ]
1308
+
1309
+ def get(self):
1310
+ items = []
1311
+ if self.item and self.size > 0:
1312
+ for i in range(self.size):
1313
+ items.append(self.item[i].get())
1314
+ return CapabilityItemMap(
1315
+ item=items,
1316
+ size=self.size
1317
+ )
1318
+
1319
+ @staticmethod
1320
+ def create(item_map: CapabilityItemMap) -> 'CapabilityItemMapInner':
1321
+ if item_map.item and len(item_map.item) > 0:
1322
+ items_array = (CapabilityItemInner * len(item_map.item))()
1323
+ for i, item in enumerate(item_map.item):
1324
+ items_array[i] = CapabilityItemInner.create(item)
1325
+ items_ptr = ctypes.cast(items_array, ctypes.POINTER(CapabilityItemInner))
1326
+ else:
1327
+ items_ptr = ctypes.POINTER(CapabilityItemInner)()
1328
+
1329
+ return CapabilityItemMapInner(
1330
+ items_ptr,
1331
+ len(item_map.item) if item_map.item else 0
1332
+ )
1333
+
1334
+
1335
+ class CapabilitiesInner(ctypes.Structure):
1336
+ _fields_ = [
1337
+ ("item_map", ctypes.POINTER(CapabilityItemMapInner)),
1338
+ ("capability_type", ctypes.c_int)
1339
+ ]
1340
+
1341
+ def get(self):
1342
+ return Capabilities(
1343
+ item_map=self.item_map.contents.get() if self.item_map else None,
1344
+ capability_type=self.capability_type
1345
+ )
1346
+
1347
+ @staticmethod
1348
+ def create(capabilities: Capabilities) -> 'CapabilitiesInner':
1349
+ item_map_ptr = None
1350
+ if capabilities.item_map:
1351
+ item_map_inner = CapabilityItemMapInner.create(capabilities.item_map)
1352
+ item_map_ptr = ctypes.pointer(item_map_inner)
1353
+
1354
+ return CapabilitiesInner(
1355
+ item_map_ptr,
1356
+ capabilities.capability_type
1357
+ )
1358
+
1359
+
1360
+
1361
+ class CapabilitiesItemMapInner(ctypes.Structure):
1362
+ _fields_ = [
1363
+ ("item", ctypes.POINTER(CapabilityItemInner)),
1364
+ ("size", ctypes.c_size_t)
1365
+ ]
1366
+
1367
+ def get(self):
1368
+ return CapabilitiesItemMap(
1369
+ item=self.item,
1370
+ size=self.size
1371
+ )