python-aidot-cameras 0.15.0b5__tar.gz → 0.15.2__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.0b5/python_aidot_cameras.egg-info → python_aidot_cameras-0.15.2}/PKG-INFO +3 -1
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/README.md +2 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/client.py +5 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/controls.py +32 -2
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/hwaccel.py +14 -4
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/pyproject.toml +1 -1
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2/python_aidot_cameras.egg-info}/PKG-INFO +3 -1
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/python_aidot_cameras.egg-info/SOURCES.txt +1 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_hwaccel_probe.py +24 -5
- python_aidot_cameras-0.15.2/tests/test_resolution_persists.py +95 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/LICENSE +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/MANIFEST.in +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/__init__.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/__main__.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_upstream.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/__init__.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/__init__.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/clock.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/codecs/__init__.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/codecs/base.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/codecs/g711.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/codecs/g722.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/codecs/h264.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/codecs/opus.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/codecs/vpx.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/contrib/__init__.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/contrib/media.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/contrib/signaling.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/events.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/exceptions.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/jitterbuffer.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/mediastreams.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rate.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcconfiguration.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcdatachannel.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcdtlstransport.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcicetransport.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcpeerconnection.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcrtpparameters.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcrtpreceiver.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcrtpsender.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcrtptransceiver.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcsctptransport.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtcsessiondescription.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtp.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/sdp.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/stats.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/utils.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/ble_gateway.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/__init__.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/constants.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/go2rtc.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/lan_control.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/models.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/playback.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/protocol.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/sdes.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/sdes_open.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/tutk.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/webrtc.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/webrtc_open.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/client.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/const.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/credentials.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/crypto.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/device_client.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/discover.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/exceptions.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/g711.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/py.typed +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/python_aidot_cameras.egg-info/dependency_links.txt +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/python_aidot_cameras.egg-info/entry_points.txt +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/python_aidot_cameras.egg-info/requires.txt +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/python_aidot_cameras.egg-info/top_level.txt +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/setup.cfg +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_aioice_compat.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_alarm_event.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_answer_sdp_video_pt.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_audio_mux_offline.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_backoff.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_battery_detection.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_battery_evidence_corroboration.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_battery_skip_turn.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_ble_gateway.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_constants_imports_resolve.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_deferred_hardening.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_device_login_guard.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_device_user_info_cache.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dormant_camera_cleanup.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_mux_terminal_write.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_not_ready_burst.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_pinning.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_serve_decode_skip.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_serve_open_timeout.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_skip_signaling_wait.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_slow_probe.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_egress_guard.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_env_seams.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_go2rtc.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_go2rtc_cli.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_h264_decode_rate_limit.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_highport_nomination.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_ice_config_cache.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_ice_peer_reflexive.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_idle_release_both_loops.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_keepalive_renew.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_key_restart_sdp.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_keyframe_prompter.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_lan_control.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_light_active_color_mode.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_live_stream_param.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_live_validate_policy.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_logging_caps.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_media_wait_floor.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_motion_poll.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_mqtt_credential_refetch.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_mqtt_credential_self_heal.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_mqtt_password_not_persisted.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_mqtt_session_reconnect.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_narrow_pc_ice.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_no_self_referential_go2rtc.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_no_undefined_names.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_offline_keepalive_pause.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_open_fail_logger.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_open_gate_delay.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_peerid_reuse.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_persistent_mqtt.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_persistent_mqtt_robustness.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_playback_tls.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_post_merge_hardening.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_restart_cycle.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_retry_policy.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_scripts_importable.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_adaptive.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_bridge_break_gate.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_echo_wait_timeout.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_fast_liveplay.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_ffmpeg_stderr_log.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_idle_release.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_open_cleanup.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_serve_audio.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_serve_cmd.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_sprop.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_talk.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_teardown_exit_log.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_terminal_ack.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_terminal_ack_latency.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_watchdog.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdp_narrowing_properties.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdp_payload_type_narrowing.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_security_hardening.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_serializable_login_info.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_serve_relay.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_session_stats.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_shared_house_seam.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_speak.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sprop_staleness.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_stream_cap.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_stream_drain_ownership.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_stream_idle.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_stream_slot_cap.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_stream_teardown.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_talk.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_terminal_ack.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_token_file_robustness.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_token_refresh.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_turn_create_permission.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_upstream_compat.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_viewer_check_throttle.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_viewer_presence.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_viewer_present_push_mode.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_wait_or_event.py +0 -0
- {python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_wake_readiness_retry.py +0 -0
{python_aidot_cameras-0.15.0b5/python_aidot_cameras.egg-info → python_aidot_cameras-0.15.2}/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.2
|
|
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
|
|
@@ -167,6 +167,8 @@ audio, idle release, the sprop cache path) are documented in
|
|
|
167
167
|
|
|
168
168
|
| Variable | Purpose | Default |
|
|
169
169
|
| --- | --- | --- |
|
|
170
|
+
| `AIDOT_VIDEO_DECODER` | Force a video decoder instead of measuring one: a decoder name (`h264_v4l2m2m`), or an acceleration method prefixed with `hwaccel:` (`hwaccel:videotoolbox`). The prefix is required because the two are not interchangeable - VideoToolbox and VAAPI have no decoder to name. | (measured) |
|
|
171
|
+
| `AIDOT_DISABLE_HWACCEL` | Keep to software decoding and skip the measurement entirely. | (unset) |
|
|
170
172
|
| `AIDOT_MAX_CONCURRENT_OPENS` | Caps how many stream opens run concurrently across all cameras. | `2` |
|
|
171
173
|
| `AIDOT_MAX_CONCURRENT_STREAMS` | Caps how many cameras stream at once. | `3` |
|
|
172
174
|
| `AIDOT_FAST_CONNECT` | Enable LAN-direct "fast connect" (STUN-only, skips several cloud signaling waits) when truthy. On-LAN only - off-subnet/strict-NAT viewers must leave it off. | unset (off) |
|
|
@@ -136,6 +136,8 @@ audio, idle release, the sprop cache path) are documented in
|
|
|
136
136
|
|
|
137
137
|
| Variable | Purpose | Default |
|
|
138
138
|
| --- | --- | --- |
|
|
139
|
+
| `AIDOT_VIDEO_DECODER` | Force a video decoder instead of measuring one: a decoder name (`h264_v4l2m2m`), or an acceleration method prefixed with `hwaccel:` (`hwaccel:videotoolbox`). The prefix is required because the two are not interchangeable - VideoToolbox and VAAPI have no decoder to name. | (measured) |
|
|
140
|
+
| `AIDOT_DISABLE_HWACCEL` | Keep to software decoding and skip the measurement entirely. | (unset) |
|
|
139
141
|
| `AIDOT_MAX_CONCURRENT_OPENS` | Caps how many stream opens run concurrently across all cameras. | `2` |
|
|
140
142
|
| `AIDOT_MAX_CONCURRENT_STREAMS` | Caps how many cameras stream at once. | `3` |
|
|
141
143
|
| `AIDOT_FAST_CONNECT` | Enable LAN-direct "fast connect" (STUN-only, skips several cloud signaling waits) when truthy. On-LAN only - off-subnet/strict-NAT viewers must leave it off. | unset (off) |
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/client.py
RENAMED
|
@@ -867,6 +867,8 @@ class CameraMixin(_CameraControlsMixin, _WebRTCOpenMixin, _SdesOpenMixin):
|
|
|
867
867
|
self.latest_jpeg: Optional[bytes] = None
|
|
868
868
|
self._streaming_active: bool = False
|
|
869
869
|
self._stream_session: Optional[Any] = None
|
|
870
|
+
# Last resolution asked for, re-sent when a session starts.
|
|
871
|
+
self._desired_quality: Optional[str] = None
|
|
870
872
|
self._stream_task: Optional["asyncio.Task[None]"] = None
|
|
871
873
|
self._stream_mqtt_drain: Optional["asyncio.Future"] = None
|
|
872
874
|
self._last_frame_time: float = 0.0
|
|
@@ -3354,6 +3356,8 @@ class CameraMixin(_CameraControlsMixin, _WebRTCOpenMixin, _SdesOpenMixin):
|
|
|
3354
3356
|
|
|
3355
3357
|
self._fast_attempt_override = None
|
|
3356
3358
|
self._stream_session = session
|
|
3359
|
+
# A remembered resolution is only deliverable once a session exists.
|
|
3360
|
+
self._apply_pending_resolution()
|
|
3357
3361
|
# Don't block solely on wait_done(): the SDES ffmpeg reads RTP over a
|
|
3358
3362
|
# UDP socket with no input timeout, so when a battery camera tears the
|
|
3359
3363
|
# session down (~49-72s) ffmpeg keeps waiting on dead sockets forever
|
|
@@ -3564,6 +3568,7 @@ class CameraMixin(_CameraControlsMixin, _WebRTCOpenMixin, _SdesOpenMixin):
|
|
|
3564
3568
|
continue
|
|
3565
3569
|
|
|
3566
3570
|
self._stream_session = session
|
|
3571
|
+
self._apply_pending_resolution()
|
|
3567
3572
|
try:
|
|
3568
3573
|
while self._streaming_active:
|
|
3569
3574
|
await asyncio.sleep(5.0)
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/controls.py
RENAMED
|
@@ -144,6 +144,13 @@ class _CameraControlsMixin:
|
|
|
144
144
|
mirroring the official app's HD/SD toggle. Rides the active stream
|
|
145
145
|
session (SETSTREAMCTRL=800), so the camera must be streaming.
|
|
146
146
|
|
|
147
|
+
The choice is REMEMBERED and re-sent whenever a session next starts.
|
|
148
|
+
Without that it was simply dropped when nothing was streaming - and
|
|
149
|
+
since a camera is idle far more often than not, the usual outcome of
|
|
150
|
+
changing this was nothing at all, while the caller was told the setting
|
|
151
|
+
had been applied. Nothing else re-sent it, so "it will apply on the next
|
|
152
|
+
session" was not true of any code path.
|
|
153
|
+
|
|
147
154
|
Source: f0.java g3() -> X2(800, SetStreamCtrlReq.parseContent(0, quality)).
|
|
148
155
|
Payload <IB3x> = channel(0) + quality byte + 3 reserved.
|
|
149
156
|
"""
|
|
@@ -151,14 +158,37 @@ class _CameraControlsMixin:
|
|
|
151
158
|
if q is None:
|
|
152
159
|
_LOGGER.error("async_set_resolution: unknown quality %r", quality)
|
|
153
160
|
return False
|
|
161
|
+
self._desired_quality = quality.lower()
|
|
154
162
|
payload = struct.pack("<IB3x", 0, q)
|
|
155
163
|
session = self._stream_session
|
|
156
164
|
if session is None:
|
|
157
|
-
_LOGGER.
|
|
158
|
-
|
|
165
|
+
_LOGGER.info(
|
|
166
|
+
"resolution %s remembered; the camera is not streaming, so it "
|
|
167
|
+
"will be applied when a session next starts", quality)
|
|
168
|
+
return True
|
|
159
169
|
ok = session._avio_cmd(SETSTREAMCTRL_CMD, payload)
|
|
160
170
|
_LOGGER.debug(
|
|
161
171
|
"set resolution %s (quality=%d) -> %s",
|
|
162
172
|
quality, q, "sent" if ok else "no channel yet",
|
|
163
173
|
)
|
|
164
174
|
return ok
|
|
175
|
+
|
|
176
|
+
def _apply_pending_resolution(self) -> None:
|
|
177
|
+
"""Re-send the remembered resolution now that a session exists.
|
|
178
|
+
|
|
179
|
+
Called when a stream session becomes active. Best-effort and silent on
|
|
180
|
+
failure: a stream that is up matters more than a quality preference, so
|
|
181
|
+
this must never be able to disturb it.
|
|
182
|
+
"""
|
|
183
|
+
quality = getattr(self, "_desired_quality", None)
|
|
184
|
+
if not quality:
|
|
185
|
+
return
|
|
186
|
+
q = _STREAM_QUALITY.get(quality)
|
|
187
|
+
session = self._stream_session
|
|
188
|
+
if q is None or session is None:
|
|
189
|
+
return
|
|
190
|
+
try:
|
|
191
|
+
if session._avio_cmd(SETSTREAMCTRL_CMD, struct.pack("<IB3x", 0, q)):
|
|
192
|
+
_LOGGER.debug("re-applied remembered resolution %s", quality)
|
|
193
|
+
except Exception:
|
|
194
|
+
_LOGGER.debug("could not re-apply resolution %s", quality, exc_info=True)
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/hwaccel.py
RENAMED
|
@@ -393,6 +393,14 @@ def warm_decoder_cache(codecs: tuple = ("h264",)) -> "threading.Thread":
|
|
|
393
393
|
return _warm_thread
|
|
394
394
|
|
|
395
395
|
def _run() -> None:
|
|
396
|
+
# Prime the in-memory cache from disk HERE, on this thread, so
|
|
397
|
+
# cached_decoder() never has to read a file on the event loop.
|
|
398
|
+
try:
|
|
399
|
+
for k, v in _load_cache().items():
|
|
400
|
+
if isinstance(v, list):
|
|
401
|
+
_cache_mem.setdefault(k, list(v))
|
|
402
|
+
except Exception:
|
|
403
|
+
_LOGGER.debug("decoder cache preload failed", exc_info=True)
|
|
396
404
|
for codec in codecs:
|
|
397
405
|
try:
|
|
398
406
|
probe_decoder(codec)
|
|
@@ -432,13 +440,15 @@ def cached_decoder(codec: str) -> Optional[List[str]]:
|
|
|
432
440
|
if os.environ.get(_ENV_DISABLE, "").strip().lower() in ("1", "true", "yes", "on"):
|
|
433
441
|
return []
|
|
434
442
|
|
|
443
|
+
# MEMORY ONLY. This runs on the event loop, so it must not touch the disk:
|
|
444
|
+
# Home Assistant detects a blocking open() here and reports it as a
|
|
445
|
+
# stability problem, correctly. The disk cache is read by
|
|
446
|
+
# warm_decoder_cache() on its own thread, which populates _cache_mem; a miss
|
|
447
|
+
# here simply means "not known yet", and the caller lets ffmpeg choose,
|
|
448
|
+
# which is the behaviour that existed before any of this.
|
|
435
449
|
key = f"v{_CACHE_SCHEMA}:{codec}:{_ffmpeg_identity()}"
|
|
436
450
|
if key in _cache_mem:
|
|
437
451
|
return list(_cache_mem[key])
|
|
438
|
-
val = _load_cache().get(key)
|
|
439
|
-
if isinstance(val, list):
|
|
440
|
-
_cache_mem[key] = list(val)
|
|
441
|
-
return list(val)
|
|
442
452
|
return None
|
|
443
453
|
|
|
444
454
|
|
|
@@ -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.2"
|
|
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.0b5 → python_aidot_cameras-0.15.2/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.2
|
|
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
|
|
@@ -167,6 +167,8 @@ audio, idle release, the sprop cache path) are documented in
|
|
|
167
167
|
|
|
168
168
|
| Variable | Purpose | Default |
|
|
169
169
|
| --- | --- | --- |
|
|
170
|
+
| `AIDOT_VIDEO_DECODER` | Force a video decoder instead of measuring one: a decoder name (`h264_v4l2m2m`), or an acceleration method prefixed with `hwaccel:` (`hwaccel:videotoolbox`). The prefix is required because the two are not interchangeable - VideoToolbox and VAAPI have no decoder to name. | (measured) |
|
|
171
|
+
| `AIDOT_DISABLE_HWACCEL` | Keep to software decoding and skip the measurement entirely. | (unset) |
|
|
170
172
|
| `AIDOT_MAX_CONCURRENT_OPENS` | Caps how many stream opens run concurrently across all cameras. | `2` |
|
|
171
173
|
| `AIDOT_MAX_CONCURRENT_STREAMS` | Caps how many cameras stream at once. | `3` |
|
|
172
174
|
| `AIDOT_FAST_CONNECT` | Enable LAN-direct "fast connect" (STUN-only, skips several cloud signaling waits) when truthy. On-LAN only - off-subnet/strict-NAT viewers must leave it off. | unset (off) |
|
|
@@ -125,6 +125,7 @@ tests/test_persistent_mqtt.py
|
|
|
125
125
|
tests/test_persistent_mqtt_robustness.py
|
|
126
126
|
tests/test_playback_tls.py
|
|
127
127
|
tests/test_post_merge_hardening.py
|
|
128
|
+
tests/test_resolution_persists.py
|
|
128
129
|
tests/test_restart_cycle.py
|
|
129
130
|
tests/test_retry_policy.py
|
|
130
131
|
tests/test_scripts_importable.py
|
|
@@ -158,6 +158,18 @@ def test_no_sample_falls_back_to_software(monkeypatch):
|
|
|
158
158
|
assert hwaccel.probe_decoder("h264", force=True) == []
|
|
159
159
|
|
|
160
160
|
|
|
161
|
+
def test_warm_cache_primes_memory_from_disk(monkeypatch):
|
|
162
|
+
"""Since cached_decoder() is memory-only, something has to load the disk
|
|
163
|
+
cache - and it must be the background thread, not the event loop."""
|
|
164
|
+
monkeypatch.setattr(hwaccel, "_ffmpeg_identity", lambda: "b")
|
|
165
|
+
key = f"v{hwaccel._CACHE_SCHEMA}:h264:b"
|
|
166
|
+
hwaccel._save_cache({key: ["-c:v", "h264_v4l2m2m"]})
|
|
167
|
+
assert hwaccel.cached_decoder("h264") is None # not yet in memory
|
|
168
|
+
monkeypatch.setattr(hwaccel, "probe_decoder", lambda c: [])
|
|
169
|
+
hwaccel.warm_decoder_cache(("h264",)).join(timeout=30)
|
|
170
|
+
assert hwaccel.cached_decoder("h264") == ["-c:v", "h264_v4l2m2m"]
|
|
171
|
+
|
|
172
|
+
|
|
161
173
|
def test_software_verdict_is_not_confused_with_unprobed(monkeypatch):
|
|
162
174
|
"""[] means "software, proven"; None means "not probed yet". Collapsing the
|
|
163
175
|
two would re-probe forever on any host with no hardware decoding."""
|
|
@@ -168,7 +180,7 @@ def test_software_verdict_is_not_confused_with_unprobed(monkeypatch):
|
|
|
168
180
|
lambda cand, sample: 1.0 if not cand else None)
|
|
169
181
|
assert hwaccel.cached_decoder("h264") is None # nothing probed yet
|
|
170
182
|
assert hwaccel.probe_decoder("h264") == [] # proven software
|
|
171
|
-
assert hwaccel.cached_decoder("h264") == [] #
|
|
183
|
+
assert hwaccel.cached_decoder("h264") == [] # memoised, not None
|
|
172
184
|
|
|
173
185
|
|
|
174
186
|
def test_a_stale_schema_entry_is_ignored(monkeypatch):
|
|
@@ -176,6 +188,8 @@ def test_a_stale_schema_entry_is_ignored(monkeypatch):
|
|
|
176
188
|
Reading that back as a verdict would put a string into the ffmpeg argv."""
|
|
177
189
|
monkeypatch.setattr(hwaccel, "_ffmpeg_identity", lambda: "b")
|
|
178
190
|
hwaccel._save_cache({"h264:b": "h264_v4l2m2m"}) # v1-shaped entry
|
|
191
|
+
monkeypatch.setattr(hwaccel, "probe_decoder", lambda c: [])
|
|
192
|
+
hwaccel.warm_decoder_cache(("h264",)).join(timeout=30)
|
|
179
193
|
assert hwaccel.cached_decoder("h264") is None
|
|
180
194
|
|
|
181
195
|
|
|
@@ -231,13 +245,18 @@ def test_no_verdict_leaves_ffmpeg_to_choose():
|
|
|
231
245
|
sdp_path="/tmp/x.sdp", video_decoder=None)
|
|
232
246
|
|
|
233
247
|
|
|
234
|
-
def
|
|
235
|
-
"""It runs on the event loop, so it must not shell out
|
|
248
|
+
def test_cached_decoder_touches_neither_disk_nor_subprocess(monkeypatch):
|
|
249
|
+
"""It runs on the event loop, so it must not shell out AND must not read a
|
|
250
|
+
file. Home Assistant detects a blocking open() on the loop and reports it as
|
|
251
|
+
a stability problem - it did, on a shipped release. The disk cache is read
|
|
252
|
+
by warm_decoder_cache() on its own thread instead."""
|
|
253
|
+
monkeypatch.setattr(hwaccel, "_load_cache",
|
|
254
|
+
lambda: pytest.fail("must not read the cache file"))
|
|
236
255
|
monkeypatch.setattr(hwaccel, "_try_decoder",
|
|
237
256
|
lambda cand, sample: pytest.fail("must not probe"))
|
|
238
257
|
monkeypatch.setattr(hwaccel, "_make_sample",
|
|
239
258
|
lambda codec, path: pytest.fail("must not probe"))
|
|
240
|
-
assert hwaccel.cached_decoder("h264") is None #
|
|
259
|
+
assert hwaccel.cached_decoder("h264") is None # nothing memoised, no I/O
|
|
241
260
|
|
|
242
261
|
|
|
243
262
|
# --------------------------------------------------------------------------- #
|
|
@@ -266,7 +285,7 @@ def test_software_is_not_timed_when_no_hardware_qualifies(monkeypatch):
|
|
|
266
285
|
|
|
267
286
|
def _try(cand, sample):
|
|
268
287
|
tried.append(tuple(cand))
|
|
269
|
-
return
|
|
288
|
+
return # nothing decodes here
|
|
270
289
|
|
|
271
290
|
monkeypatch.setattr(hwaccel, "_try_decoder", _try)
|
|
272
291
|
assert hwaccel.probe_decoder("h264") == []
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""A resolution choice must survive being made while nothing is streaming.
|
|
2
|
+
|
|
3
|
+
The setter rides the live session (SETSTREAMCTRL): with no session there is
|
|
4
|
+
nothing to send it over. It used to return False and drop the choice entirely,
|
|
5
|
+
and nothing re-sent it - so the usual outcome of changing resolution was
|
|
6
|
+
nothing at all, because a camera is idle far more often than it is streaming.
|
|
7
|
+
The caller was told the setting had been applied, and the comment in the
|
|
8
|
+
integration's select claimed it would "take effect on the next session", which
|
|
9
|
+
no code path did.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
from unittest.mock import MagicMock
|
|
15
|
+
|
|
16
|
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
17
|
+
|
|
18
|
+
import pytest
|
|
19
|
+
|
|
20
|
+
from aidot_cameras.camera.constants import _STREAM_QUALITY, SETSTREAMCTRL_CMD
|
|
21
|
+
from aidot_cameras.camera.controls import _CameraControlsMixin
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class _Cam(_CameraControlsMixin):
|
|
25
|
+
def __init__(self, session=None):
|
|
26
|
+
self._stream_session = session
|
|
27
|
+
self._desired_quality = None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _session():
|
|
31
|
+
s = MagicMock()
|
|
32
|
+
s._avio_cmd = MagicMock(return_value=True)
|
|
33
|
+
return s
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.mark.asyncio
|
|
37
|
+
async def test_choice_made_while_idle_is_remembered_not_dropped():
|
|
38
|
+
cam = _Cam(session=None)
|
|
39
|
+
|
|
40
|
+
assert await cam.async_set_resolution("sd") is True
|
|
41
|
+
assert cam._desired_quality == "sd"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@pytest.mark.asyncio
|
|
45
|
+
async def test_remembered_choice_is_sent_when_a_session_starts():
|
|
46
|
+
cam = _Cam(session=None)
|
|
47
|
+
await cam.async_set_resolution("sd")
|
|
48
|
+
|
|
49
|
+
cam._stream_session = _session()
|
|
50
|
+
cam._apply_pending_resolution()
|
|
51
|
+
|
|
52
|
+
cam._stream_session._avio_cmd.assert_called_once()
|
|
53
|
+
cmd, payload = cam._stream_session._avio_cmd.call_args[0]
|
|
54
|
+
assert cmd == SETSTREAMCTRL_CMD
|
|
55
|
+
assert payload[4] == _STREAM_QUALITY["sd"] # AVIOCTRL_QUALITY_MIDDLE
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.mark.asyncio
|
|
59
|
+
async def test_hd_round_trips_too():
|
|
60
|
+
cam = _Cam(session=None)
|
|
61
|
+
await cam.async_set_resolution("hd")
|
|
62
|
+
cam._stream_session = _session()
|
|
63
|
+
cam._apply_pending_resolution()
|
|
64
|
+
assert cam._stream_session._avio_cmd.call_args[0][1][4] == _STREAM_QUALITY["hd"]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@pytest.mark.asyncio
|
|
68
|
+
async def test_a_live_session_still_gets_it_immediately():
|
|
69
|
+
"""Unchanged behaviour when the camera is already streaming."""
|
|
70
|
+
cam = _Cam(session=_session())
|
|
71
|
+
|
|
72
|
+
assert await cam.async_set_resolution("sd") is True
|
|
73
|
+
cam._stream_session._avio_cmd.assert_called_once()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_nothing_is_sent_when_no_choice_was_ever_made():
|
|
77
|
+
cam = _Cam(session=_session())
|
|
78
|
+
cam._apply_pending_resolution()
|
|
79
|
+
cam._stream_session._avio_cmd.assert_not_called()
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@pytest.mark.asyncio
|
|
83
|
+
async def test_an_unknown_quality_is_still_rejected():
|
|
84
|
+
cam = _Cam(session=_session())
|
|
85
|
+
assert await cam.async_set_resolution("ultra") is False
|
|
86
|
+
assert cam._desired_quality is None
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def test_reapply_never_disturbs_a_working_stream():
|
|
90
|
+
"""A quality preference must never be able to break a stream that is up."""
|
|
91
|
+
cam = _Cam(session=_session())
|
|
92
|
+
cam._desired_quality = "sd"
|
|
93
|
+
cam._stream_session._avio_cmd.side_effect = RuntimeError("channel gone")
|
|
94
|
+
|
|
95
|
+
cam._apply_pending_resolution() # must not raise
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/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.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/events.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/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.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/rtp.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/sdp.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/stats.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/_vendor/aiortc/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/__init__.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/constants.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/go2rtc.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/lan_control.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/models.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/playback.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/protocol.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/sdes_open.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/webrtc.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/camera/webrtc_open.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/aidot_cameras/device_client.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.0b5 → python_aidot_cameras-0.15.2}/tests/test_answer_sdp_video_pt.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_audio_mux_offline.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_battery_detection.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_battery_skip_turn.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_deferred_hardening.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_device_login_guard.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_device_user_info_cache.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dormant_camera_cleanup.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_mux_terminal_write.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_not_ready_burst.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_serve_decode_skip.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_serve_open_timeout.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_dtls_skip_signaling_wait.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.0b5 → python_aidot_cameras-0.15.2}/tests/test_h264_decode_rate_limit.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_highport_nomination.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_ice_config_cache.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_ice_peer_reflexive.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_idle_release_both_loops.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_keyframe_prompter.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_light_active_color_mode.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_live_stream_param.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_live_validate_policy.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_media_wait_floor.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_mqtt_credential_refetch.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_mqtt_session_reconnect.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_no_undefined_names.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_offline_keepalive_pause.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_open_fail_logger.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.0b5 → python_aidot_cameras-0.15.2}/tests/test_post_merge_hardening.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_scripts_importable.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_bridge_break_gate.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_echo_wait_timeout.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_fast_liveplay.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_ffmpeg_stderr_log.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_idle_release.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_open_cleanup.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_serve_audio.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_teardown_exit_log.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdes_terminal_ack.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_sdp_narrowing_properties.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_security_hardening.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_serializable_login_info.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_shared_house_seam.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/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.0b5 → python_aidot_cameras-0.15.2}/tests/test_token_file_robustness.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_turn_create_permission.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_viewer_check_throttle.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_viewer_present_push_mode.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.15.0b5 → python_aidot_cameras-0.15.2}/tests/test_wake_readiness_retry.py
RENAMED
|
File without changes
|