Skip to content

Instantly share code, notes, and snippets.

@nocarryr
Created June 14, 2025 23:06
Show Gist options
  • Select an option

  • Save nocarryr/8b41fffc398da4ab9aacdcce03d73041 to your computer and use it in GitHub Desktop.

Select an option

Save nocarryr/8b41fffc398da4ab9aacdcce03d73041 to your computer and use it in GitHub Desktop.
cyndilib ptz class patch
diff --git a/src/cyndilib/receiver.pxd b/src/cyndilib/receiver.pxd
index 2d03940..a3650d8 100644
--- a/src/cyndilib/receiver.pxd
+++ b/src/cyndilib/receiver.pxd
@@ -48,6 +48,7 @@ cdef class Receiver:
cdef readonly VideoRecvFrame video_frame
cdef readonly AudioRecvFrame audio_frame
cdef readonly MetadataRecvFrame metadata_frame
+ cdef readonly PTZ ptz
cdef readonly str source_name
cdef readonly bint has_video_frame, has_audio_frame, has_metadata_frame
cdef readonly RLock connection_lock
@@ -84,8 +85,6 @@ cdef class Receiver:
cdef int _send_source_tally(self) except -1 nogil
cpdef is_ptz_supported(self)
cdef bint _is_ptz_supported(self)
- cpdef set_zoom_level(self, float zoom_level)
- cdef bint _set_zoom_level(self, float zoom_level)
cpdef zoom(self, float zoom_speed)
cdef bint _set_zoom_speed(self, float zoom_speed)
cpdef pan_and_tilt(self, float pan_speed, float tilt_speed)
@@ -139,3 +138,9 @@ cdef class Receiver:
cdef void free_video(self, NDIlib_video_frame_v2_t* p) noexcept nogil
cdef void free_audio(self, NDIlib_audio_frame_v3_t* p) noexcept nogil
cdef void free_metadata(self, NDIlib_metadata_frame_t* p) noexcept nogil
+
+
+cdef class PTZ:
+ cdef Receiver receiver
+
+ cdef NDIlib_recv_instance_t _get_ptr(self)
diff --git a/src/cyndilib/receiver.pyi b/src/cyndilib/receiver.pyi
index e1a76aa..ef4794c 100644
--- a/src/cyndilib/receiver.pyi
+++ b/src/cyndilib/receiver.pyi
@@ -39,6 +39,7 @@ class Receiver:
connection_lock: RLock
connection_notify: Condition
frame_sync: FrameSync
+ ptz: PTZ
has_audio_frame: bool
has_metadata_frame: bool
has_video_frame: bool
@@ -97,6 +98,9 @@ class Receiver:
def set_exposure_fine(self, iris: float, gain: float, shutter_speed: float) -> Any: ...
def __reduce__(self): ...
+class PTZ:
+ def set_zoom_level(self, zoom_value: float) -> bool: ...
+
class RecvCreate:
# __pyx_vtable__: ClassVar[PyCapsule] = ...
allow_video_fields: bool
diff --git a/src/cyndilib/receiver.pyx b/src/cyndilib/receiver.pyx
index cc22bf1..b779145 100644
--- a/src/cyndilib/receiver.pyx
+++ b/src/cyndilib/receiver.pyx
@@ -103,6 +103,7 @@ cdef class Receiver:
audio_frame (AudioRecvFrame):
metadata_frame (MetadataRecvFrame):
frame_sync (FrameSync):
+ ptz (PTZ):
"""
def __cinit__(self, *args, **kwargs):
@@ -168,9 +169,11 @@ cdef class Receiver:
if self.ptr is NULL:
raise MemoryError()
self.frame_sync = FrameSync(self)
+ self.ptz = PTZ(self)
def __dealloc__(self):
self.frame_sync = None
+ self.ptz = None
cdef NDIlib_recv_instance_t p = self.ptr
if self.ptr is not NULL:
self.ptr = NULL
@@ -403,23 +406,6 @@ cdef class Receiver:
cdef bint _is_ptz_supported(self):
return NDIlib_recv_ptz_is_supported(self.ptr)
- cpdef set_zoom_level(self, float zoom_level):
- """Set the PTZ zoom level
-
- Arguments:
- zoom_level (float): `0.0` (max zoomed out) … `1.0` (max zoomed in)
-
- .. versionadded:: 0.0.7
- """
- return self._set_zoom_level(zoom_level)
-
- cdef bint _set_zoom_level(self, float zoom_level):
- if zoom_level < 0.0:
- zoom_level = 0.0
- elif zoom_level > 1.0:
- zoom_level = 1.0
- return NDIlib_recv_ptz_zoom(self.ptr, zoom_level)
-
cpdef zoom(self, float zoom_speed):
"""Zoom the camera with the given speed.
@@ -908,6 +894,35 @@ cdef class Receiver:
cdef void free_metadata(self, NDIlib_metadata_frame_t* p) noexcept nogil:
NDIlib_recv_free_metadata(self.ptr, p)
+
+cdef class PTZ:
+ """PTZ control for a :class:`Receiver`
+ """
+ def __init__(self, Receiver receiver):
+ self.receiver = receiver
+
+ def __dealloc__(self):
+ self.receiver = None
+
+ cdef NDIlib_recv_instance_t _get_ptr(self):
+ cdef NDIlib_recv_instance_t ptr = self.receiver.ptr
+ if ptr is NULL:
+ raise ValueError("Receiver is not connected")
+ return ptr
+
+ def set_zoom_level(self, float zoom_level):
+ """Set the PTZ zoom level
+
+ Arguments:
+ zoom_level (float): `0.0` (max zoomed out) … `1.0` (max zoomed in)
+
+ .. versionadded:: 0.0.7
+ """
+ if not 0 <= zoom_level <= 1:
+ raise ValueError("zoom_level must be between 0.0 and 1.0")
+ return NDIlib_recv_ptz_zoom(self._get_ptr(), zoom_level)
+
+
cdef class RecvThreadWorker:
cdef Receiver receiver
cdef uint32_t timeout_ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment