agora-python-server-sdk 2.0.8__tar.gz → 2.1.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.
Files changed (49) hide show
  1. {agora_python_server_sdk-2.0.8/agora_python_server_sdk.egg-info → agora_python_server_sdk-2.1.1}/PKG-INFO +9 -7
  2. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/README.md +2 -2
  3. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/__init__.py +18 -15
  4. {agora_python_server_sdk-2.0.8/agora/rtc → agora_python_server_sdk-2.1.1/agora/rtc/_ctypes_handle}/_audio_frame_observer.py +16 -47
  5. agora_python_server_sdk-2.1.1/agora/rtc/_ctypes_handle/_ctypes_data.py +1163 -0
  6. {agora_python_server_sdk-2.0.8/agora/rtc → agora_python_server_sdk-2.1.1/agora/rtc/_ctypes_handle}/_local_user_observer.py +36 -75
  7. {agora_python_server_sdk-2.0.8/agora/rtc → agora_python_server_sdk-2.1.1/agora/rtc/_ctypes_handle}/_rtc_connection_observer.py +28 -43
  8. agora_python_server_sdk-2.1.1/agora/rtc/_ctypes_handle/_video_encoded_frame_observer.py +28 -0
  9. agora_python_server_sdk-2.1.1/agora/rtc/_ctypes_handle/_video_frame_observer.py +27 -0
  10. agora_python_server_sdk-2.1.1/agora/rtc/agora_base.py +497 -0
  11. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/agora_parameter.py +2 -20
  12. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/agora_service.py +39 -119
  13. agora_python_server_sdk-2.1.1/agora/rtc/audio_encoded_frame_sender.py +35 -0
  14. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/audio_frame_observer.py +2 -1
  15. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/audio_pcm_data_sender.py +12 -15
  16. agora_python_server_sdk-2.1.1/agora/rtc/audio_sessionctrl.py +484 -0
  17. agora_python_server_sdk-2.1.1/agora/rtc/audio_vad.py +164 -0
  18. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/local_audio_track.py +14 -7
  19. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/local_user.py +86 -57
  20. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/local_user_observer.py +3 -1
  21. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/local_video_track.py +17 -9
  22. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/media_node_factory.py +16 -11
  23. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/remote_audio_track.py +14 -31
  24. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/remote_video_track.py +6 -41
  25. agora_python_server_sdk-2.1.1/agora/rtc/rtc_connection.py +136 -0
  26. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/rtc_connection_observer.py +2 -1
  27. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora/rtc/video_encoded_frame_observer.py +3 -4
  28. agora_python_server_sdk-2.1.1/agora/rtc/video_encoded_image_sender.py +33 -0
  29. agora_python_server_sdk-2.1.1/agora/rtc/video_frame_observer.py +8 -0
  30. agora_python_server_sdk-2.1.1/agora/rtc/video_frame_sender.py +30 -0
  31. agora_python_server_sdk-2.1.1/agora/rtc/voice_detection.py +240 -0
  32. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1/agora_python_server_sdk.egg-info}/PKG-INFO +10 -8
  33. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora_python_server_sdk.egg-info/SOURCES.txt +9 -6
  34. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/setup.py +19 -21
  35. agora_python_server_sdk-2.0.8/agora/rtc/_video_encoded_frame_observer.py +0 -56
  36. agora_python_server_sdk-2.0.8/agora/rtc/_video_frame_observer.py +0 -74
  37. agora_python_server_sdk-2.0.8/agora/rtc/agora_base.py +0 -350
  38. agora_python_server_sdk-2.0.8/agora/rtc/audio_encoded_frame_sender.py +0 -76
  39. agora_python_server_sdk-2.0.8/agora/rtc/audio_vad.py +0 -162
  40. agora_python_server_sdk-2.0.8/agora/rtc/rtc_connection.py +0 -337
  41. agora_python_server_sdk-2.0.8/agora/rtc/video_encoded_image_sender.py +0 -87
  42. agora_python_server_sdk-2.0.8/agora/rtc/video_frame_observer.py +0 -47
  43. agora_python_server_sdk-2.0.8/agora/rtc/video_frame_sender.py +0 -92
  44. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/MANIFEST.in +0 -0
  45. {agora_python_server_sdk-2.0.8/agora/rtc → agora_python_server_sdk-2.1.1/agora/rtc/_utils}/globals.py +0 -0
  46. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora_python_server_sdk.egg-info/dependency_links.txt +0 -0
  47. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/agora_python_server_sdk.egg-info/top_level.txt +0 -0
  48. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/pyproject.toml +0 -0
  49. {agora_python_server_sdk-2.0.8 → agora_python_server_sdk-2.1.1}/setup.cfg +0 -0
@@ -1,18 +1,18 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: agora_python_server_sdk
3
- Version: 2.0.8
3
+ Version: 2.1.1
4
4
  Summary: A Python SDK for Agora Server
5
5
  Home-page: https://github.com/AgoraIO-Extensions/Agora-Python-Server-SDK
6
+ License: UNKNOWN
7
+ Platform: UNKNOWN
6
8
  Classifier: Intended Audience :: Developers
7
9
  Classifier: License :: OSI Approved :: MIT License
8
10
  Classifier: Topic :: Multimedia :: Sound/Audio
9
11
  Classifier: Topic :: Multimedia :: Video
10
12
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Programming Language :: Python :: 3.8
13
- Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3 :: Only
15
- Requires-Python: >=3.8
15
+ Requires-Python: >=3.10
16
16
  Description-Content-Type: text/markdown
17
17
 
18
18
  # Note
@@ -34,7 +34,7 @@ Description-Content-Type: text/markdown
34
34
  - MacOS 13 and above
35
35
 
36
36
  - Python version:
37
- - Python 3.8 and above
37
+ - Python 3.10 and above
38
38
 
39
39
  # Using Agora-Python-Server-SDK
40
40
  ```
@@ -48,6 +48,8 @@ pip install agora_python_server_sdk
48
48
 
49
49
  ## Executing Test Script
50
50
  ```
51
- python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx --userId=xxx --audioFile=./test_data/demo.pcm --sampleRate=16000 --numOfChannels=1
51
+ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx --audioFile=./test_data/demo.pcm --sampleRate=16000 --numOfChannels=1
52
52
  ```
53
53
 
54
+
55
+
@@ -17,7 +17,7 @@
17
17
  - MacOS 13 and above
18
18
 
19
19
  - Python version:
20
- - Python 3.8 and above
20
+ - Python 3.10 and above
21
21
 
22
22
  # Using Agora-Python-Server-SDK
23
23
  ```
@@ -31,6 +31,6 @@ pip install agora_python_server_sdk
31
31
 
32
32
  ## Executing Test Script
33
33
  ```
34
- python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx --userId=xxx --audioFile=./test_data/demo.pcm --sampleRate=16000 --numOfChannels=1
34
+ python agora_rtc/examples/example_audio_pcm_send.py --appId=xxx --channelId=xxx --audioFile=./test_data/demo.pcm --sampleRate=16000 --numOfChannels=1
35
35
  ```
36
36
 
@@ -1,16 +1,17 @@
1
1
  #!/usr/bin/env python
2
2
 
3
+ import hashlib
4
+ import ssl
5
+ import zipfile
6
+ import site
7
+ from urllib import request
8
+ import ctypes
3
9
  import os
4
10
  import sys
5
11
  import logging
6
12
  logger = logging.getLogger(__name__)
7
- import ctypes
8
- from urllib import request
9
- import site
10
- import zipfile
11
- import ssl
12
13
  ssl._create_default_https_context = ssl._create_unverified_context
13
- import hashlib
14
+
14
15
 
15
16
  def get_file_md5(file_path):
16
17
  hash_md5 = hashlib.md5()
@@ -19,25 +20,26 @@ def get_file_md5(file_path):
19
20
  hash_md5.update(chunk)
20
21
  return hash_md5.hexdigest()
21
22
 
23
+
22
24
  def _check_download_and_extract_sdk():
23
25
  agora_service_path = os.path.dirname(os.path.abspath(__file__))
24
26
  sdk_dir = os.path.join(agora_service_path, "agora_sdk")
25
27
  zip_path = os.path.join(agora_service_path, "agora_rtc_sdk.zip")
26
28
 
27
- url = "https://download.agora.io/sdk/release/agora_rtc_sdk_linux_v4.4.30-20241003_233327-366740.zip"
29
+ url = "https://download.agora.io/sdk/release/agora_rtc_sdk-x86_64-linux-gnu-v4.4.30-20241024_101940-398537.zip"
28
30
  libagora_rtc_sdk_path = os.path.join(sdk_dir, "libagora_rtc_sdk.so")
29
- rtc_md5 = "f3d5ac80cd56547b0a784f7489f0aca6"
31
+ rtc_md5 = "7031dd10d1681cd88fd89d68c5b54282"
30
32
  if sys.platform == 'darwin':
31
- url = "https://download.agora.io/sdk/release/agora_rtc_sdk_mac_v4.4.30_22172_FULL_20241004_0009_366745.zip"
33
+ url = "https://download.agora.io/sdk/release/agora_rtc_sdk_mac_rel.v4.4.30_22472_FULL_20241024_1224_398653.zip"
32
34
  libagora_rtc_sdk_path = os.path.join(sdk_dir, "libAgoraRtcKit.dylib")
33
- rtc_md5 = "338a4e4816ada2300c6cbd196b74e220"
35
+ rtc_md5 = "ca3ca14f9e2b7d97eb2594d1f32dab9f"
34
36
 
35
37
  if os.path.exists(libagora_rtc_sdk_path) and get_file_md5(libagora_rtc_sdk_path) == rtc_md5:
36
38
  return
37
39
 
38
40
  logger.error("missing agora sdk, now download it, please wait for a while...")
39
41
  if os.path.exists(sdk_dir):
40
- os.system(f"rm -rf {sdk_dir}")
42
+ os.system(f"rm -rf {sdk_dir}")
41
43
  os.makedirs(agora_service_path, exist_ok=True)
42
44
  if os.path.exists(zip_path):
43
45
  os.remove(zip_path)
@@ -52,6 +54,7 @@ def _check_download_and_extract_sdk():
52
54
 
53
55
  if os.path.exists(zip_path):
54
56
  os.remove(zip_path)
57
+ logger.error("download done, continue...")
55
58
 
56
59
 
57
60
  _check_download_and_extract_sdk()
@@ -61,15 +64,15 @@ lib_path = os.path.join(sdk_dir, 'agora_sdk')
61
64
 
62
65
  try:
63
66
  if sys.platform == 'darwin':
64
- lib_agora_rtc_path =os.path.join(lib_path, 'libAgoraRtcKit.dylib')
67
+ lib_agora_rtc_path = os.path.join(lib_path, 'libAgoraRtcKit.dylib')
65
68
  agora_lib = ctypes.CDLL(lib_agora_rtc_path)
66
69
 
67
70
  elif sys.platform == 'linux':
68
- lib_agora_rtc_path =os.path.join(lib_path, 'libagora_rtc_sdk.so')
71
+ lib_agora_rtc_path = os.path.join(lib_path, 'libagora_rtc_sdk.so')
69
72
  ctypes.CDLL(os.path.join(lib_path, 'libagora-fdkaac.so'))
70
73
  ctypes.CDLL(os.path.join(lib_path, 'libaosl.so'))
71
- agora_lib = ctypes.CDLL(lib_agora_rtc_path)
74
+ agora_lib = ctypes.CDLL(lib_agora_rtc_path)
72
75
  except OSError as e:
73
76
  logger.error(f"Error loading the library: {e}")
74
77
  logger.error(f"Attempted to load from: {lib_agora_rtc_path}")
75
- sys.exit(1)
78
+ sys.exit(1)
@@ -1,47 +1,11 @@
1
1
  import ctypes
2
- from .agora_base import *
3
- from .local_user import *
2
+ from ..agora_base import *
3
+ from ..local_user import *
4
4
  import ctypes
5
- from .audio_frame_observer import *
5
+ from ..audio_frame_observer import *
6
6
  import logging
7
7
  logger = logging.getLogger(__name__)
8
-
9
-
10
- class AudioFrameInner(ctypes.Structure):
11
- _fields_ = [
12
- ("type", ctypes.c_int),
13
- ("samples_per_channel", ctypes.c_int),
14
- ("bytes_per_sample", ctypes.c_int),
15
- ("channels", ctypes.c_int),
16
- ("samples_per_sec", ctypes.c_int),
17
- ("buffer", ctypes.c_void_p),
18
- ("render_time_ms", ctypes.c_int64),
19
- ("avsync_type", ctypes.c_int),
20
- ("far_field_flag", ctypes.c_int),
21
- ("rms", ctypes.c_int),
22
- ("voice_prob", ctypes.c_int),
23
- ("music_prob", ctypes.c_int),
24
- ("pitch", ctypes.c_int)
25
- ]
26
- def _to_audio_frame(self):
27
- audio_frame = AudioFrame()
28
- audio_frame.type = self.type
29
- audio_frame.samples_per_channel = self.samples_per_channel
30
- audio_frame.bytes_per_sample = self.bytes_per_sample
31
- audio_frame.channels = self.channels
32
- audio_frame.samples_per_sec = self.samples_per_sec
33
- cdata = ctypes.string_at(self.buffer, self.samples_per_channel * self.bytes_per_sample * self.channels)
34
- audio_frame.buffer = bytearray(cdata)
35
- audio_frame.render_time_ms = self.render_time_ms
36
- audio_frame.avsync_type = self.avsync_type
37
- audio_frame.far_field_flag = self.far_field_flag
38
- audio_frame.rms = self.rms
39
- audio_frame.voice_prob = self.voice_prob
40
- audio_frame.music_prob = self.music_prob
41
- audio_frame.pitch = self.pitch
42
-
43
- return audio_frame
44
-
8
+ #from ..audio_sessionctrl import *
45
9
 
46
10
  ON_RECORD_AUDIO_FRAME_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int, AGORA_HANDLE, ctypes.c_char_p, ctypes.POINTER(AudioFrameInner))
47
11
  ON_PLAYBACK_AUDIO_FRAME_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int, AGORA_HANDLE, ctypes.c_char_p, ctypes.POINTER(AudioFrameInner))
@@ -54,6 +18,7 @@ ON_GET_RECORD_AUDIO_FRAME_PARAM_CALLBACK = ctypes.CFUNCTYPE(AudioParams, AGORA_H
54
18
  ON_GET_MIXED_AUDIO_FRAME_PARAM_CALLBACK = ctypes.CFUNCTYPE(AudioParams, AGORA_HANDLE)
55
19
  ON_GET_EAR_MONITORING_AUDIO_FRAME_PARAM_CALLBACK = ctypes.CFUNCTYPE(AudioParams, AGORA_HANDLE)
56
20
 
21
+
57
22
  class AudioFrameObserverInner(ctypes.Structure):
58
23
  _fields_ = [
59
24
  ("on_record_audio_frame", ON_RECORD_AUDIO_FRAME_CALLBACK),
@@ -65,12 +30,12 @@ class AudioFrameObserverInner(ctypes.Structure):
65
30
  ("on_get_audio_frame_position", ON_GET_AUDIO_FRAME_POSITION_CALLBACK),
66
31
  ("on_get_playback_audio_frame_param", ON_GET_PLAYBACK_AUDIO_FRAME_PARAM_CALLBACK),
67
32
  ("on_get_record_audio_frame_param", ON_GET_RECORD_AUDIO_FRAME_PARAM_CALLBACK),
68
-
33
+
69
34
  ("on_get_mixed_audio_frame_param", ON_GET_MIXED_AUDIO_FRAME_PARAM_CALLBACK),
70
35
  ("on_get_ear_monitoring_audio_frame_param", ON_GET_EAR_MONITORING_AUDIO_FRAME_PARAM_CALLBACK)
71
36
  ]
72
37
 
73
- def __init__(self, observer:IAudioFrameObserver, local_user: 'LocalUser'):
38
+ def __init__(self, observer: IAudioFrameObserver, local_user: 'LocalUser'):
74
39
  self.observer = observer
75
40
  self.local_user = local_user
76
41
  self.on_record_audio_frame = ON_RECORD_AUDIO_FRAME_CALLBACK(self._on_record_audio_frame)
@@ -79,6 +44,7 @@ class AudioFrameObserverInner(ctypes.Structure):
79
44
  self.on_ear_monitoring_audio_frame = ON_EAR_MONITORING_AUDIO_FRAME_CALLBACK(self._on_ear_monitoring_audio_frame)
80
45
  self.on_playback_audio_frame_before_mixing = ON_PLAYBACK_AUDIO_FRAME_BEFORE_MIXING_CALLBACK(self._on_playback_audio_frame_before_mixing)
81
46
  self.on_get_audio_frame_position = ON_GET_AUDIO_FRAME_POSITION_CALLBACK(self._on_get_audio_frame_position)
47
+ self._session_ctrl_manager = None #SessionCtrlManager()
82
48
 
83
49
  # self.on_get_playback_audio_frame_param = ON_GET_PLAYBACK_AUDIO_FRAME_PARAM_CALLBACK(self._on_get_playback_audio_frame_param)
84
50
  # self.on_get_record_audio_frame_param = ON_GET_RECORD_AUDIO_FRAME_PARAM_CALLBACK(self._on_get_record_audio_frame_param)
@@ -88,14 +54,14 @@ class AudioFrameObserverInner(ctypes.Structure):
88
54
  def _on_record_audio_frame(self, local_user_handle, channel_id, audio_frame_inner):
89
55
  logger.debug(f"AudioFrameObserverInner _on_record_audio_frame: {local_user_handle}, {channel_id}, {audio_frame_inner}")
90
56
  channel_id_str = channel_id.decode('utf-8')
91
- frame = audio_frame_inner.contents._to_audio_frame()
57
+ frame = audio_frame_inner.contents.get()
92
58
  ret = self.observer.on_record_audio_frame(self.local_user, channel_id_str, frame)
93
59
  return ret
94
60
 
95
61
  def _on_playback_audio_frame(self, local_user_handle, channel_id, audio_frame_inner):
96
62
  logger.debug(f"AudioFrameObserverInner _on_playback_audio_frame: {local_user_handle}, {channel_id}, {audio_frame_inner}")
97
63
  channel_id_str = channel_id.decode('utf-8')
98
- frame = audio_frame_inner.contents._to_audio_frame()
64
+ frame = audio_frame_inner.contents.get()
99
65
  ret = self.observer.on_playback_audio_frame(self.local_user, channel_id_str, frame)
100
66
  return ret
101
67
 
@@ -110,6 +76,10 @@ class AudioFrameObserverInner(ctypes.Structure):
110
76
  return ret
111
77
 
112
78
  def _on_playback_audio_frame_before_mixing(self, local_user_handle, channel_id, user_id, audio_frame_inner):
79
+ #session control here !
80
+ #ret, c_data = self._session_ctrl_manager.process_audio_frame(user_id, audio_frame_inner.contents.buffer, audio_frame_inner.contents.samples_per_channel)
81
+
82
+ #print("ret = ", ret)
113
83
  #logger.debug(f"AudioFrameObserverInner _on_playback_audio_frame_before_mixing: {local_user_handle}, {channel_id}, {user_id}, {audio_frame_inner}")
114
84
  if channel_id is None:
115
85
  channel_id_str = ""
@@ -117,10 +87,10 @@ class AudioFrameObserverInner(ctypes.Structure):
117
87
  channel_id_str = channel_id.decode('utf-8')
118
88
 
119
89
  user_id_str = user_id.decode('utf-8')
120
- frame = audio_frame_inner.contents._to_audio_frame()
90
+ frame = audio_frame_inner.contents.get()
121
91
  ret = self.observer.on_playback_audio_frame_before_mixing(self.local_user, channel_id_str, user_id_str, frame)
122
92
  return ret
123
-
93
+
124
94
  def _on_get_audio_frame_position(self, local_user_handle):
125
95
  logger.debug(f"AudioFrameObserverInner _on_get_audio_frame_position: {local_user_handle}")
126
96
  return self.observer.on_get_audio_frame_position(self.local_user)
@@ -140,4 +110,3 @@ class AudioFrameObserverInner(ctypes.Structure):
140
110
  def _on_get_ear_monitoring_audio_frame_param(self, local_user_handle) -> AudioParams:
141
111
  logger.debug(f"AudioFrameObserverInner _on_get_ear_monitoring_audio_frame_param: {local_user_handle}")
142
112
  return self.observer.on_get_ear_monitoring_audio_frame_param(self.local_user)
143
-