python-aidot-cameras 0.9.1__tar.gz → 0.9.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.9.1/src/python_aidot_cameras.egg-info → python_aidot_cameras-0.9.2}/PKG-INFO +1 -1
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/pyproject.toml +1 -1
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/protocol.py +31 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2/src/python_aidot_cameras.egg-info}/PKG-INFO +1 -1
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/LICENSE +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/MANIFEST.in +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/README.md +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/setup.cfg +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/__init__.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/aes_utils.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/__init__.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/client.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/constants.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/controls.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/go2rtc.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/lan_control.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/models.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/playback.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/sdes.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/sdes_open.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/tutk.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/webrtc.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/camera/webrtc_open.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/client.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/const.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/credentials.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/device_client.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/discover.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/exceptions.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/g711.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/login_const.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/models/__init__.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/models/device_client_model.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/models/device_model.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/models/discover_model.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/py.typed +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/python_aidot_cameras.egg-info/SOURCES.txt +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/python_aidot_cameras.egg-info/dependency_links.txt +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/python_aidot_cameras.egg-info/requires.txt +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/python_aidot_cameras.egg-info/top_level.txt +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_aioice_compat.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_alarm_event.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_backoff.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_device_login_guard.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_go2rtc.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_highport_nomination.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_ice_config_cache.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_lan_control.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_live_stream_param.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_motion_poll.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_no_undefined_names.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_persistent_mqtt.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_persistent_mqtt_robustness.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_post_merge_hardening.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_sdes_adaptive.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_sdes_fast_liveplay.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_sdes_idle_release.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_sdes_serve_audio.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_sdes_serve_cmd.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_sdes_sprop.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_sdes_talk.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_sdes_watchdog.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_serve_relay.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_session_stats.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_speak.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_stream_cap.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_stream_idle.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_stream_teardown.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_talk.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_terminal_ack.py +0 -0
- {python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_token_refresh.py +0 -0
{python_aidot_cameras-0.9.1/src/python_aidot_cameras.egg-info → python_aidot_cameras-0.9.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-aidot-cameras
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.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
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-aidot-cameras"
|
|
7
|
-
version = "0.9.
|
|
7
|
+
version = "0.9.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"
|
|
@@ -897,6 +897,8 @@ def _dtls_av_mux_run(vq, aq, out_fileobj, progress, stop_flag) -> None:
|
|
|
897
897
|
have_audio = False
|
|
898
898
|
v0 = [None]
|
|
899
899
|
a_pts = [0]
|
|
900
|
+
a_rtp0 = [None] # first audio RTP timestamp (8 kHz units), for gap detection
|
|
901
|
+
a_in = [0] # 8 kHz samples emitted to the resampler so far (incl. concealed)
|
|
900
902
|
vstarted = [False]
|
|
901
903
|
|
|
902
904
|
def _flush_video():
|
|
@@ -934,7 +936,35 @@ def _dtls_av_mux_run(vq, aq, out_fileobj, progress, stop_flag) -> None:
|
|
|
934
936
|
data, _ts = aq.get_nowait()
|
|
935
937
|
except _q.Empty:
|
|
936
938
|
break
|
|
939
|
+
# Lock audio to its RTP clock. The camera's PCMA RTP timestamp is
|
|
940
|
+
# an 8 kHz sample count; on packet loss it jumps ahead of the
|
|
941
|
+
# samples we've actually decoded. Without filling that gap the
|
|
942
|
+
# audio timeline silently COMPRESSES (the lost time vanishes), so
|
|
943
|
+
# audio runs ahead of the RTP-timestamped video -> growing A/V
|
|
944
|
+
# desync and player jitter-buffer resyncs, heard as choppiness.
|
|
945
|
+
# Conceal the gap with silence (PLC) through the same stateful
|
|
946
|
+
# resampler, mirroring what the video path does with its 90 kHz
|
|
947
|
+
# timestamps. Lossless streams have _gap == 0 (no-op).
|
|
948
|
+
if _np is not None:
|
|
949
|
+
if a_rtp0[0] is None:
|
|
950
|
+
a_rtp0[0] = int(_ts)
|
|
951
|
+
_expected = (int(_ts) - a_rtp0[0]) & 0xFFFFFFFF
|
|
952
|
+
_gap = _expected - a_in[0]
|
|
953
|
+
if _gap < 0 or _gap > 8000 * 5:
|
|
954
|
+
a_in[0] = _expected # wrap / stream reset -> resync, no fill
|
|
955
|
+
elif _gap >= 160: # >= 20 ms missing: conceal with silence
|
|
956
|
+
try:
|
|
957
|
+
_sil = _np.zeros((1, int(_gap)), dtype=_np.int16)
|
|
958
|
+
_sfr = av.AudioFrame.from_ndarray(
|
|
959
|
+
_sil, format="s16", layout="mono")
|
|
960
|
+
_sfr.sample_rate = 8000
|
|
961
|
+
for _rfr in resampler.resample(_sfr):
|
|
962
|
+
fifo.write(_rfr)
|
|
963
|
+
a_in[0] += int(_gap)
|
|
964
|
+
except Exception:
|
|
965
|
+
_LOGGER.debug("swallowed exception in %s", '_flush_audio', exc_info=True)
|
|
937
966
|
for fr in adec.decode(av.Packet(data)):
|
|
967
|
+
_ndec = fr.samples
|
|
938
968
|
fr.pts = None
|
|
939
969
|
if _np is not None:
|
|
940
970
|
try:
|
|
@@ -964,6 +994,7 @@ def _dtls_av_mux_run(vq, aq, out_fileobj, progress, stop_flag) -> None:
|
|
|
964
994
|
_LOGGER.debug("swallowed exception in %s", '_flush_audio', exc_info=True)
|
|
965
995
|
for rfr in resampler.resample(fr): # 8k PCMA -> 48k fltp
|
|
966
996
|
fifo.write(rfr)
|
|
997
|
+
a_in[0] += _ndec
|
|
967
998
|
except Exception:
|
|
968
999
|
_LOGGER.debug("swallowed exception in %s", '_flush_audio', exc_info=True)
|
|
969
1000
|
while True:
|
{python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2/src/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.9.
|
|
3
|
+
Version: 0.9.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
|
|
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
|
|
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.9.1 → python_aidot_cameras-0.9.2}/src/aidot/models/device_client_model.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/src/aidot/models/discover_model.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
|
|
File without changes
|
{python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_persistent_mqtt_robustness.py
RENAMED
|
File without changes
|
{python_aidot_cameras-0.9.1 → python_aidot_cameras-0.9.2}/tests/test_post_merge_hardening.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
|
|
File without changes
|