agora-python-server-sdk 2.0.2__tar.gz → 2.0.4__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.
- agora_python_server_sdk-2.0.4/PKG-INFO +53 -0
- agora_python_server_sdk-2.0.4/README.md +36 -0
- agora_python_server_sdk-2.0.4/agora/rtc/__init__.py +65 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/_audio_frame_observer.py +28 -40
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/_local_user_observer.py +38 -84
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/_rtc_connection_observer.py +37 -92
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/_video_encoded_frame_observer.py +3 -7
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/_video_frame_observer.py +8 -25
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/agora_base.py +5 -5
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/agora_service.py +31 -14
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/audio_encoded_frame_sender.py +5 -20
- agora_python_server_sdk-2.0.4/agora/rtc/audio_frame_observer.py +32 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/audio_vad.py +5 -4
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/globals.py +4 -4
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/local_audio_track.py +14 -24
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/local_user.py +17 -90
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/local_user_observer.py +1 -1
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/local_video_track.py +3 -7
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/media_node_factory.py +5 -5
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/remote_audio_track.py +3 -1
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/remote_video_track.py +5 -12
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/rtc_connection.py +13 -25
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/rtc_connection_observer.py +0 -10
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/video_encoded_frame_observer.py +0 -1
- agora_python_server_sdk-2.0.4/agora/rtc/video_encoded_image_sender.py +87 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/video_frame_observer.py +3 -0
- agora_python_server_sdk-2.0.4/agora/rtc/video_frame_sender.py +92 -0
- agora_python_server_sdk-2.0.4/agora_python_server_sdk.egg-info/PKG-INFO +53 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora_python_server_sdk.egg-info/SOURCES.txt +1 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/setup.py +14 -17
- agora_python_server_sdk-2.0.2/PKG-INFO +0 -76
- agora_python_server_sdk-2.0.2/README.md +0 -59
- agora_python_server_sdk-2.0.2/agora/rtc/__init__.py +0 -23
- agora_python_server_sdk-2.0.2/agora/rtc/audio_frame_observer.py +0 -50
- agora_python_server_sdk-2.0.2/agora/rtc/video_frame_sender.py +0 -198
- agora_python_server_sdk-2.0.2/agora_python_server_sdk.egg-info/PKG-INFO +0 -76
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/MANIFEST.in +0 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/agora_parameter.py +0 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/audio_pcm_data_sender.py +0 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora_python_server_sdk.egg-info/dependency_links.txt +0 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora_python_server_sdk.egg-info/top_level.txt +0 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/pyproject.toml +0 -0
- {agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/setup.cfg +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: agora_python_server_sdk
|
|
3
|
+
Version: 2.0.4
|
|
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
|
+
# Note
|
|
19
|
+
- This is a Python SDK wrapper for the Agora RTC SDK.
|
|
20
|
+
- It supports Linux and Mac platforms.
|
|
21
|
+
- The examples are provided as very simple demonstrations and are not recommended for use in production environments.
|
|
22
|
+
|
|
23
|
+
# Very Important Notice !!!
|
|
24
|
+
- A process can only have one instance.
|
|
25
|
+
- An instance can have multiple connections.
|
|
26
|
+
- 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.
|
|
27
|
+
|
|
28
|
+
# Required Operating Systems and Python Versions
|
|
29
|
+
- Supported Linux versions:
|
|
30
|
+
- Ubuntu 18.04 LTS and above
|
|
31
|
+
- CentOS 7.0 and above
|
|
32
|
+
|
|
33
|
+
- Supported Mac versions:
|
|
34
|
+
- MacOS 13 and above
|
|
35
|
+
|
|
36
|
+
- Python version:
|
|
37
|
+
- Python 3.8 and above
|
|
38
|
+
|
|
39
|
+
# Using Agora-Python-Server-SDK
|
|
40
|
+
```
|
|
41
|
+
pip install agora_python_server_sdk
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
# Running Examples
|
|
45
|
+
|
|
46
|
+
## Preparing Test Data
|
|
47
|
+
- Download and unzip [test_data.zip](https://download.agora.io/demo/test/test_data_202408221437.zip) to the Agora-Python-Server-SDK directory.
|
|
48
|
+
|
|
49
|
+
## Executing Test Script
|
|
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
|
|
52
|
+
```
|
|
53
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Note
|
|
2
|
+
- This is a Python SDK wrapper for the Agora RTC SDK.
|
|
3
|
+
- It supports Linux and Mac platforms.
|
|
4
|
+
- The examples are provided as very simple demonstrations and are not recommended for use in production environments.
|
|
5
|
+
|
|
6
|
+
# Very Important Notice !!!
|
|
7
|
+
- A process can only have one instance.
|
|
8
|
+
- An instance can have multiple connections.
|
|
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
|
+
|
|
11
|
+
# Required Operating Systems and Python Versions
|
|
12
|
+
- Supported Linux versions:
|
|
13
|
+
- Ubuntu 18.04 LTS and above
|
|
14
|
+
- CentOS 7.0 and above
|
|
15
|
+
|
|
16
|
+
- Supported Mac versions:
|
|
17
|
+
- MacOS 13 and above
|
|
18
|
+
|
|
19
|
+
- Python version:
|
|
20
|
+
- Python 3.8 and above
|
|
21
|
+
|
|
22
|
+
# Using Agora-Python-Server-SDK
|
|
23
|
+
```
|
|
24
|
+
pip install agora_python_server_sdk
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
# Running Examples
|
|
28
|
+
|
|
29
|
+
## Preparing Test Data
|
|
30
|
+
- Download and unzip [test_data.zip](https://download.agora.io/demo/test/test_data_202408221437.zip) to the Agora-Python-Server-SDK directory.
|
|
31
|
+
|
|
32
|
+
## Executing Test Script
|
|
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
|
|
35
|
+
```
|
|
36
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import logging
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
import ctypes
|
|
8
|
+
from urllib import request
|
|
9
|
+
import site
|
|
10
|
+
import zipfile
|
|
11
|
+
import ssl
|
|
12
|
+
ssl._create_default_https_context = ssl._create_unverified_context
|
|
13
|
+
|
|
14
|
+
def _check_download_and_extract_sdk():
|
|
15
|
+
agora_service_path = os.path.dirname(os.path.abspath(__file__))
|
|
16
|
+
sdk_dir = os.path.join(agora_service_path, "agora_sdk")
|
|
17
|
+
zip_path = os.path.join(agora_service_path, "agora_rtc_sdk.zip")
|
|
18
|
+
|
|
19
|
+
url = "https://download.agora.io/sdk/release/agora_rtc_sdk_linux_v4.4.30-20240928_160128-358664.zip"
|
|
20
|
+
libagora_rtc_sdk_path = os.path.join(sdk_dir, "libagora_rtc_sdk.so")
|
|
21
|
+
if sys.platform == 'darwin':
|
|
22
|
+
url = "https://download.agora.io/sdk/release/agora_sdk_mac_v4.4.30_22119_FULL_20240928_1647_358680.zip"
|
|
23
|
+
libagora_rtc_sdk_path = os.path.join(sdk_dir, "libAgoraRtcKit.dylib")
|
|
24
|
+
|
|
25
|
+
if os.path.exists(libagora_rtc_sdk_path):
|
|
26
|
+
return
|
|
27
|
+
|
|
28
|
+
logger.error("missing agora sdk, now download it, please wait for a while...")
|
|
29
|
+
if os.path.exists(sdk_dir):
|
|
30
|
+
os.system(f"rm -rf {sdk_dir}")
|
|
31
|
+
os.makedirs(agora_service_path, exist_ok=True)
|
|
32
|
+
if os.path.exists(zip_path):
|
|
33
|
+
os.remove(zip_path)
|
|
34
|
+
|
|
35
|
+
logger.info(f"agora_service_path: {agora_service_path}")
|
|
36
|
+
logger.info(f"Downloading {url}...")
|
|
37
|
+
request.urlretrieve(url, zip_path)
|
|
38
|
+
|
|
39
|
+
logger.info(f"Extracting {zip_path}...")
|
|
40
|
+
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
|
41
|
+
zip_ref.extractall(agora_service_path)
|
|
42
|
+
|
|
43
|
+
if os.path.exists(zip_path):
|
|
44
|
+
os.remove(zip_path)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
_check_download_and_extract_sdk()
|
|
48
|
+
|
|
49
|
+
sdk_dir = os.path.dirname(os.path.abspath(__file__))
|
|
50
|
+
lib_path = os.path.join(sdk_dir, 'agora_sdk')
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
if sys.platform == 'darwin':
|
|
54
|
+
lib_agora_rtc_path =os.path.join(lib_path, 'libAgoraRtcKit.dylib')
|
|
55
|
+
agora_lib = ctypes.CDLL(lib_agora_rtc_path)
|
|
56
|
+
|
|
57
|
+
elif sys.platform == 'linux':
|
|
58
|
+
lib_agora_rtc_path =os.path.join(lib_path, 'libagora_rtc_sdk.so')
|
|
59
|
+
ctypes.CDLL(os.path.join(lib_path, 'libagora-fdkaac.so'))
|
|
60
|
+
ctypes.CDLL(os.path.join(lib_path, 'libaosl.so'))
|
|
61
|
+
agora_lib = ctypes.CDLL(lib_agora_rtc_path)
|
|
62
|
+
except OSError as e:
|
|
63
|
+
logger.error(f"Error loading the library: {e}")
|
|
64
|
+
logger.error(f"Attempted to load from: {lib_agora_rtc_path}")
|
|
65
|
+
sys.exit(1)
|
{agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/_audio_frame_observer.py
RENAMED
|
@@ -3,6 +3,8 @@ from .agora_base import *
|
|
|
3
3
|
from .local_user import *
|
|
4
4
|
import ctypes
|
|
5
5
|
from .audio_frame_observer import *
|
|
6
|
+
import logging
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class AudioFrameInner(ctypes.Structure):
|
|
@@ -14,7 +16,12 @@ class AudioFrameInner(ctypes.Structure):
|
|
|
14
16
|
("samples_per_sec", ctypes.c_int),
|
|
15
17
|
("buffer", ctypes.c_void_p),
|
|
16
18
|
("render_time_ms", ctypes.c_int64),
|
|
17
|
-
("avsync_type", ctypes.c_int)
|
|
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)
|
|
18
25
|
]
|
|
19
26
|
def _to_audio_frame(self):
|
|
20
27
|
audio_frame = AudioFrame()
|
|
@@ -27,6 +34,12 @@ class AudioFrameInner(ctypes.Structure):
|
|
|
27
34
|
audio_frame.buffer = bytearray(cdata)
|
|
28
35
|
audio_frame.render_time_ms = self.render_time_ms
|
|
29
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
|
+
|
|
30
43
|
return audio_frame
|
|
31
44
|
|
|
32
45
|
|
|
@@ -73,31 +86,31 @@ class AudioFrameObserverInner(ctypes.Structure):
|
|
|
73
86
|
# self.on_get_ear_monitoring_audio_frame_param = ON_GET_EAR_MONITORING_AUDIO_FRAME_PARAM_CALLBACK(self._on_get_ear_monitoring_audio_frame_param)
|
|
74
87
|
|
|
75
88
|
def _on_record_audio_frame(self, local_user_handle, channel_id, audio_frame_inner):
|
|
76
|
-
|
|
89
|
+
logger.debug(f"AudioFrameObserverInner _on_record_audio_frame: {local_user_handle}, {channel_id}, {audio_frame_inner}")
|
|
77
90
|
channel_id_str = channel_id.decode('utf-8')
|
|
78
91
|
frame = audio_frame_inner.contents._to_audio_frame()
|
|
79
92
|
ret = self.observer.on_record_audio_frame(self.local_user, channel_id_str, frame)
|
|
80
93
|
return ret
|
|
81
94
|
|
|
82
95
|
def _on_playback_audio_frame(self, local_user_handle, channel_id, audio_frame_inner):
|
|
83
|
-
|
|
96
|
+
logger.debug(f"AudioFrameObserverInner _on_playback_audio_frame: {local_user_handle}, {channel_id}, {audio_frame_inner}")
|
|
84
97
|
channel_id_str = channel_id.decode('utf-8')
|
|
85
98
|
frame = audio_frame_inner.contents._to_audio_frame()
|
|
86
99
|
ret = self.observer.on_playback_audio_frame(self.local_user, channel_id_str, frame)
|
|
87
100
|
return ret
|
|
88
101
|
|
|
89
102
|
def _on_mixed_audio_frame(self, local_user_handle, channel_id, audio_frame_inner):
|
|
90
|
-
|
|
103
|
+
logger.debug(f"AudioFrameObserverInner _on_mixed_audio_frame: {local_user_handle}, {channel_id}, {audio_frame_inner}")
|
|
91
104
|
ret = self.observer.on_mixed_audio_frame(self.local_user, audio_frame_inner)
|
|
92
105
|
return ret
|
|
93
106
|
|
|
94
107
|
def _on_ear_monitoring_audio_frame(self, local_user_handle, audio_frame_inner):
|
|
95
|
-
|
|
108
|
+
logger.debug(f"AudioFrameObserverInner _on_ear_monitoring_audio_frame: {local_user_handle}, {audio_frame_inner}")
|
|
96
109
|
ret = self.observer.on_ear_monitoring_audio_frame(self.local_user, audio_frame_inner)
|
|
97
110
|
return ret
|
|
98
111
|
|
|
99
112
|
def _on_playback_audio_frame_before_mixing(self, local_user_handle, channel_id, user_id, audio_frame_inner):
|
|
100
|
-
#
|
|
113
|
+
#logger.debug(f"AudioFrameObserverInner _on_playback_audio_frame_before_mixing: {local_user_handle}, {channel_id}, {user_id}, {audio_frame_inner}")
|
|
101
114
|
if channel_id is None:
|
|
102
115
|
channel_id_str = ""
|
|
103
116
|
else:
|
|
@@ -109,47 +122,22 @@ class AudioFrameObserverInner(ctypes.Structure):
|
|
|
109
122
|
return ret
|
|
110
123
|
|
|
111
124
|
def _on_get_audio_frame_position(self, local_user_handle):
|
|
112
|
-
|
|
113
|
-
return 0
|
|
125
|
+
logger.debug(f"AudioFrameObserverInner _on_get_audio_frame_position: {local_user_handle}")
|
|
114
126
|
return self.observer.on_get_audio_frame_position(self.local_user)
|
|
115
127
|
|
|
116
|
-
def _on_get_playback_audio_frame_param(self, local_user_handle):
|
|
117
|
-
|
|
118
|
-
params = AudioParams()
|
|
119
|
-
params.sample_rate = 16000 # 示例值
|
|
120
|
-
params.channels = 1 # 示例值
|
|
121
|
-
params.mode = 0 # 示例值
|
|
122
|
-
params.samples_per_call = 1024 # 示例值
|
|
123
|
-
return params
|
|
128
|
+
def _on_get_playback_audio_frame_param(self, local_user_handle) -> AudioParams:
|
|
129
|
+
logger.debug(f"AudioFrameObserverInner _on_get_playback_audio_frame_param: {local_user_handle}")
|
|
124
130
|
return self.observer.on_get_playback_audio_frame_param(self.local_user)
|
|
125
131
|
|
|
126
|
-
def _on_get_record_audio_frame_param(self, local_user_handle):
|
|
127
|
-
|
|
128
|
-
params = AudioParams()
|
|
129
|
-
params.sample_rate = 16000 # 示例值
|
|
130
|
-
params.channels = 1 # 示例值
|
|
131
|
-
params.mode = 0 # 示例值
|
|
132
|
-
params.samples_per_call = 1024 # 示例值
|
|
133
|
-
return params
|
|
132
|
+
def _on_get_record_audio_frame_param(self, local_user_handle) -> AudioParams:
|
|
133
|
+
logger.debug(f"AudioFrameObserverInner _on_get_record_audio_frame_param: {local_user_handle}")
|
|
134
134
|
return self.observer.on_get_record_audio_frame_param(self.local_user)
|
|
135
135
|
|
|
136
|
-
def _on_get_mixed_audio_frame_param(self, local_user_handle):
|
|
137
|
-
|
|
138
|
-
params = AudioParams()
|
|
139
|
-
params.sample_rate = 16000 # 示例值
|
|
140
|
-
params.channels = 1 # 示例值
|
|
141
|
-
params.mode = 0 # 示例值
|
|
142
|
-
params.samples_per_call = 1024 # 示例值
|
|
143
|
-
return params
|
|
136
|
+
def _on_get_mixed_audio_frame_param(self, local_user_handle) -> AudioParams:
|
|
137
|
+
logger.debug(f"AudioFrameObserverInner _on_get_mixed_audio_frame_param: {local_user_handle}")
|
|
144
138
|
return self.observer.on_get_mixed_audio_frame_param(self.local_user)
|
|
145
139
|
|
|
146
|
-
def _on_get_ear_monitoring_audio_frame_param(self, local_user_handle):
|
|
147
|
-
|
|
148
|
-
params = AudioParams()
|
|
149
|
-
params.sample_rate = 16000 # 示例值
|
|
150
|
-
params.channels = 1 # 示例值
|
|
151
|
-
params.mode = 0 # 示例值
|
|
152
|
-
params.samples_per_call = 1024 # 示例值
|
|
153
|
-
return params
|
|
140
|
+
def _on_get_ear_monitoring_audio_frame_param(self, local_user_handle) -> AudioParams:
|
|
141
|
+
logger.debug(f"AudioFrameObserverInner _on_get_ear_monitoring_audio_frame_param: {local_user_handle}")
|
|
154
142
|
return self.observer.on_get_ear_monitoring_audio_frame_param(self.local_user)
|
|
155
143
|
|
{agora_python_server_sdk-2.0.2 → agora_python_server_sdk-2.0.4}/agora/rtc/_local_user_observer.py
RENAMED
|
@@ -3,12 +3,8 @@ from .agora_base import *
|
|
|
3
3
|
from .local_user import *
|
|
4
4
|
from .remote_audio_track import RemoteAudioTrack, RemoteAudioTrackStats
|
|
5
5
|
from .remote_video_track import RemoteVideoTrack, RemoteVideoTrackStats
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
#========localuser observer=====
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
import logging
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
12
8
|
|
|
13
9
|
class VideoTrackInfoInner(ctypes.Structure):
|
|
14
10
|
_fields_ = [
|
|
@@ -52,7 +48,6 @@ class RemoteVideoStreamInfo(ctypes.Structure):
|
|
|
52
48
|
("total_downscale_level_counts", ctypes.c_uint8)
|
|
53
49
|
]
|
|
54
50
|
|
|
55
|
-
# 定义回调函数类型
|
|
56
51
|
ON_AUDIO_TRACK_PUBLISH_SUCCESS_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE, AGORA_HANDLE)
|
|
57
52
|
ON_AUDIO_TRACK_PUBLISH_START_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE, AGORA_HANDLE)
|
|
58
53
|
ON_AUDIO_TRACK_UNPUBLISHED_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE, AGORA_HANDLE)
|
|
@@ -91,31 +86,6 @@ ON_REMOTE_SUBSCRIBE_FALLBACK_TO_AUDIO_ONLY_CALLBACK = ctypes.CFUNCTYPE(None, AGO
|
|
|
91
86
|
ON_STREAM_MESSAGE_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE, user_id_t, ctypes.c_int, ctypes.c_char_p, ctypes.c_size_t)
|
|
92
87
|
ON_USER_STATE_CHANGED_CALLBACK = ctypes.CFUNCTYPE(None, AGORA_HANDLE, user_id_t, ctypes.c_uint32)
|
|
93
88
|
|
|
94
|
-
|
|
95
|
-
"""
|
|
96
|
-
on_user_info_updated(user_id_t: string ; msg: int, val: int)
|
|
97
|
-
msg:
|
|
98
|
-
enum USER_MEDIA_INFO {
|
|
99
|
-
/**
|
|
100
|
-
* 0: The user has muted the audio.
|
|
101
|
-
*/
|
|
102
|
-
USER_MEDIA_INFO_MUTE_AUDIO = 0,
|
|
103
|
-
/**
|
|
104
|
-
* 1: The user has muted the video.
|
|
105
|
-
*/
|
|
106
|
-
USER_MEDIA_INFO_MUTE_VIDEO = 1,
|
|
107
|
-
/**
|
|
108
|
-
* 4: The user has enabled the video, which includes video capturing and encoding.
|
|
109
|
-
*/
|
|
110
|
-
USER_MEDIA_INFO_ENABLE_VIDEO = 4,
|
|
111
|
-
/**
|
|
112
|
-
* 8: The user has enabled the local video capturing.
|
|
113
|
-
*/
|
|
114
|
-
USER_MEDIA_INFO_ENABLE_LOCAL_VIDEO = 8,
|
|
115
|
-
};
|
|
116
|
-
val: 1: The user has muted the audio.0: unmuted the audio
|
|
117
|
-
参考:https://doc.shengwang.cn/api-ref/rtc-server-sdk/cpp/classagora_1_1rtc_1_1_i_local_user_observer#onUserInfoUpdated()
|
|
118
|
-
"""
|
|
119
89
|
class RTCLocalUserObserverInner(ctypes.Structure):
|
|
120
90
|
_fields_ = [
|
|
121
91
|
("on_audio_track_publish_success", ON_AUDIO_TRACK_PUBLISH_SUCCESS_CALLBACK),
|
|
@@ -208,63 +178,49 @@ class RTCLocalUserObserverInner(ctypes.Structure):
|
|
|
208
178
|
Avoid to create a global LocalAudioTrack map table as it can significantly impact performance .
|
|
209
179
|
"""
|
|
210
180
|
def _on_audio_track_publish_success(self, local_user_handle, local_audio_track_handle):
|
|
211
|
-
|
|
181
|
+
logger.debug(f"LocalUserCB _on_audio_track_publish_success: {local_user_handle}, {local_audio_track_handle}")
|
|
212
182
|
#note: to get
|
|
213
183
|
audio_track = self.local_user.get_audio_map(local_audio_track_handle)
|
|
214
184
|
self.local_user_observer.on_audio_track_publish_success(self.local_user, audio_track)
|
|
215
185
|
|
|
216
186
|
def _on_video_track_publish_success(self, local_user_handle, local_video_track_handle):
|
|
217
|
-
|
|
187
|
+
logger.debug(f"LocalUserCB _on_video_track_publish_success: {local_user_handle}, {local_video_track_handle}")
|
|
218
188
|
video_track = self.local_user.get_video_map(local_video_track_handle)
|
|
219
189
|
self.local_user_observer.on_video_track_publish_success(self.local_user, video_track)
|
|
220
190
|
|
|
221
191
|
def _on_video_track_publish_start(self, local_user_handle, local_video_track_handle):
|
|
222
|
-
|
|
192
|
+
logger.debug(f"LocalUserCB _on_video_track_publish_start: {local_user_handle}, {local_video_track_handle}")
|
|
223
193
|
video_track = self.local_user.get_video_map(local_video_track_handle)
|
|
224
194
|
self.local_user_observer.on_video_track_publish_start(self.local_user, video_track)
|
|
225
195
|
|
|
226
196
|
def _on_audio_track_publish_start(self, local_user_handle, local_audio_track_handle):
|
|
227
|
-
|
|
197
|
+
logger.debug(f"LocalUserCB _on_audio_track_publish_start: {local_user_handle}, {local_audio_track_handle}")
|
|
228
198
|
audio_track = self.local_user.get_audio_map(local_audio_track_handle)
|
|
229
199
|
self.local_user_observer.on_audio_track_publish_start(self.local_user, audio_track)
|
|
230
200
|
|
|
231
201
|
def _on_audio_track_unpublished(self, local_user_handle, local_audio_track_handle):
|
|
232
|
-
|
|
202
|
+
logger.debug(f"LocalUserCB _on_audio_track_unpublished: {local_user_handle}, {local_audio_track_handle}")
|
|
233
203
|
audio_track = self.local_user.get_audio_map(local_audio_track_handle)
|
|
234
204
|
self.local_user._del_audio_map(local_audio_track_handle)
|
|
235
205
|
self.local_user_observer.on_audio_track_unpublished(self.local_user, audio_track)
|
|
236
206
|
|
|
237
207
|
def _on_audio_track_publication_failure(self, local_user_handle, local_audio_track_handle, error_code):
|
|
238
|
-
|
|
208
|
+
logger.debug(f"LocalUserCB _on_audio_track_publication_failure: {local_user_handle}, {local_audio_track_handle}, {error_code}")
|
|
239
209
|
audio_track = self.local_user.get_audio_map(local_audio_track_handle)
|
|
240
|
-
#note :move from map for failed publish
|
|
241
210
|
self.local_user.del_audio_map(local_audio_track_handle)
|
|
242
211
|
self.local_user_observer.on_audio_track_publication_failure(self.local_user, audio_track, error_code)
|
|
243
212
|
|
|
244
213
|
def _on_local_audio_track_state_changed(self, local_user_handle, local_audio_track_handle, state, error):
|
|
245
|
-
|
|
214
|
+
logger.debug(f"LocalUserCB _on_local_audio_track_state_changed: {local_user_handle}, {local_audio_track_handle}, {state}, {error}")
|
|
246
215
|
audio_track = self.local_user.get_audio_map(local_audio_track_handle)
|
|
247
216
|
self.local_user_observer.on_local_audio_track_state_changed(self.local_user, audio_track, state, error)
|
|
248
217
|
|
|
249
218
|
def _on_local_audio_track_statistics(self, local_user_handle, stats):
|
|
250
|
-
#print("LocalUserCB _on_local_audio_track_statistics:", local_user_handle, stats)
|
|
251
|
-
#stats: pointer to LocalAudioStats
|
|
252
219
|
local_audio_stats = stats.contents
|
|
253
220
|
self.local_user_observer.on_local_audio_track_statistics(self.local_user, local_audio_stats)
|
|
254
|
-
|
|
255
|
-
"""
|
|
256
|
-
# 在LocalUser中是通过LocalUser.sub_audio(uid) 创建的,所以这里直接用uid来获取对应的RemoteAudioTrack
|
|
257
|
-
# 也就是说从app层的视角,对audio的区分是uid,但这边的回调并没有userid,所以对app层是不太友好的
|
|
258
|
-
# 也就是需要在LocalUser层中建立一个map表,用来记录userid和handle
|
|
259
|
-
# 然后在回调中,通过handle,找到uid,然后call 给app层的是uid
|
|
260
|
-
# 这样的话,在LocalUser层,就可以直接通过uid来获取对应的RemoteAudioTrack
|
|
261
|
-
"""
|
|
262
|
-
#
|
|
263
|
-
# _on_user_audio_track_subscribed:in LocalUser to do sub(userid), and in this call back it pass out with
|
|
264
|
-
# user_id & remote_audio_track_handle, so we should construct RemoteAudioTrack with (user_id & remote_audio_track_handle
|
|
265
|
-
# and save it in local_user, then in app layer, we can get RemoteAudioTrack with userid)
|
|
221
|
+
|
|
266
222
|
def _on_user_audio_track_subscribed(self, local_user_handle, user_id, remote_audio_track_handle):
|
|
267
|
-
|
|
223
|
+
logger.debug(f"LocalUserCB _on_user_audio_track_subscribed: {local_user_handle}, {user_id}, {remote_audio_track_handle}")
|
|
268
224
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
269
225
|
# note: this is a pointer to agora::rtc::IRemoteAudioTrack
|
|
270
226
|
remote_audio_track = RemoteAudioTrack(remote_audio_track_handle, user_id_str)
|
|
@@ -273,65 +229,63 @@ class RTCLocalUserObserverInner(ctypes.Structure):
|
|
|
273
229
|
self.local_user_observer.on_user_audio_track_subscribed(self.local_user, user_id_str, remote_audio_track)
|
|
274
230
|
|
|
275
231
|
def _on_remote_audio_track_statistics(self, local_user_handle, remote_audio_track_handle, stats):
|
|
276
|
-
|
|
232
|
+
logger.debug(f"LocalUserCB _on_remote_audio_track_statistics: {local_user_handle}, {remote_audio_track_handle}, {stats}")
|
|
277
233
|
audio_stats = stats.contents #RemoteAudioTrackStats
|
|
278
234
|
remote_audio_track = self.local_user.get_remote_audio_map(remote_audio_track_handle)
|
|
279
235
|
self.local_user_observer.on_remote_audio_track_statistics(self.local_user, remote_audio_track, audio_stats)
|
|
280
236
|
|
|
281
|
-
|
|
282
237
|
def _on_user_audio_track_state_changed(self, local_user_handle, user_id, remote_audio_track_handle, state, reason, elapsed):
|
|
283
|
-
|
|
238
|
+
logger.debug(f"LocalUserCB _on_user_audio_track_state_changed: {local_user_handle}, {user_id}, {remote_audio_track_handle}, {state}, {reason}, {elapsed}")
|
|
284
239
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
285
240
|
remote_audio_track = self.local_user.get_remote_audio_map(remote_audio_track_handle)
|
|
286
241
|
self.local_user_observer.on_user_audio_track_state_changed(self.local_user, user_id_str, remote_audio_track, state, reason, elapsed)
|
|
287
242
|
|
|
288
243
|
def _on_audio_subscribe_state_changed(self, local_user_handle, channel_id, user_id, state, reason, elapsed):
|
|
289
|
-
|
|
244
|
+
logger.debug(f"LocalUserCB _on_audio_subscribe_state_changed: {local_user_handle}, {channel_id}, {user_id}, {state}, {reason}, {elapsed}")
|
|
290
245
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
291
246
|
channel_id_str = channel_id.decode('utf-8') if channel_id else ""
|
|
292
247
|
self.local_user_observer.on_audio_subscribe_state_changed(self.local_user, channel_id_str, user_id_str, state, reason, elapsed)
|
|
293
248
|
|
|
294
249
|
def _on_audio_publish_state_changed(self, local_user_handle, channel_id, state, reason, elapsed):
|
|
295
|
-
|
|
250
|
+
logger.debug(f"LocalUserCB _on_audio_publish_state_changed: {local_user_handle}, {channel_id}, {state}, {reason}, {elapsed}")
|
|
296
251
|
channel_id_str = channel_id.decode('utf-8') if channel_id else ""
|
|
297
252
|
self.local_user_observer.on_audio_publish_state_changed(self.local_user, channel_id_str, state, reason, elapsed)
|
|
298
253
|
|
|
299
254
|
def _on_first_remote_audio_frame(self, local_user_handle, user_id, elapsed):
|
|
300
|
-
|
|
255
|
+
logger.debug(f"LocalUserCB _on_first_remote_audio_frame: {local_user_handle}, {user_id}, {elapsed}")
|
|
301
256
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
302
257
|
self.local_user_observer.on_first_remote_audio_frame(self.local_user, user_id_str, elapsed)
|
|
303
258
|
|
|
304
259
|
def _on_first_remote_audio_decoded(self, local_user_handle, user_id, elapsed):
|
|
305
|
-
|
|
260
|
+
logger.debug(f"LocalUserCB _on_first_remote_audio_decoded: {local_user_handle}, {user_id}, {elapsed}")
|
|
306
261
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
307
262
|
self.local_user_observer.on_first_remote_audio_decoded(self.local_user, user_id_str, elapsed)
|
|
308
263
|
|
|
309
264
|
def _on_video_track_unpublished(self, local_user_handle, local_video_track_handle):
|
|
310
|
-
|
|
265
|
+
logger.debug(f"LocalUserCB _on_video_track_unpublished: {local_user_handle}, {local_video_track_handle}")
|
|
311
266
|
local_video_track = self.local_user.get_video_map(local_video_track_handle)
|
|
312
267
|
#and then remove it from the local user
|
|
313
268
|
self.local_user.del_video_map(local_video_track_handle)
|
|
314
269
|
self.local_user_observer.on_video_track_unpublished(self.local_user, local_video_track)
|
|
315
270
|
|
|
316
271
|
def _on_video_track_publication_failure(self, local_user_handle, local_video_track_handle, error_code):
|
|
317
|
-
|
|
272
|
+
logger.debug(f"LocalUserCB _on_video_track_publication_failure: {local_user_handle}, {local_video_track_handle}, {error_code}")
|
|
318
273
|
local_video_track = self.local_user.get_video_map(local_video_track_handle)
|
|
319
274
|
self.local_user_observer.on_video_track_publication_failure(self.local_user, local_video_track, error_code)
|
|
320
275
|
|
|
321
276
|
def _on_local_video_track_state_changed(self, local_user_handle, local_video_track_handle, state, error):
|
|
322
|
-
|
|
277
|
+
logger.debug(f"LocalUserCB _on_local_video_track_state_changed: {local_user_handle}, {local_video_track_handle}, {state}, {error}")
|
|
323
278
|
local_video_track = self.local_user.get_video_map(local_video_track_handle)
|
|
324
279
|
self.local_user_observer.on_local_video_track_state_changed(self.local_user, local_video_track, state, error)
|
|
325
280
|
|
|
326
281
|
def _on_local_video_track_statistics(self, local_user_handle, local_video_track_handle, stats):
|
|
327
|
-
|
|
282
|
+
logger.debug(f"LocalUserCB _on_local_video_track_statistics: {local_user_handle}, {local_video_track_handle}, {stats}")
|
|
328
283
|
#stats: ctypes.pointer to LocalVideoTrackStats
|
|
329
284
|
local_video_track = self.local_user.get_video_map(local_video_track_handle)
|
|
330
285
|
video_stats = stats.contents
|
|
331
286
|
self.local_user_observer.on_local_video_track_statistics(self.local_user, local_video_track, video_stats)
|
|
332
|
-
# # #ctypes.CFUNCTYPE(None, AGORA_HANDLE, user_id_t, ctypes.POINTER(VideoTrackInfo), AGORA_HANDLE)
|
|
333
287
|
def _on_user_video_track_subscribed(self, local_user_handle, user_id, video_track_info, remote_video_track_handle):
|
|
334
|
-
|
|
288
|
+
logger.debug(f"LocalUserCB _on_user_video_track_subscribed: {local_user_handle}, {user_id}, {remote_video_track_handle}, {video_track_info}")
|
|
335
289
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
336
290
|
# track_info = video_track_info.contents._to_track_info()
|
|
337
291
|
track_info = video_track_info.contents #videoTrackInfo
|
|
@@ -343,79 +297,79 @@ class RTCLocalUserObserverInner(ctypes.Structure):
|
|
|
343
297
|
self.local_user_observer.on_user_video_track_subscribed(self.local_user, user_id_str, track_info, remote_video_track)
|
|
344
298
|
|
|
345
299
|
def _on_user_video_track_state_changed(self, local_user_handle, user_id, remote_video_track_handle, state, reason, elapsed):
|
|
346
|
-
|
|
300
|
+
logger.debug(f"LocalUserCB _on_user_video_track_state_changed: {local_user_handle}, {user_id}, {remote_video_track_handle}, {state}, {reason}, {elapsed}")
|
|
347
301
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
348
302
|
video_track = self.local_user.get_remote_video_map(remote_video_track_handle)
|
|
349
303
|
self.local_user_observer.on_user_video_track_state_changed(self.local_user, user_id_str, video_track, state, reason, elapsed)
|
|
350
304
|
|
|
351
305
|
def _on_remote_video_track_statistics(self, local_user_handle, remote_video_track_handle, stats_ptr):
|
|
352
|
-
|
|
306
|
+
logger.debug(f"LocalUserCB _on_remote_video_track_statistics: {local_user_handle}, {remote_video_track_handle}, {stats_ptr}")
|
|
353
307
|
remote_stats = stats_ptr.contents #RemoteVideoTrackStats
|
|
354
308
|
video_track = self.local_user.get_remote_video_map(remote_video_track_handle)
|
|
355
309
|
self.local_user_observer.on_remote_video_track_statistics(self.local_user, video_track, remote_stats)
|
|
356
310
|
|
|
357
311
|
def _on_audio_volume_indication(self, local_user_handle, audio_volume_info_ptr, speaker_number, total_volume):
|
|
358
|
-
|
|
312
|
+
logger.debug(f"LocalUserCB _on_audio_volume_indication: {local_user_handle}, {audio_volume_info_ptr}, {speaker_number}, {total_volume}")
|
|
359
313
|
audio_volume_info = audio_volume_info_ptr.contents
|
|
360
314
|
self.local_user_observer.on_audio_volume_indication(self.local_user, audio_volume_info, speaker_number, total_volume)
|
|
361
315
|
|
|
362
316
|
def _on_active_speaker(self, local_user_handle, user_id):
|
|
363
|
-
|
|
317
|
+
logger.debug(f"LocalUserCB _on_active_speaker: {local_user_handle}, {user_id}")
|
|
364
318
|
user_id_str = user_id.decode('utf-8')
|
|
365
319
|
self.local_user_observer.on_active_speaker(self.local_user, user_id_str)
|
|
366
320
|
|
|
367
321
|
def _on_remote_video_stream_info_updated(self, local_user_handle, remote_video_stream_info_ptr):
|
|
368
|
-
|
|
322
|
+
logger.debug(f"LocalUserCB _on_remote_video_stream_info_updated: {local_user_handle}, {remote_video_stream_info_ptr}")
|
|
369
323
|
video_stream_info = remote_video_stream_info_ptr.contents
|
|
370
324
|
self.local_user_observer.on_remote_video_stream_info_updated(self.local_user, video_stream_info)
|
|
371
325
|
|
|
372
326
|
def _on_video_subscribe_state_changed(self, local_user_handle, channel_id, user_id, state, reason, elapsed):
|
|
373
|
-
|
|
327
|
+
logger.debug(f"LocalUserCB _on_video_subscribe_state_changed: {local_user_handle}, {channel_id}, {user_id}, {state}, {reason}, {elapsed}")
|
|
374
328
|
user_id_str = user_id.decode('utf-8')
|
|
375
329
|
channel_id_str = channel_id.decode('utf-8')
|
|
376
330
|
self.local_user_observer.on_video_subscribe_state_changed(self.local_user, channel_id_str, user_id_str, state, reason, elapsed)
|
|
377
331
|
|
|
378
332
|
def _on_video_publish_state_changed(self, local_user_handle, channel_id, state, reason, elapsed):
|
|
379
|
-
|
|
333
|
+
logger.debug(f"LocalUserCB _on_video_publish_state_changed: {local_user_handle}, {channel_id}, {state}, {reason}, {elapsed}")
|
|
380
334
|
channel_id_str = channel_id.decode('utf-8')
|
|
381
335
|
self.local_user_observer.on_video_publish_state_changed(self.local_user, channel_id_str, state, reason, elapsed)
|
|
382
336
|
|
|
383
337
|
def _on_first_remote_video_frame(self, local_user_handle, user_id, width, height, elapsed):
|
|
384
|
-
|
|
338
|
+
logger.debug(f"LocalUserCB _on_first_remote_video_frame: {local_user_handle}, {user_id}, {width}, {height}, {elapsed}")
|
|
385
339
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
386
340
|
self.local_user_observer.on_first_remote_video_frame(self.local_user, user_id_str, width, height, elapsed)
|
|
387
341
|
|
|
388
342
|
def _on_first_remote_video_decoded(self, local_user_handle, user_id, width, height, elapsed):
|
|
389
|
-
|
|
343
|
+
logger.debug(f"LocalUserCB _on_first_remote_video_decoded: {local_user_handle}, {user_id}, {width}, {height}, {elapsed}")
|
|
390
344
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
391
345
|
self.local_user_observer.on_first_remote_video_decoded(self.local_user, user_id_str, width, height, elapsed)
|
|
392
346
|
|
|
393
347
|
def _on_first_remote_video_frame_rendered(self, local_user_handle, user_id, width, height, elapsed):
|
|
394
|
-
|
|
348
|
+
logger.debug(f"LocalUserCB _on_first_remote_video_frame_rendered: {local_user_handle}, {user_id}, {width}, {height}, {elapsed}")
|
|
395
349
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
396
350
|
self.local_user_observer.on_first_remote_video_frame_rendered(self.local_user, user_id_str, width, height, elapsed)
|
|
397
351
|
|
|
398
352
|
def _on_video_size_changed(self, local_user_handle, user_id, width, height, elapsed):
|
|
399
|
-
|
|
353
|
+
logger.debug(f"LocalUserCB _on_video_size_changed: {local_user_handle}, {user_id}, {width}, {height}, {elapsed}")
|
|
400
354
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
401
355
|
self.local_user_observer.on_video_size_changed(self.local_user, user_id_str, width, height, elapsed)
|
|
402
356
|
|
|
403
357
|
def _on_user_info_updated(self, local_user_handle, user_id, msg, val):
|
|
404
|
-
|
|
358
|
+
logger.debug(f"LocalUserCB _on_user_info_updated: {local_user_handle}, {user_id}, {msg}, {val}")
|
|
405
359
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
406
360
|
self.local_user_observer.on_user_info_updated(self.local_user, user_id_str, msg, val)
|
|
407
361
|
|
|
408
362
|
def _on_intra_request_received(self, local_user_handle):
|
|
409
|
-
|
|
363
|
+
logger.debug(f"LocalUserCB _on_intra_request_received: {local_user_handle}")
|
|
410
364
|
self.local_user_observer.on_intra_request_received(self.local_user)
|
|
411
365
|
|
|
412
366
|
def _on_remote_subscribe_fallback_to_audio_only(self, local_user_handle, user_id, is_fallback):
|
|
413
|
-
|
|
367
|
+
logger.debug(f"LocalUserCB _on_remote_subscribe_fallback_to_audio_only: {local_user_handle}, {user_id}, {is_fallback}")
|
|
414
368
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
415
369
|
self.local_user_observer.on_remote_subscribe_fallback_to_audio_only(self.local_user, user_id_str, is_fallback)
|
|
416
370
|
|
|
417
371
|
def _on_stream_message(self, local_user_handle, user_id, stream_id, data, size):
|
|
418
|
-
|
|
372
|
+
logger.debug(f"LocalUserCB _on_stream_message: {local_user_handle}, {user_id}, {stream_id}, {data}, {size}")
|
|
419
373
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
420
374
|
bytes_from_c = ctypes.string_at(data, size)
|
|
421
375
|
data_byte_array = bytearray(bytes_from_c).decode()
|
|
@@ -423,7 +377,7 @@ class RTCLocalUserObserverInner(ctypes.Structure):
|
|
|
423
377
|
self.local_user_observer.on_stream_message(self.local_user, user_id_str, stream_id, data_byte_array, size)
|
|
424
378
|
|
|
425
379
|
def _on_user_state_changed(self, local_user_handle, user_id, state):
|
|
426
|
-
|
|
380
|
+
logger.debug(f"LocalUserCB _on_user_state_changed: {local_user_handle}, {user_id}, {state}")
|
|
427
381
|
user_id_str = user_id.decode('utf-8') if user_id else ""
|
|
428
382
|
self.local_user_observer.on_user_state_changed(self.local_user, user_id_str, state)
|
|
429
383
|
|