libdatachannel-py 2025.1.0.dev14__tar.gz → 2025.1.0.dev16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. {libdatachannel_py-2025.1.0.dev14/src/libdatachannel_py.egg-info → libdatachannel_py-2025.1.0.dev16}/PKG-INFO +1 -1
  2. libdatachannel_py-2025.1.0.dev16/VERSION +1 -0
  3. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/buildbase.py +54 -4
  4. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/pyproject.toml +6 -7
  5. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/run.py +64 -14
  6. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel/codec/__init__.pyi +20 -19
  7. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel/libdatachannel_ext.cpython-313-darwin.so +0 -0
  8. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel/libyuv/__init__.pyi +8 -8
  9. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16/src/libdatachannel_py.egg-info}/PKG-INFO +1 -1
  10. libdatachannel_py-2025.1.0.dev14/VERSION +0 -1
  11. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/LICENSE +0 -0
  12. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/MANIFEST.in +0 -0
  13. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/README.md +0 -0
  14. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/pypath.py +0 -0
  15. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/setup.cfg +0 -0
  16. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/setup.py +0 -0
  17. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel/__init__.py +0 -0
  18. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel/codec/__init__.py +0 -0
  19. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel/libdatachannel_ext.pyi +0 -0
  20. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel/libyuv/__init__.py +0 -0
  21. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel/py.typed +0 -0
  22. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel_py.egg-info/SOURCES.txt +0 -0
  23. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel_py.egg-info/dependency_links.txt +0 -0
  24. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/src/libdatachannel_py.egg-info/top_level.txt +0 -0
  25. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_audio_codec.py +0 -0
  26. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_candidate.py +0 -0
  27. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_configuration.py +0 -0
  28. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_description.py +0 -0
  29. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_frameinfo.py +0 -0
  30. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_h265nalunit.py +0 -0
  31. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_libyuv.py +0 -0
  32. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_mediahandler.py +0 -0
  33. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_message.py +0 -0
  34. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_nalunit.py +0 -0
  35. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_packetizationconfig.py +0 -0
  36. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_peerconnection.py +0 -0
  37. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_prop_audio_codec.py +0 -0
  38. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_reliability.py +0 -0
  39. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_rtppacketizer.py +0 -0
  40. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_video_codec.py +0 -0
  41. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_websocket.py +0 -0
  42. {libdatachannel_py-2025.1.0.dev14 → libdatachannel_py-2025.1.0.dev16}/tests/test_websocketserver.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: libdatachannel-py
3
- Version: 2025.1.0.dev14
3
+ Version: 2025.1.0.dev16
4
4
  Summary: libdatachannel-py is a Python binding for libdatachannel.
5
5
  Home-page: https://github.com/shiguredo/libdatachannel-py
6
6
  License-Expression: Apache-2.0
@@ -0,0 +1 @@
1
+ 2025.1.0.dev16
@@ -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(url: str, output_dir: Optional[str] = None, filename: Optional[str] = None) -> str:
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
- return output_path
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, source_dir, build_dir, install_dir, configuration: str, cmake_args: List[str]
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
- git_clone_shallow("https://gitlab.xiph.org/xiph/opus", version, opus_source_dir)
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(
@@ -17,21 +17,20 @@ Source = "https://github.com/shiguredo/libdatachannel-py"
17
17
  Discord = "https://discord.gg/shiguredo"
18
18
 
19
19
  [build-system]
20
- requires = ["setuptools>=80.9", "wheel>=0.45.1"]
20
+ requires = ["setuptools>=80.9"]
21
21
  build-backend = "setuptools.build_meta"
22
22
 
23
23
  [dependency-groups]
24
24
  dev = [
25
- "nanobind>=2.8",
26
- "pytest",
25
+ "nanobind==2.9.2",
27
26
  "setuptools>=80.9",
28
- "build>=1.2.2.post1",
29
- "wheel>=0.45.1",
30
- "numpy>=2.3",
27
+ "pytest",
28
+ "pytest-aiohttp",
29
+ "numpy",
31
30
  "ty",
32
31
  "hypothesis",
33
32
  "aiohttp",
34
- "pytest-aiohttp",
33
+ "ruff",
35
34
  ]
36
35
 
37
36
  [tool.uv.workspace]
@@ -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 main():
183
- parser = argparse.ArgumentParser()
184
- parser.add_argument("--debug", action="store_true")
185
- parser.add_argument("--relwithdebinfo", action="store_true")
186
- parser.add_argument("target", choices=AVAILABLE_TARGETS)
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
- args = parser.parse_args()
189
- if args.target == "windows_x86_64":
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 args.target == "macos_x86_64":
217
+ elif target == "macos_x86_64":
192
218
  platform = Platform("macos", get_macos_osver(), "x86_64")
193
- elif args.target == "macos_arm64":
219
+ elif target == "macos_arm64":
194
220
  platform = Platform("macos", get_macos_osver(), "arm64")
195
- elif args.target == "ubuntu-22.04_x86_64":
221
+ elif target == "ubuntu-22.04_x86_64":
196
222
  platform = Platform("ubuntu", "22.04", "x86_64")
197
- elif args.target == "ubuntu-24.04_x86_64":
223
+ elif target == "ubuntu-24.04_x86_64":
198
224
  platform = Platform("ubuntu", "24.04", "x86_64")
199
- elif args.target == "ubuntu-24.04_armv8":
225
+ elif target == "ubuntu-24.04_armv8":
200
226
  platform = Platform("ubuntu", "24.04", "armv8")
201
- elif args.target == "ubuntu-22.04_armv8_jetson":
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 {args.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()
@@ -3,7 +3,8 @@ import datetime
3
3
  import enum
4
4
  from typing import Annotated
5
5
 
6
- from numpy.typing import ArrayLike
6
+ import numpy
7
+ from numpy.typing import NDArray
7
8
 
8
9
 
9
10
  class VideoCodecType(enum.Enum):
@@ -29,22 +30,22 @@ class VideoFrameBufferI420:
29
30
  def create(arg0: int, arg1: int, /) -> VideoFrameBufferI420: ...
30
31
 
31
32
  @property
32
- def y(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
33
+ def y(self) -> Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')]: ...
33
34
 
34
35
  @y.setter
35
- def y(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
36
+ def y(self, arg: Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')], /) -> None: ...
36
37
 
37
38
  @property
38
- def u(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
39
+ def u(self) -> Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')]: ...
39
40
 
40
41
  @u.setter
41
- def u(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
42
+ def u(self, arg: Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')], /) -> None: ...
42
43
 
43
44
  @property
44
- def v(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
45
+ def v(self) -> Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')]: ...
45
46
 
46
47
  @v.setter
47
- def v(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
48
+ def v(self, arg: Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')], /) -> None: ...
48
49
 
49
50
  def width(self) -> int: ...
50
51
 
@@ -61,16 +62,16 @@ class VideoFrameBufferNV12:
61
62
  def create(arg0: int, arg1: int, /) -> VideoFrameBufferNV12: ...
62
63
 
63
64
  @property
64
- def y(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
65
+ def y(self) -> Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')]: ...
65
66
 
66
67
  @y.setter
67
- def y(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
68
+ def y(self, arg: Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')], /) -> None: ...
68
69
 
69
70
  @property
70
- def uv(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
71
+ def uv(self) -> Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')]: ...
71
72
 
72
73
  @uv.setter
73
- def uv(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
74
+ def uv(self, arg: Annotated[NDArray[numpy.uint8], dict(shape=(None, None), order='C')], /) -> None: ...
74
75
 
75
76
  def width(self) -> int: ...
76
77
 
@@ -85,10 +86,10 @@ class VideoFrameBufferBGR888:
85
86
  def create(arg0: int, arg1: int, /) -> VideoFrameBufferBGR888: ...
86
87
 
87
88
  @property
88
- def bgr(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None, 3), order='C')]: ...
89
+ def bgr(self) -> Annotated[NDArray[numpy.uint8], dict(shape=(None, None, 3), order='C')]: ...
89
90
 
90
91
  @bgr.setter
91
- def bgr(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None, 3), order='C')], /) -> None: ...
92
+ def bgr(self, arg: Annotated[NDArray[numpy.uint8], dict(shape=(None, None, 3), order='C')], /) -> None: ...
92
93
 
93
94
  def width(self) -> int: ...
94
95
 
@@ -161,10 +162,10 @@ class EncodedImage:
161
162
  def __init__(self) -> None: ...
162
163
 
163
164
  @property
164
- def data(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None), order='C')]: ...
165
+ def data(self) -> Annotated[NDArray[numpy.uint8], dict(shape=(None,), order='C')]: ...
165
166
 
166
167
  @data.setter
167
- def data(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None), order='C')], /) -> None: ...
168
+ def data(self, arg: Annotated[NDArray[numpy.uint8], dict(shape=(None,), order='C')], /) -> None: ...
168
169
 
169
170
  @property
170
171
  def timestamp(self) -> datetime.timedelta: ...
@@ -263,10 +264,10 @@ class AudioFrame:
263
264
  def sample_rate(self, arg: int, /) -> None: ...
264
265
 
265
266
  @property
266
- def pcm(self) -> Annotated[ArrayLike, dict(dtype='float32', shape=(None, None), order='C')]: ...
267
+ def pcm(self) -> Annotated[NDArray[numpy.float32], dict(shape=(None, None), order='C')]: ...
267
268
 
268
269
  @pcm.setter
269
- def pcm(self, arg: Annotated[ArrayLike, dict(dtype='float32', shape=(None, None), order='C')], /) -> None: ...
270
+ def pcm(self, arg: Annotated[NDArray[numpy.float32], dict(shape=(None, None), order='C')], /) -> None: ...
270
271
 
271
272
  @property
272
273
  def timestamp(self) -> datetime.timedelta: ...
@@ -282,10 +283,10 @@ class EncodedAudio:
282
283
  def __init__(self) -> None: ...
283
284
 
284
285
  @property
285
- def data(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None), order='C')]: ...
286
+ def data(self) -> Annotated[NDArray[numpy.uint8], dict(shape=(None,), order='C')]: ...
286
287
 
287
288
  @data.setter
288
- def data(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None), order='C')], /) -> None: ...
289
+ def data(self, arg: Annotated[NDArray[numpy.uint8], dict(shape=(None,), order='C')], /) -> None: ...
289
290
 
290
291
  @property
291
292
  def timestamp(self) -> datetime.timedelta: ...
@@ -1,6 +1,6 @@
1
1
  import enum
2
2
 
3
- from numpy.typing import ArrayLike
3
+ from numpy.typing import NDArray
4
4
 
5
5
 
6
6
  class FilterMode(enum.Enum):
@@ -172,16 +172,16 @@ class RotationMode(enum.Enum):
172
172
 
173
173
  kRotate270 = 270
174
174
 
175
- def nv12_scale(src_y: ArrayLike, src_uv: ArrayLike, src_stride_y: int, src_stride_uv: int, src_width: int, src_height: int, dst_y: ArrayLike, dst_uv: ArrayLike, dst_stride_y: int, dst_stride_uv: int, dst_width: int, dst_height: int, filtering: FilterMode) -> int: ...
175
+ def nv12_scale(src_y: NDArray, src_uv: NDArray, src_stride_y: int, src_stride_uv: int, src_width: int, src_height: int, dst_y: NDArray, dst_uv: NDArray, dst_stride_y: int, dst_stride_uv: int, dst_width: int, dst_height: int, filtering: FilterMode) -> int: ...
176
176
 
177
- def i420_scale(src_y: ArrayLike, src_u: ArrayLike, src_v: ArrayLike, src_stride_y: int, src_stride_u: int, src_stride_v: int, src_width: int, src_height: int, dst_y: ArrayLike, dst_u: ArrayLike, dst_v: ArrayLike, dst_stride_y: int, dst_stride_u: int, dst_stride_v: int, dst_width: int, dst_height: int, filtering: FilterMode) -> int: ...
177
+ def i420_scale(src_y: NDArray, src_u: NDArray, src_v: NDArray, src_stride_y: int, src_stride_u: int, src_stride_v: int, src_width: int, src_height: int, dst_y: NDArray, dst_u: NDArray, dst_v: NDArray, dst_stride_y: int, dst_stride_u: int, dst_stride_v: int, dst_width: int, dst_height: int, filtering: FilterMode) -> int: ...
178
178
 
179
- def convert_to_i420(sample: ArrayLike, sample_size: int, dst_y: ArrayLike, dst_stride_y: int, dst_u: ArrayLike, dst_stride_u: int, dst_v: ArrayLike, dst_stride_v: int, crop_x: int, crop_y: int, src_width: int, src_height: int, crop_width: int, crop_height: int, rotation: RotationMode, fourcc: FourCC) -> int: ...
179
+ def convert_to_i420(sample: NDArray, sample_size: int, dst_y: NDArray, dst_stride_y: int, dst_u: NDArray, dst_stride_u: int, dst_v: NDArray, dst_stride_v: int, crop_x: int, crop_y: int, src_width: int, src_height: int, crop_width: int, crop_height: int, rotation: RotationMode, fourcc: FourCC) -> int: ...
180
180
 
181
- def nv12_to_i420(src_y: ArrayLike, src_uv: ArrayLike, src_stride_y: int, src_stride_uv: int, dst_y: ArrayLike, dst_u: ArrayLike, dst_v: ArrayLike, dst_stride_y: int, dst_stride_u: int, dst_stride_v: int, width: int, height: int) -> int: ...
181
+ def nv12_to_i420(src_y: NDArray, src_uv: NDArray, src_stride_y: int, src_stride_uv: int, dst_y: NDArray, dst_u: NDArray, dst_v: NDArray, dst_stride_y: int, dst_stride_u: int, dst_stride_v: int, width: int, height: int) -> int: ...
182
182
 
183
- def i420_to_nv12(src_y: ArrayLike, src_u: ArrayLike, src_v: ArrayLike, src_stride_y: int, src_stride_u: int, src_stride_v: int, dst_y: ArrayLike, dst_uv: ArrayLike, dst_stride_y: int, dst_stride_uv: int, width: int, height: int) -> int: ...
183
+ def i420_to_nv12(src_y: NDArray, src_u: NDArray, src_v: NDArray, src_stride_y: int, src_stride_u: int, src_stride_v: int, dst_y: NDArray, dst_uv: NDArray, dst_stride_y: int, dst_stride_uv: int, width: int, height: int) -> int: ...
184
184
 
185
- def rgb24_to_i420(src_rgb24: ArrayLike, src_stride_rgb24: int, dst_y: ArrayLike, dst_u: ArrayLike, dst_v: ArrayLike, dst_stride_y: int, dst_stride_u: int, dst_stride_v: int, width: int, height: int) -> int: ...
185
+ def rgb24_to_i420(src_rgb24: NDArray, src_stride_rgb24: int, dst_y: NDArray, dst_u: NDArray, dst_v: NDArray, dst_stride_y: int, dst_stride_u: int, dst_stride_v: int, width: int, height: int) -> int: ...
186
186
 
187
- def i420_to_rgb24(src_y: ArrayLike, src_u: ArrayLike, src_v: ArrayLike, src_stride_y: int, src_stride_u: int, src_stride_v: int, dst_rgb24: ArrayLike, dst_stride_rgb24: int, width: int, height: int) -> int: ...
187
+ def i420_to_rgb24(src_y: NDArray, src_u: NDArray, src_v: NDArray, src_stride_y: int, src_stride_u: int, src_stride_v: int, dst_rgb24: NDArray, dst_stride_rgb24: int, width: int, height: int) -> int: ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: libdatachannel-py
3
- Version: 2025.1.0.dev14
3
+ Version: 2025.1.0.dev16
4
4
  Summary: libdatachannel-py is a Python binding for libdatachannel.
5
5
  Home-page: https://github.com/shiguredo/libdatachannel-py
6
6
  License-Expression: Apache-2.0
@@ -1 +0,0 @@
1
- 2025.1.0.dev14