|
6 | 6 | import ipaddress |
7 | 7 | import socket |
8 | 8 | import nmap |
9 | | -from typing import List, Dict, Any, Optional, Tuple |
| 9 | +import cv2 |
| 10 | +from typing import List, Dict, Any, Optional, Tuple, Callable |
10 | 11 | from dataclasses import dataclass |
| 12 | +from concurrent.futures import ThreadPoolExecutor |
11 | 13 |
|
12 | 14 | @dataclass |
13 | 15 | class NetworkService: |
@@ -52,6 +54,7 @@ def __init__(self, timeout: float = 2.0, max_workers: int = 50): |
52 | 54 | self.timeout = timeout |
53 | 55 | self.max_workers = max_workers |
54 | 56 | self.nm = nmap.PortScanner() |
| 57 | + self.executor = ThreadPoolExecutor(max_workers=max_workers) |
55 | 58 |
|
56 | 59 | async def scan_network(self, network: str = '192.168.1.0/24', |
57 | 60 | ports: Optional[List[int]] = None, |
@@ -104,6 +107,34 @@ async def scan_rtsp_servers(self, network: str = '192.168.1.0/24') -> List[Netwo |
104 | 107 | async def scan_email_servers(self, network: str = '192.168.1.0/24') -> List[NetworkService]: |
105 | 108 | """Scan for email servers (SMTP, IMAP) on the network.""" |
106 | 109 | return await self.scan_network(network, service_types=['smtp', 'smtps', 'imap', 'imaps']) |
| 110 | + |
| 111 | + async def _run_in_executor(self, func: Callable, *args) -> Any: |
| 112 | + """Run a function in the thread pool.""" |
| 113 | + loop = asyncio.get_event_loop() |
| 114 | + return await loop.run_in_executor(self.executor, func, *args) |
| 115 | + |
| 116 | + async def check_rtsp_stream(self, ip: str, port: int = 554, timeout: float = 2.0) -> bool: |
| 117 | + """Check if an RTSP stream is accessible using OpenCV.""" |
| 118 | + rtsp_url = f"rtsp://{ip}:{port}" |
| 119 | + |
| 120 | + def _check() -> bool: |
| 121 | + cap = None |
| 122 | + try: |
| 123 | + cap = cv2.VideoCapture(rtsp_url, cv2.CAP_FFMPEG) |
| 124 | + cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('H', '2', '6', '4')) |
| 125 | + cap.set(cv2.CAP_PROP_OPEN_TIMEOUT_MSEC, int(timeout * 1000)) |
| 126 | + cap.set(cv2.CAP_PROP_READ_TIMEOUT_MSEC, int(timeout * 1000)) |
| 127 | + return cap.isOpened() and cap.grab() |
| 128 | + except Exception: |
| 129 | + return False |
| 130 | + finally: |
| 131 | + if cap is not None: |
| 132 | + cap.release() |
| 133 | + |
| 134 | + try: |
| 135 | + return await self._run_in_executor(_check) |
| 136 | + except Exception: |
| 137 | + return False |
107 | 138 |
|
108 | 139 | async def check_rtsp_stream(self, ip: str, port: int = 554, timeout: float = 2.0) -> bool: |
109 | 140 | """Check if an RTSP stream is accessible.""" |
|
0 commit comments