- 音视频
- 通信
【免费下载链接】aiortc
WebRTC and ORTC implementation for Python using asyncio
aiortc是一个基于asyncio的 Python WebRTC / ORTC 实现,协议栈复杂(SDP、ICE、DTLS、SRTP、SCTP、RTP 一应俱全),因此项目对贡献质量有明确要求。本文以 贡献指南 为主体,结合仓库中的 CI 工作流、构建配置与测试代码,讲清楚三件事:什么形式的贡献被欢迎、一份合格的代码贡献应如何组织本地开发、跑测试与通过自动化检查,以及如何向维护者提出高质量的问题。读完本文,你可以在本地完整复现aiortc的"开发—测试—构建文档—打包装"全流程,并理解每个检查项背后的实现依据。
1. 贡献指南的核心主张:欢迎什么,要求什么
贡献指南 开篇即给出三类被欢迎的贡献:Bug reports、patches and suggestions(问题报告、补丁与建议)。指南特别强调:
Feedback about the examples or documentation are especially valuable as they make
aiortcaccessible to a wider audience.—— 对
examples/示例和docs/文档的反馈格外有价值,因为它们让aiortc对更广泛的开发者群体可用。
这条提示对应仓库中真实存在的两大块贡献面:
- 示例代码:examples/ 目录下提供 7 个可运行示例——
server/(WebRTC 信令 + 媒体 + 数据通道服务)、webcam/(摄像头采集)、videostream-cli/、datachannel-cli/、datachannel-filexfer/(数据通道文件传输)、datachannel-vpn/(基于数据通道的虚拟网络)、janus/(对接 Janus 网关)。修一个示例的 README、补一个参数说明,就是指南里说的高价值贡献。 - 文档:docs/ 目录下由 Sphinx 组织,入口为 docs/index.rst,
toctree依次为examples、api、helpers、contributing、changelog、license。文档贡献者可以直接在本地用 Sphinx 构建验证(见第 4 节)。
贡献的另一个硬性要求来自指南原文:
Code contributionsmustcome with full unit test coverage. WebRTC is a complex protocol stack and ensuring correct behaviour now and in the future requires a proper investment in automated testing.
—— 代码贡献必须附带完整的单元测试覆盖。
这不是口号。从源码结构看,tests/目录共 24 个测试模块,约 454 个测试方法(def test_*),另有 39 个二进制协议报文固件(*.bin),是"完整单测覆盖"要求的直接体现:
| 固件类型 | 示例文件 | 用途 |
|---|---|---|
| RTP 报文 | tests/rtp.bin、tests/rtp_with_sdes_mid.bin、tests/rtp_only_padding.bin | 验证 src/aiortc/rtp.py 对各类头部(CSRC、header extension、纯 padding)的解析 |
| RTCP 报文 | tests/rtcp_rr.bin、tests/rtcp_sr.bin、tests/rtcp_bye.bin | 验证接收报告、发送报告、BYE 的序列化/反序列化 |
| SCTP 报文 | tests/sctp_init.bin、tests/sctp_sack.bin、tests/sctp_reconfig_reset_out.bin | 验证 src/aiortc/rtcsctptransport.py 中纯 Python SCTP 实现 |
| 异常报文 | tests/rtcp_rr_invalid.bin、tests/sctp_cookie_echo.bin | 验证错误处理路径(invalid / truncation 分支) |
二进制固件的加载方式见 tests/utils.py 中的load()函数(按文件路径读取原始字节),测试用例直接以这些字节序列为输入断言解析结果——这也是新贡献者补测试时可以参照的模式。
2. 行为准则与沟通渠道
2.1 Code of Conduct
指南规定本项目及所有参与者受 CODE_OF_CONDUCT.md 约束,参与即视为接受该准则。该文件采用 Contributor Covenant 1.4 版本,核心内容包括:营造无骚扰环境的承诺、可接受/不可接受行为的列举(如包容性语言、尊重不同观点;不可接受性骚扰、trolling、公开/私下骚扰、未经同意公开他人隐私信息等)、维护者对不符合准则内容的删除/拒绝/封禁权限,以及适用范围(项目空间及代表项目行事的公共空间)。不当行为的举报渠道为项目团队邮箱 jeremy DOT laine AT m4x DOT org,团队有义务对举报人信息保密。
2.2 提问渠道:不要把 Issue 当问答区
贡献指南 的 "Questions" 一节明确指出:GitHub issues 不适合处理一般性提问,Stack Overflow 等地方更合适。如果仍要在 Issue 中提问,必须先满足三个条件:
- 问题关于
aiortc,而不是关于asyncio; - 文档没有给出答案;
- 这个问题还没有被问过。
指南还给出了一个技巧:"A good question can be written as a suggestion to improve the documentation."(一个好问题可以写成"改进文档"的建议。)——即如果你发现文档讲不清楚,直接提文档改进建议,往往比提问更高效,也更受维护者欢迎。
配合仓库中的 Issue 模板,提交 Bug 前需要自查四件事:
- 是否已有相同主题的 issue;
- 确认是
aiortc相关的问题——"The goal of the issue tracker is not to provide general guidance about WebRTC or free debugging of your code."(issue 区不提供 WebRTC 通识指导,也不免费调试你的代码); - 明确说明该问题能否在不改动任何代码的情况下,用
aiortc自带的某个 example 复现; - 体谅维护者:
aiortc以 best-effort 方式维护,不保证每个 issue 都会被处理。
3. 本地开发环境搭建
以下命令以当前仓库的实际构建配置为准。aiortc要求Python >= 3.8(见 pyproject.toml 的requires-python = ">=3.8",classifiers 覆盖 3.8–3.12),且源码构建依赖两个 C 编解码库:
- Opus:音频编解码(src/aiortc/codecs/opus.py 通过 CFFI 绑定)
- LibVPX:视频编解码(src/aiortc/codecs/vpx.py)
Linux(Debian/Ubuntu):
apt install libopus-dev libvpx-devmacOS:
brew install opus libvpx然后以可编辑方式安装项目并带上开发依赖:
pip install .[dev].[dev]的额外依赖定义在 pyproject.toml 的[project.optional-dependencies]中,为:aiohttp>=3.7.0、coverage[toml]>=7.2.2、numpy>=1.19.0。其中coverage[toml]是后面运行覆盖率统计必需的,aiohttp供 contrib/signaling.py 等信令工具及对应测试使用。
3.1 为什么需要 CFFI 与 abi3
setup.py 中的关键配置有两点值得贡献者了解:
cffi_modules=["src/_cffi_src/build_opus.py:ffibuilder", "src/_cffi_src/build_vpx.py:ffibuilder"]:构建时由 src/_cffi_src/build_opus.py 和 src/_cffi_src/build_vpx.py 生成 CFFI 绑定,因此系统必须存在上述两个库的头文件与静态/动态库。- 自定义的
bdist_wheel_abi3类会把 CPython 的 wheel tag 改写为cp38-abi3,即以Limited API (abi3)打轮子——3.8 编译的 wheel 可在更高版本 CPython 上运行,这解释了 CI 为何只用 Python 3.8 构建 wheel 即可覆盖 3.8–3.12 的测试矩阵。
3.2 发布包内容清单:MANIFEST.in
源发行包(sdist)收录哪些文件由 MANIFEST.in 显式声明:
include CODE_OF_CONDUCT.md include LICENSE recursive-include docs *.py *.rst *.svg Makefile recursive-include examples *.html *.js *.py *.rst *.wav recursive-include requirements *.txt recursive-include scripts *.json *.py recursive-include src/_cffi_src *.py recursive-include stubs *.pyi recursive-include tests *.bin *.py注意recursive-include tests *.bin *.py这一行:39 个二进制协议固件也随源码包分发。如果你为测试新增固件,必须确保其扩展名在此清单的收录规则内,否则check-manifest(CI 的 lint 阶段)会因 sdist 内容不一致而失败。
4. 开发工作流:复现 CI 的完整检查链
CI 工作流定义在 .github/workflows/tests.yml,在push和pull_request事件上触发,包含 5 个 job。贡献者把本地开发与这四条命令对齐,即可在提 PR 前自查。
4.1 Lint:ruff + mypy + check-manifest
对应 CI 的lintjob:
pip install check-manifest mypy ruff ruff check . ruff format --check --diff . check-manifest其中 ruff 的规则集配置在 pyproject.toml 的[tool.ruff.lint]:
[tool.ruff.lint] select = [ "E", # pycodestyle "F", # Pyflakes "W", # pycodestyle "I", # isort ] [tool.ruff.lint.isort] known-third-party = ["aiortc"]即强制代码风格(E/W)、未定义名称与未用导入(F)、以及 import 排序(I)。mypy 同样配置在 pyproject.toml:
[tool.mypy] disallow_untyped_calls = true disallow_untyped_decorators = true ignore_missing_imports = true mypy_path = "stubs" strict_optional = false warn_redundant_casts = true warn_unused_ignores = truemypy_path = "stubs"指向 stubs/ 目录,里面为google_crc32c等缺少类型信息的依赖提供了.pyi桩文件;同理src/aiortc/codecs/下也有_opus.pyi、_vpx.pyi为 CFFI 绑定声明类型。新增 C 绑定或第三方依赖时,维护这些桩文件是贡献的一部分。
4.2 单元测试:unittest + coverage
对应 CI 的testjob(在 Python 3.8–3.12 矩阵上执行,系统包为libopus-dev libvpx-dev):
python -m pip install -U pip setuptools wheel pip install .[dev] coverage run -m unittest discover -v coverage xml测试基于标准库unittest的discover机制从仓库根发现tests/包,覆盖率统计范围由 pyproject.toml 限定:
[tool.coverage.run] source = ["aiortc"] [tool.coverage.report] exclude_lines = ["pragma: no cover"]针对asyncio协程,测试统一用 tests/utils.py 中的asynctest装饰器把协程包进asyncio.run:
def asynctest(coro): @functools.wraps(coro) def wrap(*args, **kwargs): asyncio.run(coro(*args, **kwargs)) return wrap由于 WebRTC 链路(ICE → DTLS → SRTP/SCTP)涉及双向网络 I/O,测试中大量使用内存级"假网络"隔离外部依赖。tests/utils.py 提供了三套假传输:
DummyConnection:用一对asyncio.Queue模拟双向 UDP 连接,还支持loss_pattern按位图丢包,用于在可控丢包下验证 NACK/重传行为;DummyIceTransport:把DummyConnection包成符合 ICE 传输接口的对象,区分controlling/controlled角色;dummy_dtls_transport_pair():异步上下文管理器,内部用RTCCertificate.generateCertificate()生成证书并驱动RTCDtlsTransport双方完成握手,产出可直接测试 SCTP / DataChannel 的 DTLS 传输对。
如果你要为 src/aiortc/rtcdtlstransport.py、src/aiortc/rtcsctptransport.py 等模块补测试,dummy_dtls_transport_pair与二进制固件(load("rtcp_rr.bin")这类用法,如 tests/test_rtcrtpreceiver.py 对 RTCP 报文的解析断言)就是现成的范式。另外 tests/utils.py 末尾支持AIORTC_DEBUG环境变量打开 DEBUG 级日志,调试失败用例时可AIORTC_DEBUG=1运行。
一个完整的端到端测试示例是 tests/test_ortc.py,它按 ORTC 方式手工组装 ICE/DTLS/RTP 收发器,验证音视频与数据通道的完整数据面——贡献者可以把它当作"全栈回归"参照。
4.3 文档构建:Sphinx 严格模式
对应 CI 的docsjob:
pip install . -r requirements/doc.txt make -C docs html SPHINXOPTS=-WSPHINXOPTS=-W把 Sphinx 警告提升为构建错误,因此文档里任何失效的交叉引用、拼写错误都会导致 CI 失败——提交文档改动前务必本地构建通过。Sphinx 的构建入口是 docs/Makefile(标准sphinx-build -M转发),依赖清单 requirements/doc.txt 引入了sphinx_autodoc_typehints(在 API 文档中渲染类型注解)与sphinxcontrib-trio。Read the Docs 的构建环境定义在 .readthedocs.yaml:ubuntu-22.04、Python 3.11、预装libopus-dev/libvpx-dev,安装项目本体加requirements/doc.txt。
4.4 打包验证:sdist 与 wheel
CI 还有package-source(python -m build --sdist)与package-wheel(cibuildwheel多平台矩阵:macOS x86_64/ARM、Linux aarch64/i686/x86_64、Windows AMD64/x86)两个 job。贡献涉及构建配置(setup.py、pyproject.toml、CFFI 绑定)时,建议本地至少跑一次:
pip install -U build python -m build --sdist并确认check-manifest通过。值得注意的是 CI 的 wheel 构建通过CIBW_BEFORE_BUILD: python scripts/fetch-vendor.py /tmp/vendor预先拉取 Opus/LibVPX 源码(见 scripts/fetch-vendor.py 及其清单 scripts/fetch-vendor.json),再以CFLAGS=-I/tmp/vendor/include LDFLAGS=-L/tmp/vendor/lib编译——这说明 manylinux 容器里并非依赖系统库,贡献者在本地用系统包libopus-dev libvpx-dev构建是等价且更简便的路径。publishjob 只有在tag push(refs/tags/*)且前述 job 全部通过后才会发布到 PyPI,普通 PR 不会触发发布。
5. 提交贡献前的自检清单
把以上检查项合成为一份可直接执行的清单:
# 1) 环境 apt install libopus-dev libvpx-dev # Debian/Ubuntu;macOS: brew install opus libvpx pip install .[dev] # 2) 代码风格与静态检查 pip install check-manifest mypy ruff ruff check . ruff format --check --diff . check-manifest # 3) 单元测试 + 覆盖率 coverage run -m unittest discover -v coverage report # 4) 文档(若改动 docs/ 或 API 注解) pip install . -r requirements/doc.txt make -C docs html SPHINXOPTS=-W # 5) 发布包(若改动构建/清单文件) pip install -U build python -m build --sdist再对照 贡献指南 与 Issue 模板 的书面要求核对一遍:
- 代码改动是否附带覆盖新逻辑路径的单元测试(含异常分支,可参考
tests/中*_invalid.bin固件的用法)? - 新增测试固件/文档文件是否符合 MANIFEST.in 的收录规则?
- 文档改动是否通过
-W严格构建? - 如果提的是问题而非代码:能否不带改动地用
examples/复现?是否先查过已有 issue 与 docs/ 文档?
6. 小结
aiortc的贡献模型可以概括为:低门槛入口(文档与示例反馈)+ 高标准出口(完整单测 + 全绿 CI)。指南中"完整单元测试覆盖"的要求,落实在仓库层面就是tests/中 24 个测试模块、约 454 个测试方法与 39 个二进制协议固件,以及.github/workflows/tests.yml中 docs / lint / test / package-source / package-wheel 五道自动关卡。掌握第 4 节的本地命令与第 5 节的清单后,你的任何贡献都能在提交前完成与 CI 等价的自我验证。
关键文件索引
| 文件 | 说明 |
|---|---|
| docs/contributing.rst | 贡献指南原文(本文主体) |
| CODE_OF_CONDUCT.md | Contributor Covenant 1.4 行为准则 |
| .github/ISSUE_TEMPLATE.rst | Issue 提交前自查清单 |
| .github/workflows/tests.yml | CI 工作流:docs / lint / test / 打包 / 发布 |
| pyproject.toml | 依赖、dev 依赖、coverage / mypy / ruff 配置 |
| setup.py | CFFI 绑定与 abi3 wheel 构建 |
| MANIFEST.in | sdist 文件收录清单 |
| tests/utils.py | asynctest、假 ICE/DTLS 传输、固件加载 |
| .readthedocs.yaml | 在线文档构建环境 |
- 音视频
- 通信
【免费下载链接】aiortc
WebRTC and ORTC implementation for Python using asyncio
相关推荐
NautilusTrader 贡献指南:从 Issue 到可合入 Pull Request 的完整实战流程
NautilusTrader 贡献指南:从 Issue 到可合入 Pull Request 的完整实战流程 本篇技术指南完整解析 NautilusTrader
金融科技后端gitsome 贡献指南:从提交 Issue 到合并 Pull Request 的完整实战流程
gitsome 贡献指南:从提交 Issue 到合并 Pull Request 的完整实战流程 gitsome 是一个"超级充电"式的 Git/GitHub 命
开发工具版本控制Spack 贡献指南:从 Pull Request 到 CI 全流程实战
Spack 贡献指南:从 Pull Request 到 CI 全流程实战 面向希望向 Spack 提交新包、新特性或 bug 修复的开发者与管理员。本文以官方
开发工具构建工具CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考