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.
- agora_python_server_sdk-1.1.0/MANIFEST.in +1 -0
- agora_python_server_sdk-1.1.0/PKG-INFO +70 -0
- agora_python_server_sdk-1.1.0/README.md +53 -0
- agora_python_server_sdk-1.1.0/agora_python_server_sdk.egg-info/PKG-INFO +70 -0
- agora_python_server_sdk-1.1.0/agora_python_server_sdk.egg-info/SOURCES.txt +21 -0
- agora_python_server_sdk-1.1.0/agora_python_server_sdk.egg-info/dependency_links.txt +1 -0
- agora_python_server_sdk-1.1.0/agora_python_server_sdk.egg-info/top_level.txt +1 -0
- agora_python_server_sdk-1.1.0/agora_service/__init__.py +21 -0
- agora_python_server_sdk-1.1.0/agora_service/agora_base.py +71 -0
- agora_python_server_sdk-1.1.0/agora_service/agora_service.py +110 -0
- agora_python_server_sdk-1.1.0/agora_service/audio_frame_observer.py +65 -0
- agora_python_server_sdk-1.1.0/agora_service/audio_pcm_data_sender.py +86 -0
- agora_python_server_sdk-1.1.0/agora_service/audio_vad.py +155 -0
- agora_python_server_sdk-1.1.0/agora_service/local_audio_track.py +30 -0
- agora_python_server_sdk-1.1.0/agora_service/local_user.py +15 -0
- agora_python_server_sdk-1.1.0/agora_service/media_node_factory.py +16 -0
- agora_python_server_sdk-1.1.0/agora_service/rtc_conn_observer.py +299 -0
- agora_python_server_sdk-1.1.0/agora_service/rtc_connection.py +321 -0
- agora_python_server_sdk-1.1.0/agora_service/video_frame_observer.py +34 -0
- agora_python_server_sdk-1.1.0/agora_service/video_sender.py +193 -0
- agora_python_server_sdk-1.1.0/pyproject.toml +4 -0
- agora_python_server_sdk-1.1.0/setup.cfg +4 -0
- 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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
agora_service
|
|
@@ -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
|
+
|