some bullshit

This commit is contained in:
rattatwinko
2025-05-27 16:05:04 +02:00
parent 64b472ad8e
commit 82f435b8c3
5 changed files with 5517 additions and 272 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -284,11 +284,13 @@ class CameraStream:
self.frame_timeout = 5.0 # Timeout after 5 seconds without frames
self.reconnect_interval = 5.0 # Try to reconnect every 5 seconds
self.last_reconnect_attempt = 0
self.connection_retries = 0
self.max_retries = 3
def start(self):
"""Start the camera stream"""
"""Start the camera stream with improved error handling"""
if self.running:
return
return False
try:
if self.is_network_camera:
@@ -315,6 +317,16 @@ class CameraStream:
logger.info(f"Connecting to network camera: {url}")
self.cap = cv2.VideoCapture(url)
# Wait for connection
retry_count = 0
while not self.cap.isOpened() and retry_count < 3:
time.sleep(1)
retry_count += 1
self.cap.open(url)
if not self.cap.isOpened():
raise Exception(f"Failed to connect to network camera at {url}")
else:
# Handle local camera
self.cap = cv2.VideoCapture(self.camera_id)
@@ -329,6 +341,7 @@ class CameraStream:
self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
self.running = True
self.connection_retries = 0
self.thread = threading.Thread(target=self._capture_loop)
self.thread.daemon = True
self.thread.start()
@@ -338,6 +351,7 @@ class CameraStream:
if self.cap:
self.cap.release()
self.cap = None
self.connection_retries += 1
return False
def stop(self):
@@ -356,15 +370,23 @@ class CameraStream:
break
def _capture_loop(self):
"""Main capture loop with automatic reconnection"""
"""Main capture loop with improved error handling and reconnection"""
while self.running:
try:
if not self.cap or not self.cap.isOpened():
current_time = time.time()
if current_time - self.last_reconnect_attempt >= self.reconnect_interval:
logger.info(f"Attempting to reconnect camera {self.camera_id}")
self.last_reconnect_attempt = current_time
self.start()
if self.connection_retries < self.max_retries:
logger.info(f"Attempting to reconnect camera {self.camera_id}")
self.last_reconnect_attempt = current_time
if self.start():
logger.info(f"Successfully reconnected camera {self.camera_id}")
else:
logger.warning(f"Failed to reconnect camera {self.camera_id}")
else:
logger.error(f"Max reconnection attempts reached for camera {self.camera_id}")
self.running = False
break
time.sleep(1)
continue
@@ -511,10 +533,16 @@ def video_feed(camera_id):
return Response(gen_frames(camera_id),
mimetype='multipart/x-mixed-replace; boundary=frame')
@app.route('/scan_cameras')
def scan_cameras_route():
"""Scan and return available cameras"""
cameras = scan_cameras_silently()
return jsonify({'cameras': cameras})
@app.route('/cameras')
def get_cameras():
"""Get list of available cameras"""
# Scan for local cameras silently
# Get local cameras
cameras = scan_cameras_silently()
# Add network cameras
@@ -523,7 +551,9 @@ def get_cameras():
cameras.append({
'id': f'net:{name}',
'type': 'network',
'name': f'{name} ({url})'
'name': f'{name} ({url})',
'width': 1280, # Default width for network cameras
'height': 720 # Default height for network cameras
})
# Add status information for active cameras
@@ -536,7 +566,7 @@ def get_cameras():
camera['active'] = False
camera['status'] = 'disconnected'
return jsonify(cameras)
return jsonify({'cameras': cameras})
@app.route('/add_camera/<path:camera_id>')
def add_camera(camera_id):
@@ -597,6 +627,109 @@ def load_model():
success = camera_manager.detector.load_yolo_model(model_dir)
return jsonify({'success': success})
@app.route('/check_model')
def check_model():
"""Check YOLO model status"""
return jsonify({
'model_loaded': camera_manager.detector.model_loaded,
'model_name': camera_manager.detector.current_model,
'cuda_available': camera_manager.detector.cuda_available
})
@app.route('/model_info')
def model_info():
"""Get detailed model information"""
detector = camera_manager.detector
return jsonify({
'model_loaded': detector.model_loaded,
'model_name': detector.current_model,
'cuda_available': detector.cuda_available,
'classes': detector.classes,
'confidence_threshold': detector.confidence_threshold
})
@app.route('/update_model_settings', methods=['POST'])
def update_model_settings():
"""Update model settings"""
data = request.json
if 'confidence_threshold' in data:
try:
threshold = float(data['confidence_threshold'])
if 0 <= threshold <= 1:
camera_manager.detector.confidence_threshold = threshold
return jsonify({'success': True})
except ValueError:
pass
return jsonify({'success': False, 'error': 'Invalid settings'})
@app.route('/network_cameras/list')
def list_network_cameras():
"""List all configured network cameras"""
cameras = []
for name, info in camera_manager.network_cameras.items():
if isinstance(info, dict):
cameras.append({
'name': name,
'url': info['url'],
'username': info.get('username'),
'has_auth': bool(info.get('username') and info.get('password'))
})
else:
cameras.append({
'name': name,
'url': info,
'has_auth': False
})
return jsonify({'cameras': cameras})
@app.route('/network_cameras/remove/<name>', methods=['POST'])
def remove_network_camera(name):
"""Remove a network camera"""
success = camera_manager.remove_network_camera(name)
return jsonify({'success': success})
@app.route('/camera_settings/<path:camera_id>', methods=['GET', 'POST'])
def camera_settings(camera_id):
"""Get or update camera settings"""
camera = camera_manager.get_camera(camera_id)
if not camera:
return jsonify({'success': False, 'error': 'Camera not found'})
if request.method == 'POST':
data = request.json
try:
if 'width' in data and 'height' in data:
width = int(data['width'])
height = int(data['height'])
if camera.cap:
camera.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
camera.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
if 'fps' in data:
fps = int(data['fps'])
if camera.cap:
camera.cap.set(cv2.CAP_PROP_FPS, fps)
if 'reconnect' in data and data['reconnect']:
# Force camera reconnection
camera.stop()
time.sleep(1) # Wait for cleanup
camera.start()
return jsonify({'success': True})
except Exception as e:
logger.error(f"Error updating camera settings: {e}")
return jsonify({'success': False, 'error': str(e)})
else:
if not camera.cap:
return jsonify({'success': False, 'error': 'Camera not connected'})
settings = {
'width': int(camera.cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
'height': int(camera.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)),
'fps': int(camera.cap.get(cv2.CAP_PROP_FPS)),
'is_network': camera.is_network_camera,
'status': 'connected' if camera.cap and camera.cap.isOpened() else 'disconnected'
}
return jsonify({'success': True, 'settings': settings})
# Reduce camera scanning noise
def scan_cameras_silently():
"""Scan for cameras while suppressing OpenCV warnings"""