python-aidot-cameras 0.7.20__tar.gz → 0.7.21__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {python_aidot_cameras-0.7.20/src/python_aidot_cameras.egg-info → python_aidot_cameras-0.7.21}/PKG-INFO +1 -1
  2. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/pyproject.toml +1 -1
  3. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/client.py +32 -6
  4. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21/src/python_aidot_cameras.egg-info}/PKG-INFO +1 -1
  5. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/LICENSE +0 -0
  6. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/MANIFEST.in +0 -0
  7. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/README.md +0 -0
  8. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/setup.cfg +0 -0
  9. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/__init__.py +0 -0
  10. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/aes_utils.py +0 -0
  11. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/__init__.py +0 -0
  12. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/constants.py +0 -0
  13. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/controls.py +0 -0
  14. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/go2rtc.py +0 -0
  15. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/lan_control.py +0 -0
  16. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/models.py +0 -0
  17. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/playback.py +0 -0
  18. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/protocol.py +0 -0
  19. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/sdes.py +0 -0
  20. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/tutk.py +0 -0
  21. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/camera/webrtc.py +0 -0
  22. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/client.py +0 -0
  23. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/const.py +0 -0
  24. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/credentials.py +0 -0
  25. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/device_client.py +0 -0
  26. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/discover.py +0 -0
  27. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/exceptions.py +0 -0
  28. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/g711.py +0 -0
  29. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/login_const.py +0 -0
  30. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/models/__init__.py +0 -0
  31. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/models/device_client_model.py +0 -0
  32. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/models/device_model.py +0 -0
  33. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/models/discover_model.py +0 -0
  34. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/aidot/py.typed +0 -0
  35. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/python_aidot_cameras.egg-info/SOURCES.txt +0 -0
  36. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/python_aidot_cameras.egg-info/dependency_links.txt +0 -0
  37. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/python_aidot_cameras.egg-info/requires.txt +0 -0
  38. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/src/python_aidot_cameras.egg-info/top_level.txt +0 -0
  39. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_alarm_event.py +0 -0
  40. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_backoff.py +0 -0
  41. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_go2rtc.py +0 -0
  42. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_highport_nomination.py +0 -0
  43. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_lan_control.py +0 -0
  44. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_live_stream_param.py +0 -0
  45. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_motion_poll.py +0 -0
  46. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_no_undefined_names.py +0 -0
  47. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_post_merge_hardening.py +0 -0
  48. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_sdes_idle_release.py +0 -0
  49. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_sdes_sprop.py +0 -0
  50. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_sdes_talk.py +0 -0
  51. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_sdes_watchdog.py +0 -0
  52. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_serve_relay.py +0 -0
  53. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_speak.py +0 -0
  54. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_stream_cap.py +0 -0
  55. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_stream_idle.py +0 -0
  56. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_talk.py +0 -0
  57. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_terminal_ack.py +0 -0
  58. {python_aidot_cameras-0.7.20 → python_aidot_cameras-0.7.21}/tests/test_token_refresh.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-aidot-cameras
3
- Version: 0.7.20
3
+ Version: 0.7.21
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-aidot-cameras"
7
- version = "0.7.20"
7
+ version = "0.7.21"
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"
@@ -1950,6 +1950,7 @@ class CameraMixin(_CameraControlsMixin):
1950
1950
  live_stream_param: Optional[bool] = None,
1951
1951
  serve_relay: Optional[bool] = None,
1952
1952
  stream_idle_s: Optional[float] = None,
1953
+ sdes_fast_liveplay: Optional[bool] = None,
1953
1954
  ) -> None:
1954
1955
  """Start a persistent stream that keeps the camera session alive.
1955
1956
 
@@ -1998,6 +1999,8 @@ class CameraMixin(_CameraControlsMixin):
1998
1999
  self._serve_relay_opt = serve_relay
1999
2000
  if stream_idle_s is not None:
2000
2001
  self._stream_idle_opt = stream_idle_s
2002
+ if sdes_fast_liveplay is not None:
2003
+ self._sdes_fast_liveplay_opt = sdes_fast_liveplay
2001
2004
  if self._stream_task is not None and not self._stream_task.done():
2002
2005
  return
2003
2006
  self._keepalive_rtsp_url = rtsp_push_url
@@ -3337,6 +3340,24 @@ class CameraMixin(_CameraControlsMixin):
3337
3340
  if self.is_sdes_camera:
3338
3341
  _fast_connect = False
3339
3342
 
3343
+ # P5 EXPERIMENT (opt-in): skip ONLY the livePlayResp blocking wait (~2 s)
3344
+ # for SDES, while keeping the full ICE/TURN/SCTP handshake. Rationale: the
3345
+ # SDES instability that forces _fast_connect off comes from skipping the
3346
+ # ICE/TURN waits + stripping TURN (under-arming SCTP) - NOT from skipping
3347
+ # the livePlayResp ack, which is purely a camera accept/reject we don't
3348
+ # need to block on (the official app never waits for it). So this targeted
3349
+ # skip is expected to be SCTP-safe and shave ~2 s off the SDES cold start.
3350
+ # Off by default, pending live A/B validation. start_keepalive(
3351
+ # sdes_fast_liveplay=...) wins, else AIDOT_SDES_FAST_LIVEPLAY env.
3352
+ _sdes_skip_lp = False
3353
+ if self.is_sdes_camera:
3354
+ _sl = getattr(self, "_sdes_fast_liveplay_opt", None)
3355
+ if _sl is None:
3356
+ _sl = os.environ.get(
3357
+ "AIDOT_SDES_FAST_LIVEPLAY", "").strip().lower() in (
3358
+ "1", "true", "yes", "on")
3359
+ _sdes_skip_lp = bool(_sl)
3360
+
3340
3361
  # Wake battery cameras via the cloud HTTP low-power endpoint before the
3341
3362
  # handshake (matches the app, which fires the HTTP wake so a sleeping camera
3342
3363
  # gets the signal even with no live MQTT session; the MQTT
@@ -4123,7 +4144,17 @@ class CameraMixin(_CameraControlsMixin):
4123
4144
  # (parity-confirmed). AIDOT_FAST_CONNECT skips it and proceeds to
4124
4145
  # SDP/ICE immediately - losing fast-fail on rejection (rare; ICE then
4125
4146
  # fails instead) in exchange for ~2 s off every LAN connect.
4126
- if not _fast_connect:
4147
+ if _fast_connect:
4148
+ _status(
4149
+ "AIDOT_FAST_CONNECT: skipping livePlayResp wait (~2s) -"
4150
+ " proceeding to SDP/ICE (app-parity, no fast-fail on reject)"
4151
+ )
4152
+ elif _sdes_skip_lp:
4153
+ _status(
4154
+ "AIDOT_SDES_FAST_LIVEPLAY: skipping livePlayResp wait (~2s)"
4155
+ " for SDES - full ICE/TURN/SCTP handshake retained (experiment)"
4156
+ )
4157
+ else:
4127
4158
  try:
4128
4159
  _lp_resp = await asyncio.wait_for(
4129
4160
  asyncio.shield(liveplay_resp_fut), timeout=2.0
@@ -4136,11 +4167,6 @@ class CameraMixin(_CameraControlsMixin):
4136
4167
  )
4137
4168
  except TimeoutError:
4138
4169
  pass
4139
- else:
4140
- _status(
4141
- "AIDOT_FAST_CONNECT: skipping livePlayResp wait (~2s) -"
4142
- " proceeding to SDP/ICE (app-parity, no fast-fail on reject)"
4143
- )
4144
4170
  # Short extra wait for getIceConfigResp - the server may only respond
4145
4171
  # once a live camera session is active (i.e. after livePlayReq).
4146
4172
  # Waiting here ensures TURN credentials arrive before RTCPeerConnection
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-aidot-cameras
3
- Version: 0.7.20
3
+ Version: 0.7.21
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