Speed up camera source modal with cached enumeration and instant open
Cache camera enumeration results for 30s and limit probe range using WMI camera count on Windows. Open source modal instantly with a loading spinner while dropdowns are populated asynchronously. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ Prerequisites (optional dependency):
|
||||
|
||||
import platform
|
||||
import sys
|
||||
import time
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
import numpy as np
|
||||
@@ -66,23 +67,43 @@ def _get_camera_friendly_names() -> Dict[int, str]:
|
||||
return {}
|
||||
|
||||
|
||||
_camera_cache: Optional[List[Dict[str, Any]]] = None
|
||||
_camera_cache_time: float = 0
|
||||
_CAMERA_CACHE_TTL = 30.0 # seconds
|
||||
|
||||
|
||||
def _enumerate_cameras(backend_name: str = "auto") -> List[Dict[str, Any]]:
|
||||
"""Probe camera indices and return metadata for each available camera.
|
||||
|
||||
Results are cached for 30 seconds to avoid repeated slow probes.
|
||||
Returns a list of dicts: {cv2_index, name, width, height, fps}.
|
||||
"""
|
||||
global _camera_cache, _camera_cache_time
|
||||
|
||||
now = time.monotonic()
|
||||
if _camera_cache is not None and (now - _camera_cache_time) < _CAMERA_CACHE_TTL:
|
||||
return _camera_cache
|
||||
|
||||
try:
|
||||
import cv2
|
||||
except ImportError:
|
||||
_camera_cache = []
|
||||
_camera_cache_time = now
|
||||
return []
|
||||
|
||||
backend_id = _cv2_backend_id(backend_name)
|
||||
friendly_names = _get_camera_friendly_names()
|
||||
|
||||
# On Windows, WMI tells us how many cameras exist — skip probing
|
||||
# indices beyond that count to avoid slow timeouts.
|
||||
max_probe = _MAX_CAMERA_INDEX
|
||||
if friendly_names:
|
||||
max_probe = min(len(friendly_names) + 1, _MAX_CAMERA_INDEX)
|
||||
|
||||
cameras: List[Dict[str, Any]] = []
|
||||
sequential_idx = 0
|
||||
|
||||
for i in range(_MAX_CAMERA_INDEX):
|
||||
for i in range(max_probe):
|
||||
if backend_id is not None:
|
||||
cap = cv2.VideoCapture(i, backend_id)
|
||||
else:
|
||||
@@ -108,6 +129,9 @@ def _enumerate_cameras(backend_name: str = "auto") -> List[Dict[str, Any]]:
|
||||
})
|
||||
sequential_idx += 1
|
||||
|
||||
_camera_cache = cameras
|
||||
_camera_cache_time = now
|
||||
logger.debug(f"Camera enumeration: found {len(cameras)} camera(s) (probed {max_probe} indices)")
|
||||
return cameras
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user