sora-sdk 2025.5.0.dev3__tar.gz → 2025.5.0.dev4__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 sora-sdk might be problematic. Click here for more details.

Files changed (49) hide show
  1. {sora_sdk-2025.5.0.dev3/src/sora_sdk.egg-info → sora_sdk-2025.5.0.dev4}/PKG-INFO +1 -1
  2. sora_sdk-2025.5.0.dev4/VERSION +1 -0
  3. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/src/sora_sdk/sora_sdk_ext.cpython-311-darwin.so +0 -0
  4. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4/src/sora_sdk.egg-info}/PKG-INFO +1 -1
  5. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_amd_amf.py +1 -1
  6. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_intel_vpl.py +1 -1
  7. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_nvidia_video_codec.py +1 -1
  8. sora_sdk-2025.5.0.dev4/tests/test_raspberry_pi.py +223 -0
  9. sora_sdk-2025.5.0.dev3/VERSION +0 -1
  10. sora_sdk-2025.5.0.dev3/tests/test_raspberry_pi.py +0 -98
  11. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/LICENSE +0 -0
  12. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/MANIFEST.in +0 -0
  13. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/README.md +0 -0
  14. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/buildbase.py +0 -0
  15. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/pypath.py +0 -0
  16. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/pyproject.toml +0 -0
  17. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/run.py +0 -0
  18. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/setup.cfg +0 -0
  19. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/setup.py +0 -0
  20. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/src/sora_sdk/__init__.py +0 -0
  21. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/src/sora_sdk/py.typed +0 -0
  22. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/src/sora_sdk/sora_sdk_ext.pyi +0 -0
  23. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/src/sora_sdk.egg-info/SOURCES.txt +0 -0
  24. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/src/sora_sdk.egg-info/dependency_links.txt +0 -0
  25. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/src/sora_sdk.egg-info/top_level.txt +0 -0
  26. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_apple_video_toolbox.py +0 -0
  27. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_authz.py +0 -0
  28. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_authz_simulcast.py +0 -0
  29. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_ca_cert.py +0 -0
  30. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_capability.py +0 -0
  31. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_degradation_preference.py +0 -0
  32. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_encoded_transform.py +0 -0
  33. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_key_frame_request.py +0 -0
  34. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_messaging.py +0 -0
  35. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_messaging_header.py +0 -0
  36. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_openh264.py +0 -0
  37. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_openh264_simulcast.py +0 -0
  38. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_opus.py +0 -0
  39. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_re_offer_re_answer_sdp.py +0 -0
  40. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_sendonly_recvonly.py +0 -0
  41. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_signaling.py +0 -0
  42. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_signaling_message.py +0 -0
  43. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_signaling_notify.py +0 -0
  44. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_simulcast.py +0 -0
  45. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_sora_disconnect.py +0 -0
  46. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_type_disconnect.py +0 -0
  47. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_type_switched.py +0 -0
  48. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_vad.py +0 -0
  49. {sora_sdk-2025.5.0.dev3 → sora_sdk-2025.5.0.dev4}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sora_sdk
3
- Version: 2025.5.0.dev3
3
+ Version: 2025.5.0.dev4
4
4
  Summary: WebRTC SFU Sora Python SDK
5
5
  Home-page: https://github.com/shiguredo/sora-python-sdk
6
6
  Author-email: "Shiguredo Inc." <contact+pypi@shiguredo.jp>
@@ -0,0 +1 @@
1
+ 2025.5.0.dev4
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sora_sdk
3
- Version: 2025.5.0.dev3
3
+ Version: 2025.5.0.dev4
4
4
  Summary: WebRTC SFU Sora Python SDK
5
5
  Home-page: https://github.com/shiguredo/sora-python-sdk
6
6
  Author-email: "Shiguredo Inc." <contact+pypi@shiguredo.jp>
@@ -322,7 +322,7 @@ def test_amd_amf_simulcast(
322
322
  # simulcast_count が 2 の場合、rid r2 の bytesSent/packetsSent は 0 or 1 になる
323
323
  # simulcast_count が 1 の場合、rid r2 と r1 の bytesSent/packetsSent は 0 or 1 になる
324
324
  if i < simulcast_count:
325
- assert s["bytesSent"] > 1000
325
+ assert s["bytesSent"] > 500
326
326
  assert s["packetsSent"] > 5
327
327
 
328
328
  assert s["targetBitrate"] >= expect_target_bitrate(
@@ -250,7 +250,7 @@ def test_intel_vpl_simulcast(
250
250
  # assert "SimulcastEncoderAdapter" in s["encoderImplementation"]
251
251
  assert expected_implementation in s["encoderImplementation"]
252
252
 
253
- assert s["bytesSent"] > 1000
253
+ assert s["bytesSent"] > 500
254
254
  assert s["packetsSent"] > 5
255
255
 
256
256
  assert s["targetBitrate"] >= expect_target_bitrate(
@@ -325,7 +325,7 @@ def test_nvidia_video_codec_sdk_simulcast(
325
325
  # assert "SimulcastEncoderAdapter" in s["encoderImplementation"]
326
326
  assert expected_implementation in s["encoderImplementation"]
327
327
 
328
- assert s["bytesSent"] > 1000
328
+ assert s["bytesSent"] > 500
329
329
  assert s["packetsSent"] > 5
330
330
 
331
331
  assert s["targetBitrate"] >= expect_target_bitrate(
@@ -0,0 +1,223 @@
1
+ import os
2
+ import time
3
+
4
+ import pytest
5
+ from client import (
6
+ SoraClient,
7
+ SoraRole,
8
+ codec_type_string_to_codec_type,
9
+ )
10
+ from simulcast import default_video_bit_rate, expect_target_bitrate
11
+
12
+ from sora_sdk import (
13
+ SoraVideoCodecImplementation,
14
+ SoraVideoCodecPreference,
15
+ SoraVideoCodecType,
16
+ get_video_codec_capability,
17
+ )
18
+
19
+ pytestmark = pytest.mark.skipif(
20
+ os.environ.get("RASPBERRY_PI") is None, reason="Raspberry Pi でのみ実行する"
21
+ )
22
+
23
+
24
+ def test_raspberry_pi_available():
25
+ capability = get_video_codec_capability()
26
+
27
+ intel_vpl_available = False
28
+ for e in capability.engines:
29
+ if e.name == SoraVideoCodecImplementation.RASPI_V4L2M2M:
30
+ intel_vpl_available = True
31
+
32
+ assert intel_vpl_available is True
33
+
34
+ for e in capability.engines:
35
+ if e.name == SoraVideoCodecImplementation.RASPI_V4L2M2M:
36
+ # 対応コーデックは 5 種類
37
+ assert len(e.codecs) == 5
38
+
39
+ for c in e.codecs:
40
+ match c.type:
41
+ case SoraVideoCodecType.VP8:
42
+ assert c.decoder is False
43
+ assert c.encoder is False
44
+ case SoraVideoCodecType.VP9:
45
+ assert c.decoder is False
46
+ assert c.encoder is False
47
+ case SoraVideoCodecType.AV1:
48
+ assert c.decoder is False
49
+ assert c.encoder is False
50
+ case SoraVideoCodecType.H264:
51
+ assert c.decoder is True
52
+ assert c.encoder is True
53
+ case SoraVideoCodecType.H265:
54
+ assert c.decoder is False
55
+ assert c.encoder is False
56
+ case _:
57
+ pytest.fail(f"未実装の codec_type: {c.type}")
58
+
59
+
60
+ def test_raspberry_pi_sendonly(settings):
61
+ video_codec_type = "H264"
62
+ sendonly = SoraClient(
63
+ settings,
64
+ SoraRole.SENDONLY,
65
+ audio=False,
66
+ video=True,
67
+ video_codec_type=video_codec_type,
68
+ video_codec_preference=SoraVideoCodecPreference(
69
+ codecs=[
70
+ SoraVideoCodecPreference.Codec(
71
+ type=codec_type_string_to_codec_type(video_codec_type),
72
+ encoder=SoraVideoCodecImplementation.RASPI_V4L2M2M,
73
+ ),
74
+ ]
75
+ ),
76
+ )
77
+ sendonly.connect(fake_video=True)
78
+
79
+ time.sleep(5)
80
+
81
+ assert sendonly.connect_message is not None
82
+ assert sendonly.connect_message["channel_id"] == settings.channel_id
83
+ assert "video" in sendonly.connect_message
84
+ assert sendonly.connect_message["video"]["codec_type"] == video_codec_type
85
+
86
+ sendonly_stats = sendonly.get_stats()
87
+
88
+ sendonly.disconnect()
89
+
90
+ # codec が無かったら StopIteration 例外が上がる
91
+ codec_stats = next(s for s in sendonly_stats if s.get("type") == "codec")
92
+ # H.264 が採用されているかどうか確認する
93
+ assert codec_stats["mimeType"] == f"video/{video_codec_type}"
94
+
95
+ # outbound-rtp が無かったら StopIteration 例外が上がる
96
+ outbound_rtp_stats = next(s for s in sendonly_stats if s.get("type") == "outbound-rtp")
97
+ assert outbound_rtp_stats["encoderImplementation"] == "V4L2M2M H264"
98
+ assert outbound_rtp_stats["bytesSent"] > 0
99
+ assert outbound_rtp_stats["packetsSent"] > 0
100
+
101
+
102
+ @pytest.mark.parametrize(
103
+ (
104
+ "video_width",
105
+ "video_height",
106
+ "simulcast_count",
107
+ ),
108
+ [
109
+ # 1080p
110
+ (1920, 1080, 3),
111
+ # 720p
112
+ (1280, 720, 3),
113
+ # 540p
114
+ (960, 540, 3),
115
+ # 360p
116
+ (640, 360, 2),
117
+ # 270p
118
+ (480, 270, 2),
119
+ # 180p
120
+ (320, 180, 1),
121
+ ],
122
+ )
123
+ def test_raspberry_pi_simulcast(
124
+ settings,
125
+ video_width,
126
+ video_height,
127
+ simulcast_count,
128
+ ):
129
+ video_codec_type = "H264"
130
+ expected_implementation = "V4L2M2M H264"
131
+
132
+ video_bit_rate = default_video_bit_rate(video_codec_type, video_width, video_height)
133
+
134
+ sendonly = SoraClient(
135
+ settings,
136
+ SoraRole.SENDONLY,
137
+ simulcast=True,
138
+ audio=False,
139
+ video=True,
140
+ video_codec_type=video_codec_type,
141
+ video_bit_rate=video_bit_rate,
142
+ video_width=video_width,
143
+ video_height=video_height,
144
+ video_codec_preference=SoraVideoCodecPreference(
145
+ codecs=[
146
+ SoraVideoCodecPreference.Codec(
147
+ type=codec_type_string_to_codec_type(video_codec_type),
148
+ encoder=SoraVideoCodecImplementation.RASPI_V4L2M2M,
149
+ ),
150
+ ]
151
+ ),
152
+ )
153
+ sendonly.connect(fake_video=True)
154
+
155
+ time.sleep(5)
156
+
157
+ sendonly_stats = sendonly.get_stats()
158
+
159
+ sendonly.disconnect()
160
+
161
+ # "type": "answer" の SDP で Simulcast があるかどうか
162
+ assert sendonly.answer_message is not None
163
+ assert "sdp" in sendonly.answer_message
164
+ assert "a=simulcast:send r0;r1;r2" in sendonly.answer_message["sdp"]
165
+
166
+ # codec が無かったら StopIteration 例外が上がる
167
+ sendonly_codec_stats = next(s for s in sendonly_stats if s.get("type") == "codec")
168
+ assert sendonly_codec_stats["mimeType"] == f"video/{video_codec_type}"
169
+
170
+ # 複数の outbound-rtp 統計情報を取得
171
+ outbound_rtp_stats = [
172
+ s for s in sendonly_stats if s.get("type") == "outbound-rtp" and s.get("kind") == "video"
173
+ ]
174
+ # simulcast_count に関係なく統計情報はかならず 3 本出力される
175
+ assert len(outbound_rtp_stats) == 3
176
+
177
+ # rid でソート
178
+ sorted_stats = sorted(outbound_rtp_stats, key=lambda x: x.get("rid", ""))
179
+
180
+ for i, s in enumerate(sorted_stats):
181
+ assert "qualityLimitationReason" in s
182
+ assert "qualityLimitationDurations" in s
183
+
184
+ # qualityLimitationReason が none で無い場合は安定したテストができない
185
+ if s["qualityLimitationReason"] != "none":
186
+ pytest.skip(f"qualityLimitationReason: {s['qualityLimitationReason']}")
187
+
188
+ assert s["rid"] == f"r{i}"
189
+ # simulcast_count が 2 の場合、rid r2 の bytesSent/packetsSent は 0 or 1 になる
190
+ # simulcast_count が 1 の場合、rid r2 と r1 の bytesSent/packetsSent は 0 or 1 になる
191
+ if i < simulcast_count:
192
+ assert expected_implementation in s["encoderImplementation"]
193
+
194
+ assert s["bytesSent"] > 500
195
+ assert s["packetsSent"] > 5
196
+
197
+ assert s["targetBitrate"] >= expect_target_bitrate(
198
+ video_codec_type, s["frameWidth"], s["frameHeight"]
199
+ )
200
+
201
+ print(
202
+ s["rid"],
203
+ video_codec_type,
204
+ expected_implementation,
205
+ video_bit_rate * 1000,
206
+ s["targetBitrate"],
207
+ s["frameWidth"],
208
+ s["frameHeight"],
209
+ s["bytesSent"],
210
+ s["packetsSent"],
211
+ )
212
+ else:
213
+ # 本来は 0 なのだが、simulcast_count が 1 の場合、
214
+ # packetSent が 0 ではなく 1 や 2 になる場合がある
215
+ # byteSent は 0
216
+ print(
217
+ s["rid"],
218
+ video_codec_type,
219
+ s["bytesSent"],
220
+ s["packetsSent"],
221
+ )
222
+ assert s["bytesSent"] == 0
223
+ assert s["packetsSent"] <= 2
@@ -1 +0,0 @@
1
- 2025.5.0.dev3
@@ -1,98 +0,0 @@
1
- import os
2
- import time
3
-
4
- import pytest
5
- from client import (
6
- SoraClient,
7
- SoraRole,
8
- codec_type_string_to_codec_type,
9
- )
10
-
11
- from sora_sdk import (
12
- SoraVideoCodecImplementation,
13
- SoraVideoCodecPreference,
14
- SoraVideoCodecType,
15
- get_video_codec_capability,
16
- )
17
-
18
- pytestmark = pytest.mark.skipif(
19
- os.environ.get("RASPBERRY_PI") is None, reason="Raspberry Pi でのみ実行する"
20
- )
21
-
22
-
23
- def test_intel_vpl_available():
24
- capability = get_video_codec_capability()
25
-
26
- intel_vpl_available = False
27
- for e in capability.engines:
28
- if e.name == SoraVideoCodecImplementation.RASPI_V4L2M2M:
29
- intel_vpl_available = True
30
-
31
- assert intel_vpl_available is True
32
-
33
- for e in capability.engines:
34
- if e.name == SoraVideoCodecImplementation.RASPI_V4L2M2M:
35
- # 対応コーデックは 5 種類
36
- assert len(e.codecs) == 5
37
-
38
- for c in e.codecs:
39
- match c.type:
40
- case SoraVideoCodecType.VP8:
41
- assert c.decoder is False
42
- assert c.encoder is False
43
- case SoraVideoCodecType.VP9:
44
- assert c.decoder is False
45
- assert c.encoder is False
46
- case SoraVideoCodecType.AV1:
47
- assert c.decoder is False
48
- assert c.encoder is False
49
- case SoraVideoCodecType.H264:
50
- assert c.decoder is True
51
- assert c.encoder is True
52
- case SoraVideoCodecType.H265:
53
- assert c.decoder is False
54
- assert c.encoder is False
55
- case _:
56
- pytest.fail(f"未実装の codec_type: {c.type}")
57
-
58
-
59
- def test_raspberry_pi_sendonly(settings):
60
- video_codec_type = "H264"
61
- sendonly = SoraClient(
62
- settings,
63
- SoraRole.SENDONLY,
64
- audio=False,
65
- video=True,
66
- video_codec_type=video_codec_type,
67
- video_codec_preference=SoraVideoCodecPreference(
68
- codecs=[
69
- SoraVideoCodecPreference.Codec(
70
- type=codec_type_string_to_codec_type(video_codec_type),
71
- encoder=SoraVideoCodecImplementation.RASPI_V4L2M2M,
72
- ),
73
- ]
74
- ),
75
- )
76
- sendonly.connect(fake_video=True)
77
-
78
- time.sleep(5)
79
-
80
- assert sendonly.connect_message is not None
81
- assert sendonly.connect_message["channel_id"] == settings.channel_id
82
- assert "video" in sendonly.connect_message
83
- assert sendonly.connect_message["video"]["codec_type"] == video_codec_type
84
-
85
- sendonly_stats = sendonly.get_stats()
86
-
87
- sendonly.disconnect()
88
-
89
- # codec が無かったら StopIteration 例外が上がる
90
- codec_stats = next(s for s in sendonly_stats if s.get("type") == "codec")
91
- # H.264 が採用されているかどうか確認する
92
- assert codec_stats["mimeType"] == f"video/{video_codec_type}"
93
-
94
- # outbound-rtp が無かったら StopIteration 例外が上がる
95
- outbound_rtp_stats = next(s for s in sendonly_stats if s.get("type") == "outbound-rtp")
96
- assert outbound_rtp_stats["encoderImplementation"] == "V4L2M2M H264"
97
- assert outbound_rtp_stats["bytesSent"] > 0
98
- assert outbound_rtp_stats["packetsSent"] > 0