python-aidot-cameras 0.15.5__tar.gz → 0.15.6__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.
- {python_aidot_cameras-0.15.5/python_aidot_cameras.egg-info → python_aidot_cameras-0.15.6}/PKG-INFO +1 -1
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/sdes_open.py +37 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/pyproject.toml +1 -1
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6/python_aidot_cameras.egg-info}/PKG-INFO +1 -1
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/python_aidot_cameras.egg-info/SOURCES.txt +1 -0
- python_aidot_cameras-0.15.6/tests/test_media_socket_rcvbuf.py +69 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/LICENSE +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/MANIFEST.in +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/README.md +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/__init__.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/__main__.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_upstream.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/__init__.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/__init__.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/clock.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/codecs/__init__.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/codecs/base.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/codecs/g711.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/codecs/g722.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/codecs/h264.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/codecs/opus.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/codecs/vpx.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/contrib/__init__.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/contrib/media.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/contrib/signaling.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/events.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/exceptions.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/jitterbuffer.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/mediastreams.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rate.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcconfiguration.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcdatachannel.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcdtlstransport.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcicetransport.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcpeerconnection.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcrtpparameters.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcrtpreceiver.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcrtpsender.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcrtptransceiver.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcsctptransport.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtcsessiondescription.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtp.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/sdp.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/stats.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/utils.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/ble_gateway.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/__init__.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/client.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/constants.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/controls.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/go2rtc.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/hwaccel.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/lan_control.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/models.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/playback.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/protocol.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/sdes.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/tutk.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/webrtc.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/webrtc_open.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/client.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/const.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/credentials.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/crypto.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/device_client.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/discover.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/exceptions.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/g711.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/py.typed +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/python_aidot_cameras.egg-info/dependency_links.txt +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/python_aidot_cameras.egg-info/entry_points.txt +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/python_aidot_cameras.egg-info/requires.txt +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/python_aidot_cameras.egg-info/top_level.txt +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/setup.cfg +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_aioice_compat.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_alarm_event.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_answer_sdp_video_pt.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_audio_mux_offline.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_backoff.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_battery_detection.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_battery_evidence_corroboration.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_battery_skip_turn.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_ble_gateway.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_constants_imports_resolve.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_deferred_hardening.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_device_login_guard.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_device_user_info_cache.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dormant_camera_cleanup.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_mux_terminal_write.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_not_ready_burst.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_pinning.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_serve_decode_skip.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_serve_open_timeout.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_skip_signaling_wait.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_slow_probe.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_stdout_producer.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_egress_guard.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_env_seams.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_go2rtc.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_go2rtc_cli.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_h264_decode_rate_limit.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_highport_nomination.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_hwaccel_probe.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_ice_config_cache.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_ice_peer_reflexive.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_idle_release_both_loops.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_keepalive_renew.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_key_restart_sdp.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_keyframe_prompter.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_lan_control.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_light_active_color_mode.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_live_stream_param.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_live_validate_policy.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_logging_caps.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_media_wait_floor.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_motion_poll.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_mqtt_credential_refetch.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_mqtt_credential_self_heal.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_mqtt_password_not_persisted.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_mqtt_session_reconnect.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_narrow_pc_ice.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_no_self_referential_go2rtc.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_no_undefined_names.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_offline_keepalive_pause.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_open_fail_logger.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_open_gate_delay.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_peerid_reuse.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_persistent_mqtt.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_persistent_mqtt_robustness.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_playback_tls.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_post_merge_hardening.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_resolution_persists.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_restart_cycle.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_retry_policy.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_scripts_importable.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_adaptive.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_bridge_break_gate.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_echo_wait_timeout.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_fast_liveplay.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_ffmpeg_stderr_log.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_idle_release.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_open_cleanup.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_serve_audio.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_serve_cmd.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_serve_stderr_drain.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_sprop.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_talk.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_teardown_exit_log.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_terminal_ack.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_terminal_ack_latency.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_watchdog.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdp_narrowing_properties.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdp_payload_type_narrowing.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_security_hardening.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_serializable_login_info.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_serve_relay.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_session_stats.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_shared_house_seam.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_speak.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sprop_staleness.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_stream_cap.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_stream_drain_ownership.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_stream_idle.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_stream_slot_cap.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_stream_teardown.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_talk.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_terminal_ack.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_token_file_robustness.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_token_refresh.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_turn_create_permission.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_upstream_compat.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_viewer_check_throttle.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_viewer_presence.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_viewer_present_push_mode.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_wait_or_event.py +0 -0
- {python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_wake_readiness_retry.py +0 -0
{python_aidot_cameras-0.15.5/python_aidot_cameras.egg-info → python_aidot_cameras-0.15.6}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-aidot-cameras
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.6
|
|
4
4
|
Summary: Control AiDot/Leedarson WiFi lights and cameras (WebRTC streaming, two-way audio, PTZ, controls)
|
|
5
5
|
Author-email: cbrightly <chris.brightly@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/sdes_open.py
RENAMED
|
@@ -39,6 +39,41 @@ from .protocol import (
|
|
|
39
39
|
_LOGGER = logging.getLogger(__name__)
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
#: What we ask the kernel for on a media receive socket. The kernel clamps to
|
|
43
|
+
#: ``net.core.rmem_max`` (4 MB on Home Assistant OS), and doubles what it grants
|
|
44
|
+
#: for bookkeeping, so asking for more than the cap is harmless.
|
|
45
|
+
_MEDIA_RCVBUF_BYTES = 4 * 1024 * 1024
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _widen_media_rcvbuf(sock, kind: str, device_id: str = "?") -> int:
|
|
49
|
+
"""Ask for a large receive buffer on a camera media socket.
|
|
50
|
+
|
|
51
|
+
These sockets ran on the OS default, which is 208 KB on Home Assistant OS.
|
|
52
|
+
A keyframe from an A001064 is 146-190 KB and arrives as one burst of ~130
|
|
53
|
+
packets, so a single keyframe nearly fills that buffer: any delay in the
|
|
54
|
+
reader - the GIL while another camera's bridge runs, an ffmpeg write
|
|
55
|
+
blocking - and the kernel drops the tail of the burst. ffmpeg then reports
|
|
56
|
+
``RTP: missed N packets`` and backs up its input queue.
|
|
57
|
+
|
|
58
|
+
Returns the buffer the kernel actually granted (it reports double what it
|
|
59
|
+
reserves), or 0 if the option could not be set. Best-effort by design: a
|
|
60
|
+
platform that refuses the option must not stop a camera from streaming.
|
|
61
|
+
"""
|
|
62
|
+
try:
|
|
63
|
+
import socket as _sock_rb
|
|
64
|
+
|
|
65
|
+
sock.setsockopt(_sock_rb.SOL_SOCKET, _sock_rb.SO_RCVBUF,
|
|
66
|
+
_MEDIA_RCVBUF_BYTES)
|
|
67
|
+
got = sock.getsockopt(_sock_rb.SOL_SOCKET, _sock_rb.SO_RCVBUF)
|
|
68
|
+
except Exception:
|
|
69
|
+
_LOGGER.debug("camera %s: could not widen the %s receive buffer",
|
|
70
|
+
device_id, kind, exc_info=True)
|
|
71
|
+
return 0
|
|
72
|
+
_LOGGER.debug("camera %s: %s receive buffer %d bytes (asked %d)",
|
|
73
|
+
device_id, kind, got, _MEDIA_RCVBUF_BYTES)
|
|
74
|
+
return got
|
|
75
|
+
|
|
76
|
+
|
|
42
77
|
def _start_serve_stderr_drain(proc, *, maxlines: int = 40) -> None:
|
|
43
78
|
"""Drain a serve ffmpeg's stderr continuously into a bounded tail on the proc.
|
|
44
79
|
|
|
@@ -529,11 +564,13 @@ class _SdesOpenMixin:
|
|
|
529
564
|
import socket as _socket
|
|
530
565
|
|
|
531
566
|
_audio_sock = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM)
|
|
567
|
+
_widen_media_rcvbuf(_audio_sock, "audio", getattr(self, "device_id", "?"))
|
|
532
568
|
_audio_sock.bind(("0.0.0.0", 0))
|
|
533
569
|
audio_port = _audio_sock.getsockname()[1]
|
|
534
570
|
_cl(_audio_sock.close) # also unblocks the bridge thread's recv on cleanup
|
|
535
571
|
|
|
536
572
|
_video_sock = _socket.socket(_socket.AF_INET, _socket.SOCK_DGRAM)
|
|
573
|
+
_widen_media_rcvbuf(_video_sock, "video", getattr(self, "device_id", "?"))
|
|
537
574
|
_video_sock.bind(("0.0.0.0", 0))
|
|
538
575
|
video_port = _video_sock.getsockname()[1]
|
|
539
576
|
_cl(_video_sock.close)
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-aidot-cameras"
|
|
7
|
-
version = "0.15.
|
|
7
|
+
version = "0.15.6"
|
|
8
8
|
description = "Control AiDot/Leedarson WiFi lights and cameras (WebRTC streaming, two-way audio, PTZ, controls)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6/python_aidot_cameras.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-aidot-cameras
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.6
|
|
4
4
|
Summary: Control AiDot/Leedarson WiFi lights and cameras (WebRTC streaming, two-way audio, PTZ, controls)
|
|
5
5
|
Author-email: cbrightly <chris.brightly@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -109,6 +109,7 @@ tests/test_light_active_color_mode.py
|
|
|
109
109
|
tests/test_live_stream_param.py
|
|
110
110
|
tests/test_live_validate_policy.py
|
|
111
111
|
tests/test_logging_caps.py
|
|
112
|
+
tests/test_media_socket_rcvbuf.py
|
|
112
113
|
tests/test_media_wait_floor.py
|
|
113
114
|
tests/test_motion_poll.py
|
|
114
115
|
tests/test_mqtt_credential_refetch.py
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Camera media sockets must ask for a receive buffer big enough for a keyframe.
|
|
2
|
+
|
|
3
|
+
These sockets ran on the OS default - 208 KB on Home Assistant OS. An A001064
|
|
4
|
+
keyframe is 146-190 KB delivered as one burst of ~130 packets, so a single
|
|
5
|
+
keyframe nearly fills that buffer. Any delay in the reader (the GIL while
|
|
6
|
+
another camera's bridge runs, an ffmpeg write blocking) and the kernel drops the
|
|
7
|
+
tail of the burst, which ffmpeg reports as ``RTP: missed N packets`` while its
|
|
8
|
+
input queue backs up. The box carried 44.3 million ``RcvbufErrors`` against
|
|
9
|
+
161 million datagrams received over four days, and every UDP receive error on it
|
|
10
|
+
was a buffer overflow rather than a checksum or port error.
|
|
11
|
+
"""
|
|
12
|
+
import socket
|
|
13
|
+
|
|
14
|
+
from aidot_cameras.camera.sdes_open import (
|
|
15
|
+
_MEDIA_RCVBUF_BYTES,
|
|
16
|
+
_widen_media_rcvbuf,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_the_request_clears_a_keyframe_burst():
|
|
21
|
+
# 190 KB is the largest keyframe measured on the A001064; the request has to
|
|
22
|
+
# leave room for that plus scheduling jitter, not merely match it.
|
|
23
|
+
assert _MEDIA_RCVBUF_BYTES >= 8 * 190 * 1024
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_a_real_socket_gets_more_than_the_os_default():
|
|
27
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
28
|
+
try:
|
|
29
|
+
default = sock.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF)
|
|
30
|
+
got = _widen_media_rcvbuf(sock, "video", "dev-abc")
|
|
31
|
+
assert got > 0, "the option was not set at all"
|
|
32
|
+
# Kernels clamp to rmem_max and report double what they reserve, so the
|
|
33
|
+
# exact number is not assertable - only that it grew, and that it now
|
|
34
|
+
# clears one keyframe.
|
|
35
|
+
assert got >= default
|
|
36
|
+
assert got >= 190 * 1024, f"granted {got} bytes, under one keyframe"
|
|
37
|
+
finally:
|
|
38
|
+
sock.close()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_failure_is_survivable():
|
|
42
|
+
"""A platform that refuses the option must not stop a camera streaming."""
|
|
43
|
+
|
|
44
|
+
class _Refuses:
|
|
45
|
+
def setsockopt(self, *_a):
|
|
46
|
+
raise OSError("nope")
|
|
47
|
+
|
|
48
|
+
def getsockopt(self, *_a):
|
|
49
|
+
raise OSError("nope")
|
|
50
|
+
|
|
51
|
+
assert _widen_media_rcvbuf(_Refuses(), "audio", "dev-abc") == 0
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_both_media_sockets_are_widened_before_bind():
|
|
55
|
+
"""Pin the call sites: a socket widened after bind may already have dropped.
|
|
56
|
+
|
|
57
|
+
The open path is one long method that cannot be called in isolation, so
|
|
58
|
+
assert on its source - both the audio and video sockets must be widened, and
|
|
59
|
+
each before its own bind.
|
|
60
|
+
"""
|
|
61
|
+
import inspect
|
|
62
|
+
|
|
63
|
+
from aidot_cameras.camera import sdes_open
|
|
64
|
+
|
|
65
|
+
src = inspect.getsource(sdes_open)
|
|
66
|
+
for kind in ("_audio_sock", "_video_sock"):
|
|
67
|
+
widen = src.index(f"_widen_media_rcvbuf({kind}")
|
|
68
|
+
bind = src.index(f"{kind}.bind(")
|
|
69
|
+
assert widen < bind, f"{kind} is bound before its receive buffer is set"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/__init__.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/__init__.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/clock.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/events.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/rtp.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/sdp.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/stats.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/_vendor/aiortc/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/constants.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/controls.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/lan_control.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/playback.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/aidot_cameras/camera/webrtc_open.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_answer_sdp_video_pt.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_constants_imports_resolve.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_deferred_hardening.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_device_login_guard.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_device_user_info_cache.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dormant_camera_cleanup.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_mux_terminal_write.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_not_ready_burst.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_serve_decode_skip.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_serve_open_timeout.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_skip_signaling_wait.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_dtls_stdout_producer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_h264_decode_rate_limit.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_highport_nomination.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_ice_peer_reflexive.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_idle_release_both_loops.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_light_active_color_mode.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_live_validate_policy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_mqtt_credential_refetch.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_mqtt_credential_self_heal.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_mqtt_session_reconnect.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_no_self_referential_go2rtc.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_no_undefined_names.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_offline_keepalive_pause.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_persistent_mqtt_robustness.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_post_merge_hardening.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_resolution_persists.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_scripts_importable.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_bridge_break_gate.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_echo_wait_timeout.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_fast_liveplay.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_ffmpeg_stderr_log.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_serve_stderr_drain.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_teardown_exit_log.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdes_terminal_ack_latency.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdp_narrowing_properties.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_sdp_payload_type_narrowing.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_security_hardening.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_serializable_login_info.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_stream_drain_ownership.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_token_file_robustness.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_turn_create_permission.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_viewer_check_throttle.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_viewer_present_push_mode.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.5 → python_aidot_cameras-0.15.6}/tests/test_wake_readiness_retry.py
RENAMED
|
File without changes
|