python-camera-manager-directshow 0.1.0__py3-none-any.whl

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.
app/__init__.py ADDED
File without changes
app/main.py ADDED
@@ -0,0 +1,106 @@
1
+ import os
2
+ import sys
3
+
4
+ # Allow running as `python app/main.py` while importing top-level packages.
5
+ PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
6
+ if PROJECT_ROOT not in sys.path:
7
+ sys.path.insert(0, PROJECT_ROOT)
8
+
9
+ from camera import _camera
10
+ from GUI.main_GUI import MainGUI, select_camera_gui, show_no_camera_dialog
11
+ import cv2
12
+ import threading
13
+ cv2.utils.logging.setLogLevel(cv2.utils.logging.LOG_LEVEL_ERROR)
14
+
15
+ debug = False
16
+
17
+ def debug_print(*args, **kwargs):
18
+ """Print only if DEBUG mode is enabled."""
19
+ if debug:
20
+ print(*args, **kwargs)
21
+
22
+ def main():
23
+ gui = MainGUI()
24
+ # Scan for devices and prompt user to Retry/Cancel if none found
25
+ while True:
26
+ uvc_cameras = _camera.Camera.get_connected_cameras(get_formats=True, get_ranges=True)
27
+
28
+ if uvc_cameras:
29
+ break
30
+
31
+ retry = show_no_camera_dialog(gui.root)
32
+ if not retry:
33
+ print("No cameras found. Exiting.")
34
+ return
35
+
36
+ # Get device path and format from GUI
37
+ device_path, camera_format, request_rgb24 = select_camera_gui(uvc_cameras, gui.root)
38
+ if device_path is None or camera_format is None:
39
+ print("No camera selected. Exiting.")
40
+ return
41
+
42
+ debug_print(f"Selected camera: {device_path}")
43
+ debug_print(f"Format: {camera_format.width}x{camera_format.height} @ {camera_format.fps} FPS")
44
+
45
+ # Open the selected camera using the Camera class
46
+ camera = _camera.Camera(debug_logging=[False,False,False])
47
+
48
+ # Connect the GUI callback to the camera BEFORE opening
49
+ camera.set_frame_callback(gui.update_video_frame)
50
+
51
+ # Open with device path and format
52
+ camera_opened_successfully = camera.open(
53
+ device_path,
54
+ camera_format,
55
+ request_rgb24_conversion=bool(request_rgb24)
56
+ )
57
+ if not camera_opened_successfully:
58
+ debug_print("Failed to open camera.")
59
+ return
60
+
61
+ # Bind active camera to GUI controls (e.g., format switching)
62
+ gui.bind_camera(camera, device_path)
63
+
64
+ debug_print("Camera opened successfully!")
65
+
66
+ # Handle window close event to ensure clean shutdown
67
+ closing_state = {"started": False}
68
+
69
+ def on_close():
70
+ if closing_state["started"]:
71
+ return
72
+
73
+ closing_state["started"] = True
74
+
75
+ try:
76
+ # Stop forwarding new frames to Tk while shutdown is in progress.
77
+ camera.set_frame_callback(None)
78
+ except Exception:
79
+ pass
80
+
81
+ def close_camera_background():
82
+ try:
83
+ camera.close()
84
+ except Exception as e:
85
+ print(f"Error closing camera: {e}")
86
+
87
+ close_thread = threading.Thread(target=close_camera_background, daemon=True)
88
+ close_thread.start()
89
+
90
+ def finish_close():
91
+ try:
92
+ gui.root.destroy()
93
+ except Exception:
94
+ pass
95
+
96
+ # Try fast/clean close first; if driver blocks, force-close UI shortly after.
97
+ gui.root.after(50, finish_close)
98
+ gui.root.after(1500, finish_close)
99
+
100
+ gui.root.protocol("WM_DELETE_WINDOW", on_close)
101
+
102
+ # Start the GUI event loop
103
+ gui.run()
104
+
105
+ if __name__ == "__main__":
106
+ main()
camera/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ from . import camera_manager as _camera
2
+ from .camera_inspector_bridge import CameraInspectorBridge
3
+ from .camera_device_bridge import CameraDeviceBridge
4
+
5
+ __all__ = ['_camera', 'CameraInspectorBridge', 'CameraDeviceBridge']