wrtc 0.0.2__tar.gz → 0.2.0__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.
- {wrtc-0.0.2 → wrtc-0.2.0}/CHANGES.md +84 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/CMakeLists.txt +3 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/Makefile +8 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/PKG-INFO +26 -6
- {wrtc-0.0.2 → wrtc-0.2.0}/README.md +22 -4
- {wrtc-0.0.2 → wrtc-0.2.0}/THIRD_PARTY_LICENSES.md +28 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/update.py +53 -23
- {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libwebrtc.cmake +31 -0
- wrtc-0.2.0/cmake/libwebrtc_windows.cmake +46 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/cmake/openh264.cmake +0 -31
- {wrtc-0.0.2 → wrtc-0.2.0}/pyproject.toml +21 -6
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/CMakeLists.txt +4 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/NATIVE.md +15 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/openh264_decoder.cpp +11 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/openh264_decoder.h +5 -0
- wrtc-0.2.0/python-webrtc/cpp/src/codecs/video_codec_factories.cpp +101 -0
- wrtc-0.2.0/python-webrtc/cpp/src/codecs/video_codec_factories.h +24 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/videotoolbox.mm +119 -32
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/media_stream_track.cpp +11 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/peer_connection_factory.cpp +70 -54
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/peer_connection_factory.h +6 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_audio_track_source.cpp +5 -3
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_audio_track_source.h +3 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_data_channel.cpp +60 -25
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_data_channel.h +12 -8
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_dtls_transport.cpp +5 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_dtmf_sender.cpp +39 -32
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_dtmf_sender.h +8 -4
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_ice_transport.cpp +153 -47
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_ice_transport.h +14 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/create_session_description_observer.cpp +5 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/descriptions.cpp +125 -31
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/ice.cpp +132 -49
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/rtc_peer_connection.cpp +60 -30
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/rtc_peer_connection.h +61 -14
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/rtp.cpp +81 -11
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/stats_collector_callback.h +6 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_sender.cpp +28 -17
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_sender.h +4 -4
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_transceiver.cpp +18 -4
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_transceiver.h +3 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_sctp_transport.cpp +19 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_sctp_transport.h +3 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_video_track_source.cpp +21 -26
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_video_track_source.h +5 -1
- wrtc-0.2.0/python-webrtc/cpp/src/interfaces/transceiver_state.h +36 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/encoded_frame.cpp +4 -10
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/encoded_frame.h +2 -1
- wrtc-0.2.0/python-webrtc/cpp/src/media/frame_adaptation.h +47 -0
- wrtc-0.2.0/python-webrtc/cpp/src/media/frame_buffer_pool.h +102 -0
- wrtc-0.2.0/python-webrtc/cpp/src/media/local_video_sink.h +60 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/media_stream_track_processor.cpp +5 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/media_stream_track_processor.h +3 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/relayed_video_track.cpp +13 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/relayed_video_track.h +8 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/rtc_rtp_script_transform.cpp +7 -10
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/rtc_rtp_script_transform.h +1 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/track_generator.cpp +18 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/track_generator.h +5 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/track_monitor.h +3 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/video_frame_buffer.cpp +72 -19
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_configuration.cpp +1 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_configuration.h +1 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/testing.cpp +84 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/buffer.h +5 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/dispatcher.cpp +8 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/field_trials.h +2 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/libwebrtc_thread.h +19 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/mailbox.cpp +6 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/mailbox.h +39 -9
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/native_object.h +23 -4
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/network_socket_server.cpp +297 -20
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/network_socket_server.h +18 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/port_allocator.cpp +15 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/port_allocator.h +3 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/surfaced.h +11 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/__init__.py +1 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/_alias.py +27 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/_ice_servers.py +124 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/_utils.py +17 -5
- wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/clock.py +57 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/jitterbuffer.py +152 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcdatachannel.py +7 -4
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcdtlstransport.py +6 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcicetransport.py +9 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcpeerconnection.py +215 -91
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcrtpreceiver.py +159 -20
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcrtpsender.py +84 -26
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcrtptransceiver.py +10 -4
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcsctptransport.py +2 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/rtp.py +818 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/utils.py +82 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/base.py +3 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/exceptions.py +7 -9
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/field_trials.py +6 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/media_devices.py +13 -6
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/media_stream.py +4 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/media_stream_track.py +75 -34
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/media_stream_track_processor.py +25 -20
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_data_channel.py +17 -10
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_dtmf_sender.py +9 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_ice_transport.py +15 -10
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_peer_connection.py +81 -69
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_rtp_receiver.py +50 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_rtp_script_transform.py +40 -23
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_rtp_sender.py +30 -11
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_rtp_transceiver.py +3 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_sctp_transport.py +3 -3
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/sframe_transform.py +13 -8
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/track_generator.py +11 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/loopback.py +1 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/audio_data.py +24 -13
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/blob.py +21 -6
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/events.py +1 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/media_track_constraints.py +3 -3
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_certificate.py +13 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_configuration.py +32 -18
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_encoded_frame.py +23 -13
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_ice_candidate.py +30 -12
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_stats.py +72 -29
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtp_parameters.py +48 -19
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtp_source.py +13 -9
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/video_frame.py +136 -67
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/openh264.py +34 -18
- wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/__init__.py +22 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/_alias.py +26 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/_media.py +524 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/connection.py +694 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/request_handler.py +294 -0
- wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/transport.py +703 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/streams.py +161 -106
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/events.py +95 -32
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/lifetime.py +3 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/loops.py +190 -91
- wrtc-0.2.0/python-webrtc/python/webrtc/utils/module_alias.py +92 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/names.py +9 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/operations.py +69 -28
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/strings.py +8 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/transfer.py +7 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/cover.py +60 -24
- {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/hunt.py +140 -59
- {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/stacks.py +27 -7
- {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/triage.py +66 -25
- {wrtc-0.0.2 → wrtc-0.2.0}/stubs/wrtc/__init__.pyi +18 -11
- {wrtc-0.0.2 → wrtc-0.2.0}/stubs/wrtc/_testing.pyi +15 -0
- wrtc-0.0.2/python-webrtc/python/webrtc/aiortc/rtp.py → wrtc-0.2.0/tests/aiortc/conftest.py +5 -1
- wrtc-0.2.0/tests/aiortc/test_alias.py +89 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/aiortc/test_codecs.py +33 -23
- wrtc-0.2.0/tests/aiortc/test_downstream_names.py +445 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/aiortc/test_media.py +417 -29
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/aiortc/test_peer_connection.py +18 -34
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/chaos.py +175 -110
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/conftest.py +23 -9
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_audio_data.py +16 -3
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_encoded_frame.py +47 -14
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_generator.py +27 -19
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_native_buffers.py +58 -28
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_sframe.py +42 -16
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_sframe_stream.py +16 -3
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_video_frame.py +20 -6
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/h264.py +43 -13
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/helpers.py +168 -51
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/__main__.py +15 -5
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/child.py +2 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/compare.py +53 -20
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/expectations.json +2 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/expectations.py +3 -3
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/spec.py +21 -13
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/isolation.py +18 -7
- wrtc-0.2.0/tests/pipecat/_audio.py +33 -0
- wrtc-0.2.0/tests/pipecat/_client.py +129 -0
- wrtc-0.2.0/tests/pipecat/_stun.py +100 -0
- {wrtc-0.0.2/tests/aiortc → wrtc-0.2.0/tests/pipecat}/conftest.py +4 -4
- wrtc-0.2.0/tests/pipecat/test_alias.py +151 -0
- wrtc-0.2.0/tests/pipecat/test_connection.py +829 -0
- wrtc-0.2.0/tests/pipecat/test_decimator.py +118 -0
- wrtc-0.2.0/tests/pipecat/test_media.py +481 -0
- wrtc-0.2.0/tests/pipecat/test_pipecat_names.py +199 -0
- wrtc-0.2.0/tests/pipecat/test_request_handler.py +312 -0
- wrtc-0.2.0/tests/pipecat/test_transport.py +928 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/rtc_peer_connection/test_add_track.py +7 -16
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/rtc_peer_connection/test_add_transceiver.py +17 -29
- wrtc-0.2.0/tests/rtc_rtp_transceiver/__init__.py +6 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/rtc_rtp_transceiver/test_direction.py +7 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/rtc_rtp_transceiver/test_stop.py +18 -33
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_audio_data.py +77 -30
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_blob.py +10 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_configuration.py +77 -21
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_connection_states.py +73 -11
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_data_channel.py +309 -24
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_docstrings.py +19 -6
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_e2e.py +8 -11
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_encoded_transform.py +164 -77
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_enums.py +11 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_events.py +199 -14
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_field_trials.py +133 -15
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_free_threading.py +6 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_helpers.py +8 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_ice_transport.py +280 -65
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_lifetime.py +113 -27
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_lifetime_model.py +52 -32
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_lifetime_transforms.py +89 -24
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_loopback.py +5 -1
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_loops.py +95 -23
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_mailbox.py +76 -37
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_media_devices.py +25 -4
- wrtc-0.2.0/tests/test_media_e2e.py +661 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_media_stream_track_processor.py +156 -85
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_media_stress.py +35 -19
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_native_calls.py +14 -3
- wrtc-0.2.0/tests/test_native_rules.py +225 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_network.py +93 -11
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_network_stress.py +102 -29
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_openh264.py +68 -12
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_openh264_encoder.py +30 -10
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_openh264_interop.py +68 -45
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_operations.py +90 -24
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_package.py +20 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_chaos.py +8 -2
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_exit.py +3 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_media.py +18 -13
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_threads.py +112 -16
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_transforms.py +23 -21
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_rtp_sender_receiver.py +169 -59
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_sdp_munging.py +41 -18
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_session_description.py +25 -8
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_sframe.py +241 -117
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_stats.py +33 -7
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_streams.py +146 -18
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_track_settings.py +53 -31
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_tracks.py +65 -14
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_video.py +26 -25
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_video_frame.py +152 -133
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_videotoolbox.py +65 -49
- {wrtc-0.0.2 → wrtc-0.2.0}/uv.lock +2563 -79
- wrtc-0.0.2/tests/test_media_e2e.py +0 -301
- wrtc-0.0.2/tests/test_native_rules.py +0 -95
- {wrtc-0.0.2 → wrtc-0.2.0}/.clang-format +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/.clang-tidy +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/.gitignore +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/.mailmap +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/.readthedocs.yaml +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/CONTRIBUTING.md +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/LICENSE.md +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/SECURITY.md +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/README.md +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/config.sha256 +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/headers.sha256 +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/runtime.sha256 +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libwebrtc_linux_fixups.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/cmake/openh264.sha256 +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/openh264.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/openh264.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/videotoolbox.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/enums/enums.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/enums/enums.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/exceptions.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/exceptions.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/functions/functions.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/functions/functions.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/functions/get_user_media.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/functions/get_user_media.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/interfaces.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/interfaces.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/media_stream.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/media_stream.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/media_stream_track.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_dtls_transport.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/create_session_description_observer.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/sdp.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/sdp.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/set_session_description_observer.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_receiver.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_receiver.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/audio_samples.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/audio_samples.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/boringssl.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/frame_transformer_bridge.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/frame_transformer_bridge.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/media.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/media.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/playout_audio_device.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/playout_audio_device.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/sframe.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/sframe.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/sframe_transform.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/sframe_transform.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/source_control.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/video_frame_buffer.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/models.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/models.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_certificate.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_certificate.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_ice_candidate.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_ice_candidate.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_session_description.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_session_description.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_session_description_init.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_session_description_init.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/webrtc/rtp_parameters.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/webrtc/rtp_parameters.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/webrtc/rtp_transceiver_init.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/module.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/testing.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/absl_optional.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/dispatcher.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/gil.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/held_events.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/locked_function.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/paced_thread.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/parking.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/registry.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/task_queue_factory.cpp +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/task_queue_factory.h +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/codecs/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/codecs/h264.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/codecs/vpx.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/contrib/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/contrib/media.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/contrib/signaling.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/events.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/exceptions.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/mediastreams.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcconfiguration.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcrtpparameters.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcsessiondescription.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/sdp.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/stats.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/enums.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_dtls_transport.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/closable.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/dictionary.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_offer_answer_options.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_rtp_transceiver_init.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_session_description.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_session_description_init.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/sframe_transform_options.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/openh264_license.txt +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/py.typed +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/scripts/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/README.md +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/cores.entitlements +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/synthetic.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/aiortc/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/README.md +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/inputs.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/LICENSE-W3C.md +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/README.md +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/test_compare.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/test_idl.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/webrtc-extensions.idl +0 -0
- {wrtc-0.0.2/tests/rtc_peer_connection → wrtc-0.2.0/tests/pipecat}/__init__.py +0 -0
- {wrtc-0.0.2/tests/rtc_rtp_transceiver → wrtc-0.2.0/tests/rtc_peer_connection}/__init__.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_isolation.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_exit_handlers.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_task_queues.py +0 -0
- {wrtc-0.0.2 → wrtc-0.2.0}/tests/timing.py +0 -0
|
@@ -1,5 +1,89 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## Version 0.2.0
|
|
4
|
+
|
|
5
|
+
**02.11.2026**
|
|
6
|
+
|
|
7
|
+
**🤖 Pipecat bots run on the engine: install `wrtc[pipecat]` and change the imports, and clients stay as they are. See [Use with Pipecat](https://wrtc.marshal.dev/guides/pipecat/)**
|
|
8
|
+
|
|
9
|
+
**🧩 More libraries built on aiortc run on the compat layer unchanged, with `webrtc.aiortc.install_alias()`**
|
|
10
|
+
|
|
11
|
+
**🔌 Clients that can't use UDP reach a server over TCP, without TURN, with `RTCConfiguration.tcp_listen`. See [Clients without UDP](https://wrtc.marshal.dev/guides/connections/#clients-without-udp)**
|
|
12
|
+
|
|
13
|
+
* Add `webrtc.pipecat`, Pipecat's SmallWebRTC transport on the native API, installed with `wrtc[pipecat]`, with `install_alias()` for Pipecat's development runner by [@MarshalX](https://github.com/MarshalX) in [#277](https://github.com/MarshalX/python-webrtc/pull/277)
|
|
14
|
+
* Add a Pipecat voice bot example, with an echo that needs no keys by [@MarshalX](https://github.com/MarshalX) in [#277](https://github.com/MarshalX/python-webrtc/pull/277)
|
|
15
|
+
* Add `webrtc.aiortc.install_alias()`, which makes `import aiortc` give the compat layer, for libraries that import aiortc themselves by [@MarshalX](https://github.com/MarshalX) in [#276](https://github.com/MarshalX/python-webrtc/pull/276)
|
|
16
|
+
* Add aiortc's `rtp`, `jitterbuffer`, `utils` and `clock` modules and the ICE server helpers of `rtcicetransport` to the compat layer by [@MarshalX](https://github.com/MarshalX) in [#276](https://github.com/MarshalX/python-webrtc/pull/276)
|
|
17
|
+
* Drop a compat layer track's buffered frames when its receiver's `_enabled` is set to `False`, and add the track's `_queue`, for libraries that skip stale frames by [@MarshalX](https://github.com/MarshalX) in [#276](https://github.com/MarshalX/python-webrtc/pull/276)
|
|
18
|
+
* Add `RTCConfiguration.tcp_listen` for clients without UDP, also on `webrtc.pipecat`'s connection and request handler by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
|
|
19
|
+
* Add a library comparison guide, a README demo and copy-page actions to the docs by [@MarshalX](https://github.com/MarshalX) in [#271](https://github.com/MarshalX/python-webrtc/pull/271)
|
|
20
|
+
* Fix a video frame leak in the compat layer when a sender's track is replaced or stopped by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
|
|
21
|
+
* Fix compat layer audio `pts` falling behind after dropped audio by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
|
|
22
|
+
* Fix a cancelled stream read losing the next chunk by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
|
|
23
|
+
* Fix ICE and DTLS transport states changing before their events by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
|
|
24
|
+
* Fix the docs' contrast, mobile overflow and dead API links by [@MarshalX](https://github.com/MarshalX) in [#275](https://github.com/MarshalX/python-webrtc/pull/275)
|
|
25
|
+
|
|
26
|
+
## Version 0.1.0
|
|
27
|
+
|
|
28
|
+
**24.10.2026**
|
|
29
|
+
|
|
30
|
+
**🧪 The first beta: the API follows the specifications and is ready to build on, while compatibility between versions isn't guaranteed until 1.0.0**
|
|
31
|
+
|
|
32
|
+
**⚡ Data channels move 1.2–2.1 Gbps, 7.7–14.6x aiortc's throughput at 10–15% of its CPU per MB. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/)**
|
|
33
|
+
|
|
34
|
+
**🚀 A data channel opens 3.5 ms after `createOffer`, 7–8x faster than aiortc, and `getStats` takes 1.7 instead of 4.2 ms**
|
|
35
|
+
|
|
36
|
+
**🎥 Simulcast for every encoder, and H.264 on macOS that recovers from encoder faults and falls back to OpenH264**
|
|
37
|
+
|
|
38
|
+
**🧭 Transceiver, ICE, SCTP and track state change with the events that report them, as in browsers**
|
|
39
|
+
|
|
40
|
+
**🧩 [Examples](https://wrtc.marshal.dev/examples/) of a server for a browser page, a Gemini Live voice agent, and WHIP/WHEP streams**
|
|
41
|
+
|
|
42
|
+
* Add simulcast for every encoder, on Windows too: each layer is sent in the negotiated codec at its scaled size, whether or not the encoder does simulcast itself. VP9 and AV1 need a `scalabilityMode` such as `L1T1` for each layer by [@MarshalX](https://github.com/MarshalX) in [#254](https://github.com/MarshalX/python-webrtc/pull/254)
|
|
43
|
+
* Fall back to OpenH264, once `await webrtc.openh264.install()` has run, when VideoToolbox can't encode or decode by [@MarshalX](https://github.com/MarshalX) in [#254](https://github.com/MarshalX/python-webrtc/pull/254)
|
|
44
|
+
* Show transceiver, ICE, SCTP and track state with the events that change them: `mid`, `currentDirection` and the selected candidate pair change when their event fires, not before by [@MarshalX](https://github.com/MarshalX) in [#259](https://github.com/MarshalX/python-webrtc/pull/259)
|
|
45
|
+
* Add a Python server for a browser page example: your camera comes back in grayscale, and Python answers a chat over a data channel by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
|
|
46
|
+
* Add a Gemini Live voice agent example, with the API key kept on the server by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
|
|
47
|
+
* Add a WHIP/WHEP example that plays a live stream in the terminal or publishes one by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
|
|
48
|
+
* Add llms.txt, Markdown versions of the docs pages and Context7 and DeepWiki configs by [@MarshalX](https://github.com/MarshalX) in [#265](https://github.com/MarshalX/python-webrtc/pull/265)
|
|
49
|
+
* Credit node-webrtc in the third-party licences by [@MarshalX](https://github.com/MarshalX) in [#262](https://github.com/MarshalX/python-webrtc/pull/262)
|
|
50
|
+
* Speed up connection setup: keep libsrtp initialized and the network list updated, start the network manager and create port allocators without waiting on the network thread by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
51
|
+
* Speed up the first connection by running libsrtp's self-tests on their own thread by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
52
|
+
* Gather a candidate pool without waits between phases, and add ICE candidates in one signaling task by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
53
|
+
* Cut thread hops from negotiation and `getStats`, and share concurrent `getStats` calls: 20 of them take 5.7 instead of 80.9 ms, renegotiation 22% less time and warm setup with trickle 18% less by [@MarshalX](https://github.com/MarshalX) in [#255](https://github.com/MarshalX/python-webrtc/pull/255)
|
|
54
|
+
* Cut signaling-thread waits from getters: `transceiver.mid` takes 1.0 instead of 9.8 µs, `sender.track` 38% less time, `getSelectedCandidatePair()` 46% less and renegotiation 15% less by [@MarshalX](https://github.com/MarshalX) in [#259](https://github.com/MarshalX/python-webrtc/pull/259)
|
|
55
|
+
* Speed up data channels on macOS and Linux with a second, connected socket for a busy peer. Set the `PythonWebRTC-ConnectedSockets` field trial to `Disabled` to turn it off by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
56
|
+
* Speed up data channel sends with one network-thread task per send, and skip the local address lookup on every UDP packet by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
57
|
+
* Convert received data channel messages once and deliver them with less Python per message by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
58
|
+
* Copy data channel messages once: 10–11% more throughput and 7–11% less CPU per MB for 1 KB messages by [@MarshalX](https://github.com/MarshalX) in [#252](https://github.com/MarshalX/python-webrtc/pull/252)
|
|
59
|
+
* Speed up event delivery, skip wake-ups while the event loop drains, and cache session descriptions between the events that change them by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
60
|
+
* Drop the unused audio processing and video render smoothing, which cost CPU on every received stream by [@MarshalX](https://github.com/MarshalX) in [#249](https://github.com/MarshalX/python-webrtc/pull/249)
|
|
61
|
+
* Send VP8 and H.264 at 720p with 6–9% less CPU per frame by [@MarshalX](https://github.com/MarshalX) in [#256](https://github.com/MarshalX/python-webrtc/pull/256)
|
|
62
|
+
* Wrap NV12 frames without copies, pass NV12 to VideoToolbox as it is, and pool frame buffers by [@MarshalX](https://github.com/MarshalX) in [#257](https://github.com/MarshalX/python-webrtc/pull/257)
|
|
63
|
+
* Copy video frame data once into pooled buffers, and convert VideoToolbox output to I420 in one pass by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
64
|
+
* Copy encoded frames less and cache RTP sources: 14% less CPU per transformed frame, `getSynchronizationSources()` in 1.3 instead of 14.8 µs. A transform now queues up to 60 unread frames instead of 120 by [@MarshalX](https://github.com/MarshalX) in [#258](https://github.com/MarshalX/python-webrtc/pull/258)
|
|
65
|
+
* Fix sockets raising SIGPIPE on macOS, which kills the process where its default handler is restored by [@MarshalX](https://github.com/MarshalX) in [#267](https://github.com/MarshalX/python-webrtc/pull/267)
|
|
66
|
+
* Fix data channel stalls under load: UDP sockets get a receive buffer of at least 8 MB, which `WebRTC-SetSocketReceiveBuffer` overrides. On Linux, raise `net.core.rmem_max` to allow it. See [Field trials](https://wrtc.marshal.dev/guides/field-trials/) by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
67
|
+
* Fix a VideoToolbox frame that fails after the encoder took it: the session restarts with a key frame by [@MarshalX](https://github.com/MarshalX) in [#254](https://github.com/MarshalX/python-webrtc/pull/254)
|
|
68
|
+
* Fix a connection kept alive after `close()` by the event loop it was bound to while closing by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
69
|
+
* Fix the operations of a closed event loop keeping their connections alive by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
70
|
+
* Fix the next operation starting before the code awaiting the previous one resumes, as in browsers by [@MarshalX](https://github.com/MarshalX) in [#259](https://github.com/MarshalX/python-webrtc/pull/259)
|
|
71
|
+
* Fix `addIceCandidate` without a remote description rejecting late; it now rejects at once by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
|
|
72
|
+
* Fix sends that fail as the remote end closes: they fire `error` with `data-channel-failure`, and their bytes stay in `bufferedAmount` by [@MarshalX](https://github.com/MarshalX) in [#252](https://github.com/MarshalX/python-webrtc/pull/252)
|
|
73
|
+
* Fix remote data channels collected before their `open` event by [@MarshalX](https://github.com/MarshalX) in [#259](https://github.com/MarshalX/python-webrtc/pull/259)
|
|
74
|
+
* Fix DTMF tones and gaps raised to longer minimums than the specification's by [@MarshalX](https://github.com/MarshalX) in [#253](https://github.com/MarshalX/python-webrtc/pull/253)
|
|
75
|
+
* Fix standalone ICE gathering waiting 1 s between phases and gathering passive TCP candidates, and gather IPv6 where the host has it by [@MarshalX](https://github.com/MarshalX) in [#253](https://github.com/MarshalX/python-webrtc/pull/253)
|
|
76
|
+
* Fix the end of candidates of an earlier remote description shown after an ICE restart by [@MarshalX](https://github.com/MarshalX) in [#253](https://github.com/MarshalX/python-webrtc/pull/253)
|
|
77
|
+
* Fix the audio capture time, so the jitter doesn't jump after a send pause by [@MarshalX](https://github.com/MarshalX) in [#253](https://github.com/MarshalX/python-webrtc/pull/253)
|
|
78
|
+
* Fix `VideoTrackGenerator` frames written back to back dropped as duplicates by [@MarshalX](https://github.com/MarshalX) in [#256](https://github.com/MarshalX/python-webrtc/pull/256)
|
|
79
|
+
* Fix relayed remote video not scaled down for its encoder at low bitrates, and a sent track's own sinks getting the encoder's smaller frames by [@MarshalX](https://github.com/MarshalX) in [#256](https://github.com/MarshalX/python-webrtc/pull/256)
|
|
80
|
+
* Fix encoded frames a transform drops staying in memory while the event loop is busy or closed by [@MarshalX](https://github.com/MarshalX) in [#260](https://github.com/MarshalX/python-webrtc/pull/260)
|
|
81
|
+
* Fix writes to a writable stream slowing down as its queue grows by [@MarshalX](https://github.com/MarshalX) in [#264](https://github.com/MarshalX/python-webrtc/pull/264)
|
|
82
|
+
* Fix the empty reason in the OpenAI example's connection error by [@MarshalX](https://github.com/MarshalX) in [#264](https://github.com/MarshalX/python-webrtc/pull/264)
|
|
83
|
+
* Fix the OpenAI example printing the API key in `--help` by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
|
|
84
|
+
* Fix the memory benchmark table when a run stops early at the memory limit, and benchmark charts crashing on a zero value or baseline by [@MarshalX](https://github.com/MarshalX) in [#264](https://github.com/MarshalX/python-webrtc/pull/264)
|
|
85
|
+
* Fix the connections guide's advice to wait for complete ICE gathering, which can take about 40 seconds with a STUN server by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
|
|
86
|
+
|
|
3
87
|
## Version 0.0.2
|
|
4
88
|
|
|
5
89
|
**15.10.2026**
|
|
@@ -33,5 +33,8 @@ find_package(Python 3.9 REQUIRED COMPONENTS Interpreter Development.Module)
|
|
|
33
33
|
find_package(pybind11 CONFIG REQUIRED)
|
|
34
34
|
|
|
35
35
|
include(cmake/openh264.cmake)
|
|
36
|
+
if(WIN32)
|
|
37
|
+
include(cmake/libwebrtc_windows.cmake)
|
|
38
|
+
endif()
|
|
36
39
|
|
|
37
40
|
add_subdirectory(python-webrtc/cpp)
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# pinned to the clang-tidy of .github/scripts/tidy.sh
|
|
4
4
|
CLANG_FORMAT := uvx clang-format==22.1.8
|
|
5
|
+
# pinned so a new release can't break lint; bump together with .github/workflows/ci.yml
|
|
6
|
+
RUFF := uvx ruff==0.17.1
|
|
7
|
+
PYREFLY := uvx pyrefly==1.3.2
|
|
5
8
|
CPP_SRC = $(shell find python-webrtc/cpp/src -name '*.cpp' -o -name '*.h' -o -name '*.mm')
|
|
6
9
|
|
|
7
10
|
# editable install; the extension is rebuilt automatically on import after C++ changes
|
|
@@ -50,15 +53,15 @@ stacks:
|
|
|
50
53
|
uv run --no-sync python -m scripts.debug.stacks $(PID) $(O)
|
|
51
54
|
|
|
52
55
|
lint: format-check
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
$(RUFF) check
|
|
57
|
+
$(RUFF) format --check
|
|
55
58
|
|
|
56
59
|
typecheck:
|
|
57
|
-
|
|
60
|
+
$(PYREFLY) check
|
|
58
61
|
|
|
59
62
|
format:
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
$(RUFF) check --fix
|
|
64
|
+
$(RUFF) format
|
|
62
65
|
$(CLANG_FORMAT) -i $(CPP_SRC)
|
|
63
66
|
|
|
64
67
|
format-check:
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wrtc
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Chrome's WebRTC engine (libwebrtc M152), with the browser API, in Python
|
|
5
5
|
Keywords: webrtc,libwebrtc,rtc,peer-to-peer,data-channel,video,audio,voip,asyncio,w3c
|
|
6
6
|
Author-Email: "Ilya (Marshal)" <ilya@marshal.dev>
|
|
7
7
|
License-Expression: BSD-3-Clause
|
|
8
8
|
License-File: LICENSE.md
|
|
9
9
|
License-File: THIRD_PARTY_LICENSES.md
|
|
10
|
-
Classifier: Development Status ::
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Natural Language :: English
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: Framework :: AsyncIO
|
|
@@ -51,6 +51,8 @@ Requires-Dist: typing_extensions>=4.10
|
|
|
51
51
|
Provides-Extra: aiortc
|
|
52
52
|
Requires-Dist: pyee<15,>=13; extra == "aiortc"
|
|
53
53
|
Requires-Dist: av<18,>=14; extra == "aiortc"
|
|
54
|
+
Provides-Extra: pipecat
|
|
55
|
+
Requires-Dist: pipecat-ai<2,>=1.15; python_version >= "3.11" and extra == "pipecat"
|
|
54
56
|
Description-Content-Type: text/markdown
|
|
55
57
|
|
|
56
58
|
<p align="center">
|
|
@@ -73,6 +75,15 @@ Description-Content-Type: text/markdown
|
|
|
73
75
|
<a href="https://pypi.org/project/wrtc/">PyPI</a>
|
|
74
76
|
</p>
|
|
75
77
|
|
|
78
|
+
<p align="center">
|
|
79
|
+
<picture>
|
|
80
|
+
<source media="(prefers-color-scheme: dark)" type="image/avif" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-dark.avif">
|
|
81
|
+
<source type="image/avif" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-light.avif">
|
|
82
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-dark.gif">
|
|
83
|
+
<img src="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-light.gif" alt="A browser page sends its camera to a Python server, which sends it back in grayscale and answers a chat message over a data channel">
|
|
84
|
+
</picture>
|
|
85
|
+
</p>
|
|
86
|
+
|
|
76
87
|
---
|
|
77
88
|
|
|
78
89
|
Python WebRTC binds **libwebrtc M152**, the engine inside Chrome, and exposes it through the **W3C APIs you
|
|
@@ -153,11 +164,13 @@ equal to the strings of the specification, dictionaries are typed dataclasses, a
|
|
|
153
164
|
| Browser API (`RTCPeerConnection`, `createOffer`, …) | ✅ | similar | ❌ rooms | ❌ GObject signals |
|
|
154
165
|
| Media path | native | Python | native | native |
|
|
155
166
|
| VP9 and AV1 | ✅ | ❌ | ✅ | ✅ |
|
|
156
|
-
| `pip install` on Linux, macOS and Windows | ✅ | ✅ | ✅ | ❌
|
|
167
|
+
| `pip install` on Linux, macOS and Windows | ✅ | ✅ | ✅ | ❌ no Linux wheels |
|
|
157
168
|
|
|
158
|
-
Against aiortc, it opens connections
|
|
159
|
-
audio. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/), which also measure Pion, libdatachannel
|
|
160
|
-
webrtc-rs.
|
|
169
|
+
Against aiortc, it opens connections 7.3–8.3x faster, moves 7.7–14.6x more data through a data channel and spends
|
|
170
|
+
less CPU on audio. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/), which also measure Pion, libdatachannel
|
|
171
|
+
and webrtc-rs.
|
|
172
|
+
|
|
173
|
+
The full comparison, and when another library is the better choice: [Choosing a Python WebRTC library](https://wrtc.marshal.dev/guides/comparison/).
|
|
161
174
|
|
|
162
175
|
## Codecs
|
|
163
176
|
|
|
@@ -194,6 +207,13 @@ Complete programs, ready to copy. The ones with dependencies declare them inline
|
|
|
194
207
|
uv run https://raw.githubusercontent.com/MarshalX/python-webrtc/main/examples/janus_streaming.py
|
|
195
208
|
```
|
|
196
209
|
|
|
210
|
+
## Pipecat
|
|
211
|
+
|
|
212
|
+
Install `wrtc[pipecat]` and import the SmallWebRTC transport from `webrtc.pipecat`, and your
|
|
213
|
+
[Pipecat](https://www.pipecat.ai) bot runs on Chrome's engine, with its clients unchanged. For Pipecat's development
|
|
214
|
+
runner, call `webrtc.pipecat.install_alias()`. See [Use with Pipecat](https://wrtc.marshal.dev/guides/pipecat/) and the
|
|
215
|
+
[voice bot example](https://github.com/MarshalX/python-webrtc/blob/main/examples/pipecat_bot.py).
|
|
216
|
+
|
|
197
217
|
## Status
|
|
198
218
|
|
|
199
219
|
Pre-1.0: the API follows the specifications, but compatibility between versions isn't guaranteed until 1.0.0. See
|
|
@@ -18,6 +18,15 @@
|
|
|
18
18
|
<a href="https://pypi.org/project/wrtc/">PyPI</a>
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
|
+
<p align="center">
|
|
22
|
+
<picture>
|
|
23
|
+
<source media="(prefers-color-scheme: dark)" type="image/avif" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-dark.avif">
|
|
24
|
+
<source type="image/avif" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-light.avif">
|
|
25
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-dark.gif">
|
|
26
|
+
<img src="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-light.gif" alt="A browser page sends its camera to a Python server, which sends it back in grayscale and answers a chat message over a data channel">
|
|
27
|
+
</picture>
|
|
28
|
+
</p>
|
|
29
|
+
|
|
21
30
|
---
|
|
22
31
|
|
|
23
32
|
Python WebRTC binds **libwebrtc M152**, the engine inside Chrome, and exposes it through the **W3C APIs you
|
|
@@ -98,11 +107,13 @@ equal to the strings of the specification, dictionaries are typed dataclasses, a
|
|
|
98
107
|
| Browser API (`RTCPeerConnection`, `createOffer`, …) | ✅ | similar | ❌ rooms | ❌ GObject signals |
|
|
99
108
|
| Media path | native | Python | native | native |
|
|
100
109
|
| VP9 and AV1 | ✅ | ❌ | ✅ | ✅ |
|
|
101
|
-
| `pip install` on Linux, macOS and Windows | ✅ | ✅ | ✅ | ❌
|
|
110
|
+
| `pip install` on Linux, macOS and Windows | ✅ | ✅ | ✅ | ❌ no Linux wheels |
|
|
102
111
|
|
|
103
|
-
Against aiortc, it opens connections
|
|
104
|
-
audio. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/), which also measure Pion, libdatachannel
|
|
105
|
-
webrtc-rs.
|
|
112
|
+
Against aiortc, it opens connections 7.3–8.3x faster, moves 7.7–14.6x more data through a data channel and spends
|
|
113
|
+
less CPU on audio. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/), which also measure Pion, libdatachannel
|
|
114
|
+
and webrtc-rs.
|
|
115
|
+
|
|
116
|
+
The full comparison, and when another library is the better choice: [Choosing a Python WebRTC library](https://wrtc.marshal.dev/guides/comparison/).
|
|
106
117
|
|
|
107
118
|
## Codecs
|
|
108
119
|
|
|
@@ -139,6 +150,13 @@ Complete programs, ready to copy. The ones with dependencies declare them inline
|
|
|
139
150
|
uv run https://raw.githubusercontent.com/MarshalX/python-webrtc/main/examples/janus_streaming.py
|
|
140
151
|
```
|
|
141
152
|
|
|
153
|
+
## Pipecat
|
|
154
|
+
|
|
155
|
+
Install `wrtc[pipecat]` and import the SmallWebRTC transport from `webrtc.pipecat`, and your
|
|
156
|
+
[Pipecat](https://www.pipecat.ai) bot runs on Chrome's engine, with its clients unchanged. For Pipecat's development
|
|
157
|
+
runner, call `webrtc.pipecat.install_alias()`. See [Use with Pipecat](https://wrtc.marshal.dev/guides/pipecat/) and the
|
|
158
|
+
[voice bot example](https://github.com/MarshalX/python-webrtc/blob/main/examples/pipecat_bot.py).
|
|
159
|
+
|
|
142
160
|
## Status
|
|
143
161
|
|
|
144
162
|
Pre-1.0: the API follows the specifications, but compatibility between versions isn't guaranteed until 1.0.0. See
|
|
@@ -242,7 +242,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
242
242
|
|
|
243
243
|
# aiortc
|
|
244
244
|
The code of webrtc/aiortc/sdp.py, mediastreams.py, rtcconfiguration.py, rtcrtpparameters.py,
|
|
245
|
-
rtcsessiondescription.py, stats.py,
|
|
245
|
+
rtcsessiondescription.py, stats.py, rtp.py, jitterbuffer.py, utils.py, clock.py, _ice_servers.py, contrib/media.py and
|
|
246
|
+
contrib/signaling.py, copied from it:
|
|
246
247
|
```
|
|
247
248
|
Copyright (c) Jeremy Lainé.
|
|
248
249
|
All rights reserved.
|
|
@@ -2185,6 +2186,32 @@ SPDX-License-Identifier: BSD-2-Clause
|
|
|
2185
2186
|
|
|
2186
2187
|
```
|
|
2187
2188
|
|
|
2189
|
+
# node-webrtc
|
|
2190
|
+
The first versions of the C++ bindings (2022) were derived from it:
|
|
2191
|
+
```
|
|
2192
|
+
Copyright (c) 2019 The node-webrtc project authors. All rights reserved.
|
|
2193
|
+
|
|
2194
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
2195
|
+
are permitted provided that the following conditions are met:
|
|
2196
|
+
|
|
2197
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
2198
|
+
list of conditions and the following disclaimer.
|
|
2199
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
2200
|
+
this list of conditions and the following disclaimer in the documentation
|
|
2201
|
+
and/or other materials provided with the distribution.
|
|
2202
|
+
|
|
2203
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
2204
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
2205
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
2206
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
2207
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
2208
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
2209
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
2210
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
2211
|
+
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
2212
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
2213
|
+
```
|
|
2214
|
+
|
|
2188
2215
|
# ooura
|
|
2189
2216
|
```
|
|
2190
2217
|
/*
|
|
@@ -37,19 +37,27 @@ import subprocess
|
|
|
37
37
|
import tempfile
|
|
38
38
|
from concurrent.futures import ThreadPoolExecutor
|
|
39
39
|
from pathlib import Path
|
|
40
|
-
from typing import TypedDict
|
|
40
|
+
from typing import NamedTuple, TypedDict
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class LlvmDir(NamedTuple):
|
|
44
|
+
"""How WebRTC pins a directory of llvm-project."""
|
|
45
|
+
|
|
46
|
+
deps_path: str
|
|
47
|
+
cmake_variable: str
|
|
48
|
+
|
|
41
49
|
|
|
42
50
|
REPO = 'repos/llvm/llvm-project'
|
|
43
51
|
CHROMIUM_CONFIG = ('__config_site', '__assertion_handler')
|
|
44
|
-
# llvm-project dir -> (its DEPS path in WebRTC, CMake variable of its commit)
|
|
45
52
|
LLVM_DIRS = {
|
|
46
|
-
'libcxx': ('src/third_party/libc++/src', 'LIBCXX_LLVM_COMMIT'),
|
|
47
|
-
'libcxxabi': ('src/third_party/libc++abi/src', 'LIBCXXABI_LLVM_COMMIT'),
|
|
48
|
-
'libc': ('src/third_party/llvm-libc/src', 'LLVM_LIBC_COMMIT'),
|
|
53
|
+
'libcxx': LlvmDir('src/third_party/libc++/src', 'LIBCXX_LLVM_COMMIT'),
|
|
54
|
+
'libcxxabi': LlvmDir('src/third_party/libc++abi/src', 'LIBCXXABI_LLVM_COMMIT'),
|
|
55
|
+
'libc': LlvmDir('src/third_party/llvm-libc/src', 'LLVM_LIBC_COMMIT'),
|
|
49
56
|
}
|
|
50
57
|
# llvm-project dirs the runtime sources include from: their own trees, and llvm-libc (-I libc)
|
|
51
58
|
RUNTIME_TREES = ('libcxx/src', 'libcxxabi/src', 'libc')
|
|
52
59
|
INCLUDE = re.compile(rb'^\s*#\s*include\s*[<"]([^>"]+)[>"]', re.MULTILINE)
|
|
60
|
+
GITHUB_TIME = '%Y-%m-%dT%H:%M:%SZ'
|
|
53
61
|
|
|
54
62
|
|
|
55
63
|
class TreeEntry(TypedDict):
|
|
@@ -90,7 +98,8 @@ def gh(path: str) -> bytes:
|
|
|
90
98
|
|
|
91
99
|
def git_tree(sha: str, *, recursive: bool = False) -> Tree:
|
|
92
100
|
"""A git tree of llvm-project."""
|
|
93
|
-
|
|
101
|
+
query = '?recursive=1' if recursive else ''
|
|
102
|
+
tree: Tree = json.loads(gh(f'{REPO}/git/trees/{sha}{query}'))
|
|
94
103
|
return tree
|
|
95
104
|
|
|
96
105
|
|
|
@@ -141,22 +150,32 @@ def git_fetch(url: str, ref: str, repo: str) -> str:
|
|
|
141
150
|
return subprocess.check_output([git, '-C', repo, 'rev-parse', 'FETCH_HEAD'], text=True).strip()
|
|
142
151
|
|
|
143
152
|
|
|
153
|
+
def commits_near(name: str, committed: str) -> list[Commit]:
|
|
154
|
+
"""The llvm-project commits that changed a directory within a day of an ISO 8601 commit time."""
|
|
155
|
+
date = dt.datetime.fromisoformat(committed).astimezone(dt.timezone.utc)
|
|
156
|
+
since = (date - dt.timedelta(days=1)).strftime(GITHUB_TIME)
|
|
157
|
+
until = (date + dt.timedelta(days=1)).strftime(GITHUB_TIME)
|
|
158
|
+
commits: list[Commit] = json.loads(gh(f'{REPO}/commits?path={name}&since={since}&until={until}&per_page=100'))
|
|
159
|
+
return commits
|
|
160
|
+
|
|
161
|
+
|
|
144
162
|
def resolve_llvm(deps: str, name: str) -> str:
|
|
145
163
|
"""Chromium mirrors each llvm-project dir as its own repo: finds the llvm-project commit with the same tree."""
|
|
146
|
-
|
|
164
|
+
deps_path = LLVM_DIRS[name].deps_path
|
|
165
|
+
match = re.search(rf"'{re.escape(deps_path)}':\s*'([^'@]+)@([0-9a-f]+)'", deps)
|
|
147
166
|
if match is None:
|
|
148
|
-
msg = f'{
|
|
167
|
+
msg = f'{deps_path} is not in the WebRTC DEPS'
|
|
149
168
|
raise SystemExit(msg)
|
|
169
|
+
|
|
150
170
|
url, revision = match.groups()
|
|
151
171
|
with tempfile.TemporaryDirectory() as repo:
|
|
152
172
|
git_fetch(url, revision, repo)
|
|
153
|
-
|
|
173
|
+
log = subprocess.check_output(
|
|
154
174
|
[tool('git'), '-C', repo, 'log', '-1', '--format=%T %cI', 'FETCH_HEAD'], text=True
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
for commit in commits:
|
|
175
|
+
)
|
|
176
|
+
tree, committed = log.split()
|
|
177
|
+
|
|
178
|
+
for commit in commits_near(name, committed):
|
|
160
179
|
if tree_sha(commit['sha'], name) == tree:
|
|
161
180
|
return commit['sha']
|
|
162
181
|
msg = f'no llvm-project commit has the {name} tree of {url}@{revision}'
|
|
@@ -167,10 +186,14 @@ def runtime_sources(tag: str) -> list[str]:
|
|
|
167
186
|
"""The libc++ and libc++abi sources of Chromium's Linux build, as llvm-project paths."""
|
|
168
187
|
sources: list[str] = []
|
|
169
188
|
for gn, llvm in (('libc%2B%2B', 'libcxx'), ('libc%2B%2Babi', 'libcxxabi')):
|
|
170
|
-
|
|
189
|
+
build_gn = chromium(f'buildtools/third_party/{gn}/BUILD.gn', tag).decode()
|
|
190
|
+
for line in build_gn.splitlines():
|
|
171
191
|
match = re.search(r'"//third_party/libc\+\+(?:abi)?/src/src/([^"]+\.cpp)"', line)
|
|
172
|
-
if match is
|
|
173
|
-
|
|
192
|
+
if match is None or line.lstrip().startswith('#'):
|
|
193
|
+
continue
|
|
194
|
+
source = match[1]
|
|
195
|
+
if 'win32' not in source:
|
|
196
|
+
sources.append(f'{llvm}/src/{source}')
|
|
174
197
|
return sorted(set(sources))
|
|
175
198
|
|
|
176
199
|
|
|
@@ -189,20 +212,27 @@ def pin_runtime(commits: dict[str, str], tag: str) -> None:
|
|
|
189
212
|
"""Pins the runtime sources and, transitively, every file they include from RUNTIME_TREES."""
|
|
190
213
|
tree: dict[str, str] = {}
|
|
191
214
|
for root in RUNTIME_TREES:
|
|
192
|
-
|
|
215
|
+
llvm_dir = root.split('/')[0]
|
|
216
|
+
tree.update({f'{root}/{e["path"]}': e['sha'] for e in subtree(commits[llvm_dir], root)})
|
|
217
|
+
|
|
193
218
|
sources = runtime_sources(tag)
|
|
194
219
|
pinned: dict[str, bytes] = {}
|
|
195
220
|
queue = list(sources)
|
|
196
221
|
with ThreadPoolExecutor(8) as pool:
|
|
197
222
|
while len(queue) > 0:
|
|
198
|
-
|
|
199
|
-
|
|
223
|
+
contents = pool.map(blob, [tree[path] for path in queue])
|
|
224
|
+
pinned.update(zip(queue, contents))
|
|
225
|
+
found: set[str] = set()
|
|
226
|
+
for path in queue:
|
|
227
|
+
found |= includes(path, pinned[path])
|
|
200
228
|
queue = sorted(c for c in found if c in tree and c not in pinned)
|
|
229
|
+
|
|
201
230
|
# CMake compiles every pinned libcxx/libcxxabi .cpp, so only the sources may be among them
|
|
202
231
|
stray = [p for p in pinned if p.endswith('.cpp') and p not in sources and not p.startswith('libc/')]
|
|
203
232
|
if len(stray) > 0:
|
|
204
233
|
msg = f'sources include other .cpp files: {stray}'
|
|
205
234
|
raise SystemExit(msg)
|
|
235
|
+
|
|
206
236
|
lines = [f'{hashlib.sha256(data).hexdigest()} {path}\n' for path, data in sorted(pinned.items())]
|
|
207
237
|
(Path(__file__).parent / 'runtime.sha256').write_text(''.join(lines))
|
|
208
238
|
print(f'{len(sources)} runtime sources, {len(lines)} files pinned')
|
|
@@ -227,7 +257,7 @@ def pin_headers(commit: str, headers: Path) -> None:
|
|
|
227
257
|
msg = f'the prebuilt headers differ from llvm-project@{commit}: {mismatches[:10]}'
|
|
228
258
|
raise SystemExit(msg)
|
|
229
259
|
|
|
230
|
-
missing = [e for e in tree if e['path'] not in local and '.' not in e['path']
|
|
260
|
+
missing = [e for e in tree if e['path'] not in local and '.' not in posixpath.basename(e['path'])]
|
|
231
261
|
|
|
232
262
|
def sha256(entry: TreeEntry) -> str:
|
|
233
263
|
data = blob(entry['sha'])
|
|
@@ -262,8 +292,8 @@ def main() -> None:
|
|
|
262
292
|
pin_config(args.chromium_tag)
|
|
263
293
|
pin_runtime(commits, args.chromium_tag)
|
|
264
294
|
|
|
265
|
-
for name,
|
|
266
|
-
print(f'set({
|
|
295
|
+
for name, llvm_dir in LLVM_DIRS.items():
|
|
296
|
+
print(f'set({llvm_dir.cmake_variable} {commits[name]})')
|
|
267
297
|
print(f'set(LIBCXX_CHROMIUM_TAG {args.chromium_tag})')
|
|
268
298
|
|
|
269
299
|
|
|
@@ -69,6 +69,37 @@ function(_fetch_pinned manifest base_url dest)
|
|
|
69
69
|
endforeach()
|
|
70
70
|
endfunction()
|
|
71
71
|
|
|
72
|
+
# Downloads a file of libwebrtc at LIBWEBRTC_COMMIT; googlesource serves files only base64-encoded
|
|
73
|
+
function(_fetch_webrtc path sha256 dest)
|
|
74
|
+
set(_encoded "${dest}.b64")
|
|
75
|
+
foreach(_attempt RANGE 1 4)
|
|
76
|
+
file(DOWNLOAD "https://webrtc.googlesource.com/src/+/${LIBWEBRTC_COMMIT}/${path}?format=TEXT"
|
|
77
|
+
"${_encoded}" STATUS _status TLS_VERIFY ON)
|
|
78
|
+
list(GET _status 0 _code)
|
|
79
|
+
if(_code EQUAL 0)
|
|
80
|
+
execute_process(
|
|
81
|
+
COMMAND "${Python_EXECUTABLE}" -c
|
|
82
|
+
"import base64, pathlib, sys; p = pathlib.Path(sys.argv[2]); p.parent.mkdir(parents=True, exist_ok=True); p.write_bytes(base64.b64decode(pathlib.Path(sys.argv[1]).read_bytes()))"
|
|
83
|
+
"${_encoded}" "${dest}"
|
|
84
|
+
RESULT_VARIABLE _decoded)
|
|
85
|
+
if(_decoded EQUAL 0)
|
|
86
|
+
file(SHA256 "${dest}" _actual)
|
|
87
|
+
if(_actual STREQUAL sha256)
|
|
88
|
+
file(REMOVE "${_encoded}")
|
|
89
|
+
return()
|
|
90
|
+
endif()
|
|
91
|
+
set(_status "SHA256 mismatch: ${_actual}")
|
|
92
|
+
else()
|
|
93
|
+
set(_status "can't decode it")
|
|
94
|
+
endif()
|
|
95
|
+
endif()
|
|
96
|
+
if(_attempt EQUAL 4)
|
|
97
|
+
message(FATAL_ERROR "Failed to fetch ${path} at ${LIBWEBRTC_COMMIT}: ${_status}")
|
|
98
|
+
endif()
|
|
99
|
+
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep ${_attempt})
|
|
100
|
+
endforeach()
|
|
101
|
+
endfunction()
|
|
102
|
+
|
|
72
103
|
# Header directories (relative to include/) needed to compile against the public API.
|
|
73
104
|
set(LIBWEBRTC_HEADER_DIRS
|
|
74
105
|
api audio call common_audio common_video logging media modules net p2p pc
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Fetches the libwebrtc sources the Windows prebuilt compiles out: the simulcast encoder adapter, and the encoder
|
|
2
|
+
# fallback wrapper it creates.
|
|
3
|
+
#
|
|
4
|
+
# Sets LIBWEBRTC_WINDOWS_SRC.
|
|
5
|
+
|
|
6
|
+
set(_sources
|
|
7
|
+
"media/engine/simulcast_encoder_adapter.cc"
|
|
8
|
+
"0fac2e2e51e3bf0a595d10b3ce5e197b1c40e4d11cbd8852d84e1fcf104a6e45"
|
|
9
|
+
"api/video_codecs/video_encoder_software_fallback_wrapper.cc"
|
|
10
|
+
"52251651cb273455adcc8db4dfe1dc654a243e709beb5a528bdbb0279f614908")
|
|
11
|
+
|
|
12
|
+
if(LIBWEBRTC_CACHE_DIR)
|
|
13
|
+
set(_dir "${LIBWEBRTC_CACHE_DIR}/libwebrtc-windows-src-${LIBWEBRTC_VERSION}")
|
|
14
|
+
else()
|
|
15
|
+
set(_dir "${CMAKE_BINARY_DIR}/libwebrtc-windows-src")
|
|
16
|
+
endif()
|
|
17
|
+
|
|
18
|
+
set(LIBWEBRTC_WINDOWS_SRC "")
|
|
19
|
+
set(_stamp "${_dir}/.complete")
|
|
20
|
+
set(_stamp_content "${LIBWEBRTC_COMMIT};${_sources}")
|
|
21
|
+
set(_stamp_current "")
|
|
22
|
+
if(EXISTS "${_stamp}")
|
|
23
|
+
file(READ "${_stamp}" _stamp_current)
|
|
24
|
+
endif()
|
|
25
|
+
set(_fetch FALSE)
|
|
26
|
+
if(NOT _stamp_current STREQUAL _stamp_content)
|
|
27
|
+
message(STATUS "Fetching libwebrtc's simulcast encoder adapter, which the Windows prebuilt lacks")
|
|
28
|
+
file(REMOVE_RECURSE "${_dir}")
|
|
29
|
+
set(_fetch TRUE)
|
|
30
|
+
endif()
|
|
31
|
+
|
|
32
|
+
list(LENGTH _sources _count)
|
|
33
|
+
math(EXPR _last "${_count} - 1")
|
|
34
|
+
foreach(_i RANGE 0 ${_last} 2)
|
|
35
|
+
math(EXPR _j "${_i} + 1")
|
|
36
|
+
list(GET _sources ${_i} _path)
|
|
37
|
+
list(GET _sources ${_j} _sha)
|
|
38
|
+
if(_fetch)
|
|
39
|
+
_fetch_webrtc("${_path}" "${_sha}" "${_dir}/${_path}")
|
|
40
|
+
endif()
|
|
41
|
+
list(APPEND LIBWEBRTC_WINDOWS_SRC "${_dir}/${_path}")
|
|
42
|
+
endforeach()
|
|
43
|
+
|
|
44
|
+
if(_fetch)
|
|
45
|
+
file(WRITE "${_stamp}" "${_stamp_content}")
|
|
46
|
+
endif()
|
|
@@ -16,37 +16,6 @@ endif()
|
|
|
16
16
|
set(OPENH264_INCLUDE_DIR "${_dir}/include")
|
|
17
17
|
set(OPENH264_ENCODER_SRC "${_dir}/webrtc/${_encoder}.cc")
|
|
18
18
|
|
|
19
|
-
# Downloads a file of libwebrtc at LIBWEBRTC_COMMIT; googlesource serves files only base64-encoded
|
|
20
|
-
function(_fetch_webrtc path sha256 dest)
|
|
21
|
-
set(_encoded "${dest}.b64")
|
|
22
|
-
foreach(_attempt RANGE 1 4)
|
|
23
|
-
file(DOWNLOAD "https://webrtc.googlesource.com/src/+/${LIBWEBRTC_COMMIT}/${path}?format=TEXT"
|
|
24
|
-
"${_encoded}" STATUS _status TLS_VERIFY ON)
|
|
25
|
-
list(GET _status 0 _code)
|
|
26
|
-
if(_code EQUAL 0)
|
|
27
|
-
execute_process(
|
|
28
|
-
COMMAND "${Python_EXECUTABLE}" -c
|
|
29
|
-
"import base64, pathlib, sys; p = pathlib.Path(sys.argv[2]); p.parent.mkdir(parents=True, exist_ok=True); p.write_bytes(base64.b64decode(pathlib.Path(sys.argv[1]).read_bytes()))"
|
|
30
|
-
"${_encoded}" "${dest}"
|
|
31
|
-
RESULT_VARIABLE _decoded)
|
|
32
|
-
if(_decoded EQUAL 0)
|
|
33
|
-
file(SHA256 "${dest}" _actual)
|
|
34
|
-
if(_actual STREQUAL sha256)
|
|
35
|
-
file(REMOVE "${_encoded}")
|
|
36
|
-
return()
|
|
37
|
-
endif()
|
|
38
|
-
set(_status "SHA256 mismatch: ${_actual}")
|
|
39
|
-
else()
|
|
40
|
-
set(_status "can't decode it")
|
|
41
|
-
endif()
|
|
42
|
-
endif()
|
|
43
|
-
if(_attempt EQUAL 4)
|
|
44
|
-
message(FATAL_ERROR "Failed to fetch ${path} at ${LIBWEBRTC_COMMIT}: ${_status}")
|
|
45
|
-
endif()
|
|
46
|
-
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep ${_attempt})
|
|
47
|
-
endforeach()
|
|
48
|
-
endfunction()
|
|
49
|
-
|
|
50
19
|
file(SHA256 "${CMAKE_CURRENT_LIST_DIR}/openh264.sha256" _manifest_hash)
|
|
51
20
|
set(_stamp "${_dir}/.complete")
|
|
52
21
|
set(_stamp_content
|