agora-python-server-sdk 1.1.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.
Files changed (23) hide show
  1. agora_python_server_sdk-1.1.0/MANIFEST.in +1 -0
  2. agora_python_server_sdk-1.1.0/PKG-INFO +70 -0
  3. agora_python_server_sdk-1.1.0/README.md +53 -0
  4. agora_python_server_sdk-1.1.0/agora_python_server_sdk.egg-info/PKG-INFO +70 -0
  5. agora_python_server_sdk-1.1.0/agora_python_server_sdk.egg-info/SOURCES.txt +21 -0
  6. agora_python_server_sdk-1.1.0/agora_python_server_sdk.egg-info/dependency_links.txt +1 -0
  7. agora_python_server_sdk-1.1.0/agora_python_server_sdk.egg-info/top_level.txt +1 -0
  8. agora_python_server_sdk-1.1.0/agora_service/__init__.py +21 -0
  9. agora_python_server_sdk-1.1.0/agora_service/agora_base.py +71 -0
  10. agora_python_server_sdk-1.1.0/agora_service/agora_service.py +110 -0
  11. agora_python_server_sdk-1.1.0/agora_service/audio_frame_observer.py +65 -0
  12. agora_python_server_sdk-1.1.0/agora_service/audio_pcm_data_sender.py +86 -0
  13. agora_python_server_sdk-1.1.0/agora_service/audio_vad.py +155 -0
  14. agora_python_server_sdk-1.1.0/agora_service/local_audio_track.py +30 -0
  15. agora_python_server_sdk-1.1.0/agora_service/local_user.py +15 -0
  16. agora_python_server_sdk-1.1.0/agora_service/media_node_factory.py +16 -0
  17. agora_python_server_sdk-1.1.0/agora_service/rtc_conn_observer.py +299 -0
  18. agora_python_server_sdk-1.1.0/agora_service/rtc_connection.py +321 -0
  19. agora_python_server_sdk-1.1.0/agora_service/video_frame_observer.py +34 -0
  20. agora_python_server_sdk-1.1.0/agora_service/video_sender.py +193 -0
  21. agora_python_server_sdk-1.1.0/pyproject.toml +4 -0
  22. agora_python_server_sdk-1.1.0/setup.cfg +4 -0
  23. agora_python_server_sdk-1.1.0/setup.py +74 -0
@@ -0,0 +1 @@
1
+ exclude agora_service/agora_sdk/*
@@ -0,0 +1,70 @@
1
+ Metadata-Version: 2.1
2
+ Name: agora_python_server_sdk
3
+ Version: 1.1.0
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
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Requires-Python: >=3.8
16
+ Description-Content-Type: text/markdown
17
+
18
+ # Notice
19
+ - this is a python sdk wrappered agora rtc sdk.
20
+ - can dev under mac, and release unde linux
21
+ - the examples is just a simple demo, it is not a good practice to use it in production
22
+ # Very import notice !!!!!!!
23
+ - It's crucial that a process can only have one instance.
24
+ - One instance can have multiple connections.
25
+ - In all observers or callbacks, it is not allowed to call the SDK's own APIs, nor is it permitted to perform CPU-intensive tasks within the callbacks. However, data copying is allowed.
26
+
27
+ # Required OS and python version
28
+ - supported Linux version:
29
+ - Ubuntu 18.04 LTS and above
30
+ - CentOS 7.0 and above
31
+
32
+ - supported Mac version:
33
+
34
+ - MacOS 13 and above
35
+
36
+ - python version:
37
+ - python 3.8 above
38
+
39
+ # Test Data
40
+ - download and unzip [test_data.zip](https://download.agora.io/demo/test/test_data_202409021506.zip)
41
+ - make **test_data** directory in the same directory with **agora_service**
42
+
43
+ # Linux debug & develop
44
+ ## Prepare C version of agora rtc sdk
45
+
46
+ - make **agora_sdk** directory in the same directory with **agora_service**
47
+ - download and unzip [agora_sdk.zip](https://download.agora.io/sdk/release/agora_rtc_sdk_linux_v4.0.1_202409051524_333459.zip
48
+ ) to **agora_sdk**
49
+ - there should be **libagora_rtc_sdk.so** and **include_c** in **agora_sdk** directory
50
+
51
+ ## run example on linux
52
+ ```
53
+ export LD_LIBRARY_PATH=/path/to/agora_sdk:$LD_LIBRARY_PATH
54
+ python examples/example_send_pcm.py {appid} {token} {channel_id} ./test_data/demo.pcm {userid}
55
+ ```
56
+
57
+ # Mac debug & develop
58
+ ## Prepare C version of agora rtc sdk
59
+ - make **agora_sdk** directory in the same directory with **agora_service**
60
+ - download and unzip [agora_sdk.zip](https://download.agora.io/sdk/release/agora_rtc_sdk_mac_20240902_320567.zip) to **agora_sdk**
61
+ - there should be **libAgoraRtcKit.dylib** and **include_c** in **agora_sdk** directory
62
+
63
+ ## run example on mac
64
+
65
+ - add **libAgoraRtcKit.dylib** to **/usr/local/lib**
66
+ - or `export DYLD_LIBRARY_PATH=/path/to/agora_sdk:$DYLD_LIBRARY_PATH`
67
+
68
+ ```
69
+ python examples/example_send_pcm.py {appid} {token} {channel_id} ./test_data/demo.pcm {userid}
70
+ ```
@@ -0,0 +1,53 @@
1
+ # Notice
2
+ - this is a python sdk wrappered agora rtc sdk.
3
+ - can dev under mac, and release unde linux
4
+ - the examples is just a simple demo, it is not a good practice to use it in production
5
+ # Very import notice !!!!!!!
6
+ - It's crucial that a process can only have one instance.
7
+ - One instance can have multiple connections.
8
+ - In all observers or callbacks, it is not allowed to call the SDK's own APIs, nor is it permitted to perform CPU-intensive tasks within the callbacks. However, data copying is allowed.
9
+
10
+ # Required OS and python version
11
+ - supported Linux version:
12
+ - Ubuntu 18.04 LTS and above
13
+ - CentOS 7.0 and above
14
+
15
+ - supported Mac version:
16
+
17
+ - MacOS 13 and above
18
+
19
+ - python version:
20
+ - python 3.8 above
21
+
22
+ # Test Data
23
+ - download and unzip [test_data.zip](https://download.agora.io/demo/test/test_data_202409021506.zip)
24
+ - make **test_data** directory in the same directory with **agora_service**
25
+
26
+ # Linux debug & develop
27
+ ## Prepare C version of agora rtc sdk
28
+
29
+ - make **agora_sdk** directory in the same directory with **agora_service**
30
+ - download and unzip [agora_sdk.zip](https://download.agora.io/sdk/release/agora_rtc_sdk_linux_v4.0.1_202409051524_333459.zip
31
+ ) to **agora_sdk**
32
+ - there should be **libagora_rtc_sdk.so** and **include_c** in **agora_sdk** directory
33
+
34
+ ## run example on linux
35
+ ```
36
+ export LD_LIBRARY_PATH=/path/to/agora_sdk:$LD_LIBRARY_PATH
37
+ python examples/example_send_pcm.py {appid} {token} {channel_id} ./test_data/demo.pcm {userid}
38
+ ```
39
+
40
+ # Mac debug & develop
41
+ ## Prepare C version of agora rtc sdk
42
+ - make **agora_sdk** directory in the same directory with **agora_service**
43
+ - download and unzip [agora_sdk.zip](https://download.agora.io/sdk/release/agora_rtc_sdk_mac_20240902_320567.zip) to **agora_sdk**
44
+ - there should be **libAgoraRtcKit.dylib** and **include_c** in **agora_sdk** directory
45
+
46
+ ## run example on mac
47
+
48
+ - add **libAgoraRtcKit.dylib** to **/usr/local/lib**
49
+ - or `export DYLD_LIBRARY_PATH=/path/to/agora_sdk:$DYLD_LIBRARY_PATH`
50
+
51
+ ```
52
+ python examples/example_send_pcm.py {appid} {token} {channel_id} ./test_data/demo.pcm {userid}
53
+ ```
@@ -0,0 +1,70 @@
1
+ Metadata-Version: 2.1
2
+ Name: agora_python_server_sdk
3
+ Version: 1.1.0
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
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Requires-Python: >=3.8
16
+ Description-Content-Type: text/markdown
17
+
18
+ # Notice
19
+ - this is a python sdk wrappered agora rtc sdk.
20
+ - can dev under mac, and release unde linux
21
+ - the examples is just a simple demo, it is not a good practice to use it in production
22
+ # Very import notice !!!!!!!
23
+ - It's crucial that a process can only have one instance.
24
+ - One instance can have multiple connections.
25
+ - In all observers or callbacks, it is not allowed to call the SDK's own APIs, nor is it permitted to perform CPU-intensive tasks within the callbacks. However, data copying is allowed.
26
+
27
+ # Required OS and python version
28
+ - supported Linux version:
29
+ - Ubuntu 18.04 LTS and above
30
+ - CentOS 7.0 and above
31
+
32
+ - supported Mac version:
33
+
34
+ - MacOS 13 and above
35
+
36
+ - python version:
37
+ - python 3.8 above
38
+
39
+ # Test Data
40
+ - download and unzip [test_data.zip](https://download.agora.io/demo/test/test_data_202409021506.zip)
41
+ - make **test_data** directory in the same directory with **agora_service**
42
+
43
+ # Linux debug & develop
44
+ ## Prepare C version of agora rtc sdk
45
+
46
+ - make **agora_sdk** directory in the same directory with **agora_service**
47
+ - download and unzip [agora_sdk.zip](https://download.agora.io/sdk/release/agora_rtc_sdk_linux_v4.0.1_202409051524_333459.zip
48
+ ) to **agora_sdk**
49
+ - there should be **libagora_rtc_sdk.so** and **include_c** in **agora_sdk** directory
50
+
51
+ ## run example on linux
52
+ ```
53
+ export LD_LIBRARY_PATH=/path/to/agora_sdk:$LD_LIBRARY_PATH
54
+ python examples/example_send_pcm.py {appid} {token} {channel_id} ./test_data/demo.pcm {userid}
55
+ ```
56
+
57
+ # Mac debug & develop
58
+ ## Prepare C version of agora rtc sdk
59
+ - make **agora_sdk** directory in the same directory with **agora_service**
60
+ - download and unzip [agora_sdk.zip](https://download.agora.io/sdk/release/agora_rtc_sdk_mac_20240902_320567.zip) to **agora_sdk**
61
+ - there should be **libAgoraRtcKit.dylib** and **include_c** in **agora_sdk** directory
62
+
63
+ ## run example on mac
64
+
65
+ - add **libAgoraRtcKit.dylib** to **/usr/local/lib**
66
+ - or `export DYLD_LIBRARY_PATH=/path/to/agora_sdk:$DYLD_LIBRARY_PATH`
67
+
68
+ ```
69
+ python examples/example_send_pcm.py {appid} {token} {channel_id} ./test_data/demo.pcm {userid}
70
+ ```
@@ -0,0 +1,21 @@
1
+ MANIFEST.in
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ agora_python_server_sdk.egg-info/PKG-INFO
6
+ agora_python_server_sdk.egg-info/SOURCES.txt
7
+ agora_python_server_sdk.egg-info/dependency_links.txt
8
+ agora_python_server_sdk.egg-info/top_level.txt
9
+ agora_service/__init__.py
10
+ agora_service/agora_base.py
11
+ agora_service/agora_service.py
12
+ agora_service/audio_frame_observer.py
13
+ agora_service/audio_pcm_data_sender.py
14
+ agora_service/audio_vad.py
15
+ agora_service/local_audio_track.py
16
+ agora_service/local_user.py
17
+ agora_service/media_node_factory.py
18
+ agora_service/rtc_conn_observer.py
19
+ agora_service/rtc_connection.py
20
+ agora_service/video_frame_observer.py
21
+ agora_service/video_sender.py
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env python
2
+
3
+ import os
4
+ import sys
5
+ import ctypes
6
+
7
+ sdk_dir = os.path.dirname(os.path.abspath(__file__))
8
+ lib_path = os.path.join(sdk_dir, 'agora_sdk')
9
+
10
+ print("sdk_dir:", lib_path)
11
+
12
+ if sys.platform == 'darwin':
13
+ lib_agora_rtc_path =os.path.join(lib_path, 'libAgoraRtcKit.dylib')
14
+ elif sys.platform == 'linux':
15
+ lib_agora_rtc_path =os.path.join(lib_path, 'libagora_rtc_sdk.so')
16
+ try:
17
+ agora_lib = ctypes.CDLL(lib_agora_rtc_path)
18
+ except OSError as e:
19
+ print(f"Error loading the library: {e}")
20
+ print(f"Attempted to load from: {lib_agora_rtc_path}")
21
+ sys.exit(1)
@@ -0,0 +1,71 @@
1
+ import time
2
+ import ctypes
3
+ import os
4
+ import sys
5
+
6
+
7
+ from . import agora_lib
8
+
9
+ AGORA_HANDLE = ctypes.c_void_p
10
+ AGORA_API_C_INT = ctypes.c_int
11
+ AGORA_API_C_HDL = ctypes.c_void_p
12
+ user_id_t = ctypes.c_char_p
13
+
14
+ class LastmileProbeOneWayResult(ctypes.Structure):
15
+ _fields_ = [
16
+ ("packet_loss_rate", ctypes.c_uint),
17
+ ("jitter", ctypes.c_uint),
18
+ ("available_bandwidth", ctypes.c_uint)
19
+ ]
20
+
21
+ class LastmileProbeResult(ctypes.Structure):
22
+ _fields_ = [
23
+ ("state", ctypes.c_int),
24
+ ("uplink_report", LastmileProbeOneWayResult),
25
+ ("downlink_report", LastmileProbeOneWayResult),
26
+ ("rtt", ctypes.c_uint)
27
+ ]
28
+
29
+
30
+ class RTCStats(ctypes.Structure):
31
+ _fields_ = [
32
+ ("connection_id", ctypes.c_uint),
33
+ ("duration", ctypes.c_uint),
34
+ ("tx_bytes", ctypes.c_uint),
35
+ ("rx_bytes", ctypes.c_uint),
36
+ ("tx_audio_bytes", ctypes.c_uint),
37
+ ("tx_video_bytes", ctypes.c_uint),
38
+ ("rx_audio_bytes", ctypes.c_uint),
39
+ ("rx_video_bytes", ctypes.c_uint),
40
+ ("tx_k_bit_rate", ctypes.c_ushort),
41
+ ("rx_k_bit_rate", ctypes.c_ushort),
42
+ ("rx_audio_k_bit_rate", ctypes.c_ushort),
43
+ ("tx_audio_k_bit_rate", ctypes.c_ushort),
44
+ ("rx_video_k_bit_rate", ctypes.c_ushort),
45
+ ("tx_video_k_bit_rate", ctypes.c_ushort),
46
+ ("lastmile_delay", ctypes.c_ushort),
47
+ ("user_count", ctypes.c_uint),
48
+ ("cpu_app_usage", ctypes.c_double),
49
+ ("cpu_total_usage", ctypes.c_double),
50
+ ("gateway_rtt", ctypes.c_int),
51
+ ("memory_app_usage_ratio", ctypes.c_double),
52
+ ("memory_total_usage_ratio", ctypes.c_double),
53
+ ("memory_app_usage_in_kbytes", ctypes.c_int),
54
+ ("connect_time_ms", ctypes.c_int),
55
+ ("first_audio_packet_duration", ctypes.c_int),
56
+ ("first_video_packet_duration", ctypes.c_int),
57
+ ("first_video_key_frame_packet_duration", ctypes.c_int),
58
+ ("packets_before_first_key_frame_packet", ctypes.c_int),
59
+ ("first_audio_packet_duration_after_unmute", ctypes.c_int),
60
+ ("first_video_packet_duration_after_unmute", ctypes.c_int),
61
+ ("first_video_key_frame_packet_duration_after_unmute", ctypes.c_int),
62
+ ("first_video_key_frame_decoded_duration_after_unmute", ctypes.c_int),
63
+ ("first_video_key_frame_rendered_duration_after_unmute", ctypes.c_int),
64
+ ("tx_packet_loss_rate", ctypes.c_int),
65
+ ("rx_packet_loss_rate", ctypes.c_int)
66
+ ]
67
+
68
+
69
+ agora_service_create_custom_audio_track_pcm = agora_lib.agora_service_create_custom_audio_track_pcm
70
+ agora_service_create_custom_audio_track_pcm.restype = AGORA_HANDLE
71
+ agora_service_create_custom_audio_track_pcm.argtypes = [AGORA_HANDLE, AGORA_HANDLE]
@@ -0,0 +1,110 @@
1
+ #!/usr/python3/bin/python3.12
2
+
3
+ # python3.6
4
+
5
+ # PYTHONPATH=../../agora_sdk/ LD_LIBRARY_PATH=../../agora_sdk/ python3.6 demo.py
6
+ import time
7
+ import ctypes
8
+
9
+ import os
10
+ import sys
11
+
12
+ from .media_node_factory import *
13
+ from .rtc_connection import *
14
+ from .audio_pcm_data_sender import *
15
+ from .local_audio_track import *
16
+ from .rtc_conn_observer import *
17
+ from .agora_base import *
18
+
19
+ script_dir = os.path.dirname(os.path.abspath(__file__))
20
+ sdk_dir = os.path.dirname(os.path.dirname(script_dir))
21
+
22
+
23
+
24
+ # 定义常量
25
+ AGORA_HANDLE = ctypes.c_void_p
26
+ AGORA_API_C_INT = ctypes.c_int
27
+ AGORA_API_C_HDLR = ctypes.c_void_p
28
+
29
+ # 定义 agora_service_config 结构体
30
+ class AgoraServiceConfig(ctypes.Structure):
31
+ _fields_ = [
32
+ ('enable_audio_processor', ctypes.c_int),
33
+ ('enable_audio_device', ctypes.c_int),
34
+ ('enable_video', ctypes.c_int),
35
+ ('context', ctypes.c_void_p),
36
+
37
+ ('app_id', ctypes.c_char_p),
38
+ ('area_code', ctypes.c_uint),
39
+ ('channel_profile', ctypes.c_int),
40
+ ('audio_scenario', ctypes.c_int),
41
+
42
+ ('use_string_uid', ctypes.c_int),
43
+
44
+ # ('log_path', ctypes.c_char_p),
45
+ # ('log_size', ctypes.c_int),
46
+ ]
47
+
48
+ def __init__(self) -> None:
49
+ self.log_path = ""
50
+ self.log_size = 0
51
+ self.appid = ""
52
+
53
+ # ('log_path', ctypes.c_char_p),
54
+ # ('log_size', ctypes.c_int),
55
+
56
+
57
+
58
+
59
+ # 定义 agora_service_create 函数
60
+ agora_service_create = agora_lib.agora_service_create
61
+ agora_service_create.restype = AGORA_HANDLE
62
+
63
+ # 定义 agora_service_initialize 函数
64
+ agora_service_initialize = agora_lib.agora_service_initialize
65
+ agora_service_initialize.restype = AGORA_API_C_INT
66
+ agora_service_initialize.argtypes = [AGORA_HANDLE, ctypes.POINTER(AgoraServiceConfig)]
67
+
68
+
69
+ agora_service_create_media_node_factory = agora_lib.agora_service_create_media_node_factory
70
+ agora_service_create_media_node_factory.restype = AGORA_HANDLE
71
+ agora_service_create_media_node_factory.argtypes = [AGORA_HANDLE]
72
+
73
+ agora_service_release = agora_lib.agora_service_release
74
+ agora_service_release.restype = AGORA_API_C_INT
75
+ agora_service_release.argtypes = [AGORA_HANDLE]
76
+
77
+ agora_service_set_log_file = agora_lib.agora_service_set_log_file
78
+ agora_service_set_log_file.restype = AGORA_API_C_INT
79
+ agora_service_set_log_file.argtypes = [AGORA_HANDLE, ctypes.c_char_p, ctypes.c_uint]
80
+
81
+
82
+ class AgoraService:
83
+ def __init__(self) -> None:
84
+ self.service_handle = agora_service_create()
85
+ self.inited = False
86
+
87
+ def NewConnection(self, con_config):
88
+ return RTCConnection(con_config,self)
89
+
90
+ def Init(self, config: AgoraServiceConfig):
91
+ if self.inited == True:
92
+ return
93
+ config.app_id = config.appid.encode('utf-8')
94
+ result = agora_service_initialize(self.service_handle, ctypes.byref(config))
95
+ self.media_node_factory = agora_service_create_media_node_factory(self.service_handle)
96
+
97
+ if config.log_path:
98
+ log_size = 512 * 1024
99
+ if config.log_size > 0:
100
+ log_size = config.log_size
101
+ agora_service_set_log_file(self.service_handle, ctypes.create_string_buffer(config.log_path.encode('utf-8')),log_size)
102
+
103
+ if result == 0:
104
+ self.inited = True
105
+ print(f'Initialization result: {result}')
106
+
107
+ def Destroy(self):
108
+ if self.inited == False:
109
+ return
110
+ agora_service_release(self.service_handle)
@@ -0,0 +1,65 @@
1
+ import ctypes
2
+ from .agora_base import *
3
+ from .local_user import *
4
+ import ctypes
5
+
6
+
7
+ class RAW_AUDIO_FRAME_OP_MODE_TYPE(ctypes.c_int):
8
+ RAW_AUDIO_FRAME_OP_MODE_READ_ONLY = 0
9
+ RAW_AUDIO_FRAME_OP_MODE_READ_WRITE = 2
10
+
11
+ class AUDIO_FRAME_POSITION(ctypes.c_int):
12
+ AUDIO_FRAME_POSITION_PLAYBACK = 0x0001
13
+ AUDIO_FRAME_POSITION_RECORD = 0x0002
14
+ AUDIO_FRAME_POSITION_MIXED = 0x0004
15
+ AUDIO_FRAME_POSITION_BEFORE_MIXING = 0x0008
16
+
17
+ class AudioFrame(ctypes.Structure):
18
+ _fields_ = [
19
+ ("type", ctypes.c_int),
20
+ ("samples_per_channel", ctypes.c_int),
21
+ ("bytes_per_sample", ctypes.c_int),
22
+ ("channels", ctypes.c_int),
23
+ ("samples_per_sec", ctypes.c_int),
24
+ ("buffer", ctypes.c_void_p),
25
+ ("render_time_ms", ctypes.c_int64),
26
+ ("avsync_type", ctypes.c_int)
27
+ ]
28
+ pass
29
+
30
+
31
+ class AudioParams(ctypes.Structure):
32
+ _fields_ = [
33
+ ("sample_rate", ctypes.c_int),
34
+ ("channels", ctypes.c_int),
35
+ ("mode", ctypes.c_int),
36
+ ("samples_per_call", ctypes.c_int)
37
+ ]
38
+ pass
39
+
40
+ ON_RECORD_AUDIO_FRAME_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int, AGORA_HANDLE, ctypes.c_char_p, ctypes.POINTER(AudioFrame))
41
+ ON_PLAYBACK_AUDIO_FRAME_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int, AGORA_HANDLE, ctypes.c_char_p, ctypes.POINTER(AudioFrame))
42
+ ON_MIXED_AUDIO_FRAME_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int, AGORA_HANDLE, ctypes.c_char_p, ctypes.POINTER(AudioFrame))
43
+ ON_EAR_MONITORING_AUDIO_FRAME_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int, AGORA_HANDLE, ctypes.POINTER(AudioFrame))
44
+ ON_PLAYBACK_AUDIO_FRAME_BEFORE_MIXING_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int, AGORA_HANDLE, ctypes.c_char_p, user_id_t, ctypes.POINTER(AudioFrame))
45
+ ON_GET_AUDIO_FRAME_POSITION_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_int, AGORA_HANDLE)
46
+ ON_GET_PLAYBACK_AUDIO_FRAME_PARAM_CALLBACK = ctypes.CFUNCTYPE(AudioParams, AGORA_HANDLE)
47
+ ON_GET_RECORD_AUDIO_FRAME_PARAM_CALLBACK = ctypes.CFUNCTYPE(AudioParams, AGORA_HANDLE)
48
+ ON_GET_MIXED_AUDIO_FRAME_PARAM_CALLBACK = ctypes.CFUNCTYPE(AudioParams, AGORA_HANDLE)
49
+ ON_GET_EAR_MONITORING_AUDIO_FRAME_PARAM_CALLBACK = ctypes.CFUNCTYPE(AudioParams, AGORA_HANDLE)
50
+
51
+ class AudioFrameObserver(ctypes.Structure):
52
+ _fields_ = [
53
+ ("on_record_audio_frame", ON_RECORD_AUDIO_FRAME_CALLBACK),
54
+ ("on_playback_audio_frame", ON_PLAYBACK_AUDIO_FRAME_CALLBACK),
55
+ ("on_mixed_audio_frame", ON_MIXED_AUDIO_FRAME_CALLBACK),
56
+ ("on_ear_monitoring_audio_frame", ON_EAR_MONITORING_AUDIO_FRAME_CALLBACK),
57
+
58
+ ("on_playback_audio_frame_before_mixing", ON_PLAYBACK_AUDIO_FRAME_BEFORE_MIXING_CALLBACK),
59
+ ("on_get_audio_frame_position", ON_GET_AUDIO_FRAME_POSITION_CALLBACK),
60
+ ("on_get_playback_audio_frame_param", ON_GET_PLAYBACK_AUDIO_FRAME_PARAM_CALLBACK),
61
+ ("on_get_record_audio_frame_param", ON_GET_RECORD_AUDIO_FRAME_PARAM_CALLBACK),
62
+
63
+ ("on_get_mixed_audio_frame_param", ON_GET_MIXED_AUDIO_FRAME_PARAM_CALLBACK),
64
+ ("on_get_ear_monitoring_audio_frame_param", ON_GET_EAR_MONITORING_AUDIO_FRAME_PARAM_CALLBACK)
65
+ ]
@@ -0,0 +1,86 @@
1
+ import ctypes
2
+ from .agora_base import *
3
+
4
+ class PcmAudioFrame:
5
+ def __init__(self):
6
+ self.data = []
7
+ self.timestamp = 0
8
+ self.samples_per_channel = 0
9
+ self.bytes_per_sample = 0
10
+ self.number_of_channels = 0
11
+ self.sample_rate = 0
12
+
13
+
14
+ agora_audio_pcm_data_sender_send = agora_lib.agora_audio_pcm_data_sender_send
15
+ agora_audio_pcm_data_sender_send.restype = AGORA_API_C_INT
16
+ agora_audio_pcm_data_sender_send.argtypes = [AGORA_HANDLE, ctypes.c_void_p, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32, ctypes.c_uint32]
17
+
18
+ agora_local_audio_track_destroy = agora_lib.agora_local_audio_track_destroy
19
+ agora_local_audio_track_destroy.argtypes = [AGORA_HANDLE]
20
+
21
+ agora_audio_pcm_data_sender_destroy = agora_lib.agora_audio_pcm_data_sender_destroy
22
+ agora_audio_pcm_data_sender_destroy.argtypes = [ctypes.c_void_p]
23
+
24
+ agora_local_audio_track_set_enabled = agora_lib.agora_local_audio_track_set_enabled
25
+ agora_local_audio_track_set_enabled.argtypes = [AGORA_HANDLE, ctypes.c_int]
26
+
27
+ agora_local_user_publish_audio = agora_lib.agora_local_user_publish_audio
28
+ agora_local_user_publish_audio.restype = AGORA_API_C_INT
29
+ agora_local_user_publish_audio.argtypes = [AGORA_HANDLE, AGORA_HANDLE]
30
+
31
+ agora_local_user_unpublish_audio = agora_lib.agora_local_user_unpublish_audio
32
+ agora_local_user_unpublish_audio.restype = AGORA_API_C_INT
33
+ agora_local_user_unpublish_audio.argtypes = [AGORA_HANDLE, AGORA_HANDLE]
34
+
35
+ agora_local_audio_track_adjust_publish_volume = agora_lib.agora_local_audio_track_adjust_publish_volume
36
+ agora_local_audio_track_adjust_publish_volume.restype = AGORA_API_C_INT
37
+ agora_local_audio_track_adjust_publish_volume.argtypes = [AGORA_HANDLE, ctypes.c_int]
38
+
39
+ #todo: need check restype, by wei 0720
40
+ agora_local_audio_track_set_max_buffer_audio_frame_number = agora_lib.agora_local_audio_track_set_max_buffer_audio_frame_number
41
+ agora_local_audio_track_set_max_buffer_audio_frame_number.restype = AGORA_API_C_INT
42
+ agora_local_audio_track_set_max_buffer_audio_frame_number.argtypes = [AGORA_HANDLE, ctypes.c_int]
43
+
44
+ agora_local_audio_track_clear_buffer = agora_lib.agora_local_audio_track_clear_buffer
45
+ agora_local_audio_track_clear_buffer.restype = AGORA_API_C_INT
46
+ agora_local_audio_track_clear_buffer.argtypes = [AGORA_HANDLE]
47
+
48
+
49
+ class AudioPcmDataSender:
50
+ def __init__(self, audio_pcm_data_sender, audio_track, local_user) -> None:
51
+ self.audio_pcm_data_sender = audio_pcm_data_sender
52
+ self.audio_track = audio_track
53
+ self.local_user = local_user
54
+
55
+
56
+ def Release(self):
57
+ if self.audio_pcm_data_sender == None:
58
+ return
59
+ agora_local_audio_track_destroy(self.audio_pcm_data_sender)
60
+ agora_audio_pcm_data_sender_destroy(self.audio_track)
61
+
62
+ def Start(self):
63
+ agora_local_audio_track_set_enabled(self.audio_track, 1)
64
+ ret = agora_local_user_publish_audio(self.local_user, self.audio_track)
65
+ return ret
66
+
67
+ def Stop(self):
68
+ ret = agora_local_user_unpublish_audio(self.local_user, self.audio_track)
69
+ agora_local_audio_track_set_enabled(self.audio_track, 0)
70
+ return ret
71
+
72
+ def SendPcmData(self, frame):
73
+ c_data = (ctypes.c_char * len(frame.data)).from_buffer(frame.data)
74
+ return agora_audio_pcm_data_sender_send(self.audio_pcm_data_sender, c_data, frame.timestamp, frame.samples_per_channel, frame.bytes_per_sample, frame.number_of_channels, frame.sample_rate)
75
+
76
+ def AdjustVolume(self, volume):
77
+ return agora_local_audio_track_adjust_publish_volume(self.audio_track, volume)
78
+
79
+ def SetSendBufferSize(self, bufSize):
80
+ ret = agora_local_audio_track_set_max_buffer_audio_frame_number(self.audio_track, bufSize)
81
+ return ret
82
+
83
+ def ClearSendBuffer(self):
84
+ ret = agora_local_audio_track_clear_buffer(self.audio_track)
85
+ return ret
86
+