55import cv2
66import numpy as np
77import requests
8- from typing import Optional , Union , Dict
8+ from typing import Optional
99from urllib .parse import urlparse
1010
1111from arduino .app_utils import Logger
@@ -125,52 +125,21 @@ def _close_camera(self) -> None:
125125 self ._cap = None
126126
127127 def _read_frame (self ) -> Optional [np .ndarray ]:
128- """Read a frame from the IP camera."""
128+ """Read a frame from the IP camera with automatic reconnection ."""
129129 if self ._cap is None :
130- return None
130+ logger .info (f"No connection to IP camera { self .url } , attempting to reconnect" )
131+ try :
132+ self ._open_camera ()
133+ except Exception as e :
134+ logger .error (f"Failed to reconnect to IP camera { self .url } : { e } " )
135+ return None
131136
132137 ret , frame = self ._cap .read ()
133- if not ret or frame is None :
134- # For IP cameras, occasional frame drops are normal
135- logger .debug (f"Frame read failed from IP camera: { self .url } " )
136- return None
137-
138- return frame
138+ if ret and frame is not None :
139+ return frame
139140
140- def reconnect (self ) -> None :
141- """Reconnect to the IP camera."""
142- logger .info (f"Reconnecting to IP camera: { self .url } " )
143- was_started = self ._is_started
144-
145- if was_started :
146- self .stop ()
147-
148- try :
149- if was_started :
150- self .start ()
151- except Exception as e :
152- logger .error (f"Failed to reconnect to IP camera: { e } " )
153- raise
141+ if not self ._cap .isOpened ():
142+ logger .warning (f"IP camera connection dropped: { self .url } " )
143+ self ._close_camera () # Will reconnect on next call
154144
155- def test_connection (self ) -> bool :
156- """
157- Test if the camera is accessible without starting it.
158-
159- Returns:
160- True if camera is accessible, False otherwise
161- """
162- try :
163- if self .url .startswith (('http://' , 'https://' )):
164- self ._test_http_connectivity ()
165-
166- # Quick test with OpenCV
167- test_cap = cv2 .VideoCapture (self ._build_authenticated_url ())
168- if test_cap .isOpened ():
169- ret , _ = test_cap .read ()
170- test_cap .release ()
171- return ret
172-
173- return False
174- except Exception as e :
175- logger .debug (f"Connection test failed: { e } " )
176- return False
145+ return None
0 commit comments