libdatachannel-py 2025.1.0.dev13__tar.gz → 2025.1.0.dev15__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.
- {libdatachannel_py-2025.1.0.dev13/src/libdatachannel_py.egg-info → libdatachannel_py-2025.1.0.dev15}/PKG-INFO +1 -1
- libdatachannel_py-2025.1.0.dev15/VERSION +1 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/buildbase.py +54 -4
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/pyproject.toml +7 -12
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/run.py +64 -14
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/libdatachannel_ext.cpython-313-darwin.so +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15/src/libdatachannel_py.egg-info}/PKG-INFO +1 -1
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_websocket.py +4 -2
- libdatachannel_py-2025.1.0.dev13/VERSION +0 -1
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/LICENSE +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/MANIFEST.in +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/README.md +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/pypath.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/setup.cfg +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/setup.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/__init__.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/codec/__init__.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/codec/__init__.pyi +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/libdatachannel_ext.pyi +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/libyuv/__init__.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/libyuv/__init__.pyi +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/py.typed +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel_py.egg-info/SOURCES.txt +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel_py.egg-info/dependency_links.txt +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel_py.egg-info/top_level.txt +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_audio_codec.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_candidate.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_configuration.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_description.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_frameinfo.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_h265nalunit.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_libyuv.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_mediahandler.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_message.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_nalunit.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_packetizationconfig.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_peerconnection.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_prop_audio_codec.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_reliability.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_rtppacketizer.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_video_codec.py +0 -0
- {libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_websocketserver.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2025.1.0.dev15
|
|
@@ -29,6 +29,7 @@ import logging
|
|
|
29
29
|
import multiprocessing
|
|
30
30
|
import os
|
|
31
31
|
import platform
|
|
32
|
+
import hashlib
|
|
32
33
|
import shlex
|
|
33
34
|
import shutil
|
|
34
35
|
import stat
|
|
@@ -143,7 +144,12 @@ def add_path(path: str, is_after=False):
|
|
|
143
144
|
os.environ["PATH"] = path + PATH_SEPARATOR + os.environ["PATH"]
|
|
144
145
|
|
|
145
146
|
|
|
146
|
-
def download(
|
|
147
|
+
def download(
|
|
148
|
+
url: str,
|
|
149
|
+
output_dir: Optional[str] = None,
|
|
150
|
+
filename: Optional[str] = None,
|
|
151
|
+
expected_sha256: Optional[str] = None,
|
|
152
|
+
) -> str:
|
|
147
153
|
if filename is None:
|
|
148
154
|
output_path = urllib.parse.urlparse(url).path.split("/")[-1]
|
|
149
155
|
else:
|
|
@@ -153,22 +159,53 @@ def download(url: str, output_dir: Optional[str] = None, filename: Optional[str]
|
|
|
153
159
|
output_path = os.path.join(output_dir, output_path)
|
|
154
160
|
|
|
155
161
|
if os.path.exists(output_path):
|
|
156
|
-
|
|
162
|
+
if expected_sha256 is not None:
|
|
163
|
+
try:
|
|
164
|
+
verify_sha256(output_path, expected_sha256)
|
|
165
|
+
except ValueError:
|
|
166
|
+
logging.warning(f"Existing file has invalid hash, removing: {output_path}")
|
|
167
|
+
os.remove(output_path)
|
|
168
|
+
return download(url, output_dir, filename, expected_sha256)
|
|
169
|
+
else:
|
|
170
|
+
return output_path
|
|
157
171
|
|
|
158
172
|
try:
|
|
173
|
+
logging.info(f"Downloading {url} to {output_path}")
|
|
159
174
|
if shutil.which("curl") is not None:
|
|
160
175
|
cmd(["curl", "-fLo", output_path, url])
|
|
161
176
|
else:
|
|
162
177
|
cmd(["wget", "-cO", output_path, url])
|
|
178
|
+
|
|
179
|
+
if expected_sha256 is not None:
|
|
180
|
+
verify_sha256(output_path, expected_sha256)
|
|
163
181
|
except Exception:
|
|
164
182
|
# ゴミを残さないようにする
|
|
165
183
|
if os.path.exists(output_path):
|
|
184
|
+
logging.error(f"Removing incomplete/invalid file: {output_path}")
|
|
166
185
|
os.remove(output_path)
|
|
167
186
|
raise
|
|
168
187
|
|
|
169
188
|
return output_path
|
|
170
189
|
|
|
171
190
|
|
|
191
|
+
def verify_sha256(file_path: str, expected_sha256: str):
|
|
192
|
+
logging.info(f"Verifying SHA256 hash for {file_path}")
|
|
193
|
+
sha256_hash = hashlib.sha256()
|
|
194
|
+
with open(file_path, "rb") as f:
|
|
195
|
+
for byte_block in iter(lambda: f.read(4096), b""):
|
|
196
|
+
sha256_hash.update(byte_block)
|
|
197
|
+
actual_sha256 = sha256_hash.hexdigest()
|
|
198
|
+
if actual_sha256 != expected_sha256.lower():
|
|
199
|
+
error_msg = (
|
|
200
|
+
f"SHA256 hash mismatch for {file_path}:\n"
|
|
201
|
+
f" Expected: {expected_sha256.lower()}\n"
|
|
202
|
+
f" Actual: {actual_sha256}"
|
|
203
|
+
)
|
|
204
|
+
logging.error(error_msg)
|
|
205
|
+
raise ValueError(error_msg)
|
|
206
|
+
logging.info(f"SHA256 hash verified successfully for {file_path}")
|
|
207
|
+
|
|
208
|
+
|
|
172
209
|
def read_version_file(path: str) -> Dict[str, str]:
|
|
173
210
|
versions = {}
|
|
174
211
|
|
|
@@ -1732,7 +1769,13 @@ def install_boringssl(
|
|
|
1732
1769
|
|
|
1733
1770
|
@versioned
|
|
1734
1771
|
def install_opus(
|
|
1735
|
-
version,
|
|
1772
|
+
version,
|
|
1773
|
+
source_dir,
|
|
1774
|
+
build_dir,
|
|
1775
|
+
install_dir,
|
|
1776
|
+
configuration: str,
|
|
1777
|
+
cmake_args: List[str],
|
|
1778
|
+
expected_sha256: Optional[str] = None,
|
|
1736
1779
|
):
|
|
1737
1780
|
opus_source_dir = os.path.join(source_dir, "opus")
|
|
1738
1781
|
opus_build_dir = os.path.join(build_dir, "opus")
|
|
@@ -1740,7 +1783,14 @@ def install_opus(
|
|
|
1740
1783
|
rm_rf(opus_source_dir)
|
|
1741
1784
|
rm_rf(opus_build_dir)
|
|
1742
1785
|
rm_rf(opus_install_dir)
|
|
1743
|
-
|
|
1786
|
+
# Git クローンではなく、配布アーカイブをダウンロードして展開する
|
|
1787
|
+
# 例: OPUS_VERSION=v1.5.2 -> https://oss-mirrors.shiguredo.jp/opus-1.5.2.tar.gz
|
|
1788
|
+
version_nov = version[1:] if version.startswith("v") else version
|
|
1789
|
+
archive_filename = f"opus-{version_nov}.tar.gz"
|
|
1790
|
+
# 公式サイトに負荷をかけないための時雨堂によるミラー
|
|
1791
|
+
url = f"https://oss-mirrors.shiguredo.jp/{archive_filename}"
|
|
1792
|
+
archive_path = download(url, source_dir, expected_sha256=expected_sha256)
|
|
1793
|
+
extract(archive_path, source_dir, "opus")
|
|
1744
1794
|
mkdir_p(opus_build_dir)
|
|
1745
1795
|
with cd(opus_build_dir):
|
|
1746
1796
|
cmd(
|
|
@@ -22,17 +22,16 @@ build-backend = "setuptools.build_meta"
|
|
|
22
22
|
|
|
23
23
|
[dependency-groups]
|
|
24
24
|
dev = [
|
|
25
|
-
"nanobind>=2.
|
|
26
|
-
"pytest
|
|
25
|
+
"nanobind>=2.8",
|
|
26
|
+
"pytest",
|
|
27
27
|
"setuptools>=80.9",
|
|
28
|
-
"build>=1.
|
|
28
|
+
"build>=1.3.0",
|
|
29
29
|
"wheel>=0.45.1",
|
|
30
|
-
"numpy>=2.
|
|
30
|
+
"numpy>=2.3",
|
|
31
31
|
"ty",
|
|
32
|
-
"hypothesis
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"pyright",
|
|
32
|
+
"hypothesis",
|
|
33
|
+
"aiohttp",
|
|
34
|
+
"pytest-aiohttp",
|
|
36
35
|
]
|
|
37
36
|
|
|
38
37
|
[tool.uv.workspace]
|
|
@@ -41,7 +40,3 @@ members = ["examples"]
|
|
|
41
40
|
[tool.ruff]
|
|
42
41
|
target-version = "py313"
|
|
43
42
|
line-length = 100
|
|
44
|
-
|
|
45
|
-
[tool.pyrefly]
|
|
46
|
-
project-includes = ["**/*"]
|
|
47
|
-
project-excludes = ["**/*venv/**/*"]
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import argparse
|
|
2
|
+
import glob
|
|
2
3
|
import multiprocessing
|
|
3
4
|
import os
|
|
4
5
|
import shutil
|
|
5
6
|
import sys
|
|
7
|
+
from typing import Optional
|
|
6
8
|
|
|
7
9
|
from buildbase import (
|
|
8
10
|
Platform,
|
|
@@ -128,6 +130,7 @@ def install_deps(
|
|
|
128
130
|
"install_dir": install_dir,
|
|
129
131
|
"configuration": "Debug" if debug else "Release",
|
|
130
132
|
"cmake_args": macos_cmake_args,
|
|
133
|
+
"expected_sha256": version.get("OPUS_SHA256_HASH"),
|
|
131
134
|
}
|
|
132
135
|
install_opus(**install_opus_args)
|
|
133
136
|
|
|
@@ -179,29 +182,52 @@ AVAILABLE_TARGETS = [
|
|
|
179
182
|
]
|
|
180
183
|
|
|
181
184
|
|
|
182
|
-
def
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
185
|
+
def _find_clang_binary(name: str) -> Optional[str]:
|
|
186
|
+
if shutil.which(name) is not None:
|
|
187
|
+
return name
|
|
188
|
+
else:
|
|
189
|
+
for n in range(50, 14, -1):
|
|
190
|
+
if shutil.which(f"{name}-{n}") is not None:
|
|
191
|
+
return f"{name}-{n}"
|
|
192
|
+
return None
|
|
187
193
|
|
|
188
|
-
|
|
189
|
-
|
|
194
|
+
|
|
195
|
+
def _format(
|
|
196
|
+
clang_format_path: Optional[str] = None,
|
|
197
|
+
):
|
|
198
|
+
if clang_format_path is None:
|
|
199
|
+
clang_format_path = _find_clang_binary("clang-format")
|
|
200
|
+
if clang_format_path is None:
|
|
201
|
+
raise Exception("clang-format not found. Please install it or specify the path.")
|
|
202
|
+
patterns = [
|
|
203
|
+
"src/**/*.cpp",
|
|
204
|
+
"src/**/*.h",
|
|
205
|
+
]
|
|
206
|
+
target_files = []
|
|
207
|
+
for pattern in patterns:
|
|
208
|
+
files = glob.glob(pattern, recursive=True)
|
|
209
|
+
target_files.extend(files)
|
|
210
|
+
cmd([clang_format_path, "-i"] + target_files)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def _build(args):
|
|
214
|
+
target = args.target
|
|
215
|
+
if target == "windows_x86_64":
|
|
190
216
|
platform = Platform("windows", get_windows_osver(), "x86_64")
|
|
191
|
-
elif
|
|
217
|
+
elif target == "macos_x86_64":
|
|
192
218
|
platform = Platform("macos", get_macos_osver(), "x86_64")
|
|
193
|
-
elif
|
|
219
|
+
elif target == "macos_arm64":
|
|
194
220
|
platform = Platform("macos", get_macos_osver(), "arm64")
|
|
195
|
-
elif
|
|
221
|
+
elif target == "ubuntu-22.04_x86_64":
|
|
196
222
|
platform = Platform("ubuntu", "22.04", "x86_64")
|
|
197
|
-
elif
|
|
223
|
+
elif target == "ubuntu-24.04_x86_64":
|
|
198
224
|
platform = Platform("ubuntu", "24.04", "x86_64")
|
|
199
|
-
elif
|
|
225
|
+
elif target == "ubuntu-24.04_armv8":
|
|
200
226
|
platform = Platform("ubuntu", "24.04", "armv8")
|
|
201
|
-
elif
|
|
227
|
+
elif target == "ubuntu-22.04_armv8_jetson":
|
|
202
228
|
platform = Platform("jetson", None, "armv8", "ubuntu-22.04")
|
|
203
229
|
else:
|
|
204
|
-
raise Exception(f"Unknown target {
|
|
230
|
+
raise Exception(f"Unknown target {target}")
|
|
205
231
|
|
|
206
232
|
source_dir = os.path.join(BASE_DIR, "_source", platform.target.package_name)
|
|
207
233
|
build_dir = os.path.join(BASE_DIR, "_build", platform.target.package_name)
|
|
@@ -341,5 +367,29 @@ def main():
|
|
|
341
367
|
)
|
|
342
368
|
|
|
343
369
|
|
|
370
|
+
def main():
|
|
371
|
+
parser = argparse.ArgumentParser()
|
|
372
|
+
sp = parser.add_subparsers(dest="command")
|
|
373
|
+
|
|
374
|
+
# build コマンド
|
|
375
|
+
bp = sp.add_parser("build")
|
|
376
|
+
bp.add_argument("target", choices=AVAILABLE_TARGETS)
|
|
377
|
+
bp.add_argument("--debug", action="store_true")
|
|
378
|
+
bp.add_argument("--relwithdebinfo", action="store_true")
|
|
379
|
+
|
|
380
|
+
# format コマンド
|
|
381
|
+
fp = sp.add_parser("format")
|
|
382
|
+
fp.add_argument("--clang-format-path", type=str, default=None)
|
|
383
|
+
|
|
384
|
+
args = parser.parse_args()
|
|
385
|
+
|
|
386
|
+
if args.command == "build":
|
|
387
|
+
_build(args)
|
|
388
|
+
elif args.command == "format":
|
|
389
|
+
_format(clang_format_path=args.clang_format_path)
|
|
390
|
+
else:
|
|
391
|
+
parser.print_help()
|
|
392
|
+
|
|
393
|
+
|
|
344
394
|
if __name__ == "__main__":
|
|
345
395
|
main()
|
|
Binary file
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_websocket.py
RENAMED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import time
|
|
2
2
|
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
3
5
|
from libdatachannel import WebSocket, WebSocketConfiguration
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
# https://github.com/paullouisageneau/libdatachannel/blob/0e40aeb058b947014a918a448ce2d346e6ab14fe/test/websocket.cpp
|
|
7
9
|
# を Python に直したもの
|
|
8
|
-
def test_websocket():
|
|
10
|
+
def test_websocket(echo_websocket_server):
|
|
9
11
|
my_message = "Hello world from libdatachannel"
|
|
10
12
|
config = WebSocketConfiguration()
|
|
11
13
|
config.disable_tls_verification = True
|
|
@@ -37,7 +39,7 @@ def test_websocket():
|
|
|
37
39
|
ws.on_closed(ws_on_closed)
|
|
38
40
|
ws.on_message(ws_on_message)
|
|
39
41
|
|
|
40
|
-
ws.open(
|
|
42
|
+
ws.open(echo_websocket_server)
|
|
41
43
|
|
|
42
44
|
attempts = 20
|
|
43
45
|
while (not ws.is_open() or not received) and attempts > 0:
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2025.1.0.dev13
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/src/libdatachannel/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_audio_codec.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_candidate.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_configuration.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_description.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_frameinfo.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_h265nalunit.py
RENAMED
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_mediahandler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_peerconnection.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_prop_audio_codec.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_reliability.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_rtppacketizer.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_video_codec.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev13 → libdatachannel_py-2025.1.0.dev15}/tests/test_websocketserver.py
RENAMED
|
File without changes
|