import asyncio import os from datetime import datetime from pathlib import Path import cv2 from aiohttp import ClientSession from blinkpy.blinkpy import Blink from blinkpy.auth import Auth class BlinkRecorder: def __init__(self, save_path: str): self.save_path = Path(save_path) self.blink: Blink | None = None self.recording = False async def setup(self) -> None: self.blink = Blink(session=ClientSession()) auth = Auth({"username": os.getenv("BLINK_USERNAME"), "password": os.getenv("BLINK_PASSWORD")}) self.blink.auth = auth await self.blink.start() async def start_continuous_recording(self) -> None: if not self.blink: return self.recording = True tasks = [] for name, camera in self.blink.cameras.items(): camera_folder = self.save_path / name camera_folder.mkdir(parents=True, exist_ok=True) tasks.append(asyncio.create_task( self.record_camera(camera, camera_folder) )) await asyncio.gather(*tasks) async def record_camera(self, camera, save_path: Path) -> None: # Each camera gets a new video file every hour while self.recording: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") video_path = save_path / f"{timestamp}.mp4" # Get RTSP stream URL (this varies based on camera model) stream_url = await camera.get_rtsp_stream() # Setup video capture and writer cap = cv2.VideoCapture(stream_url) fourcc = cv2.VideoWriter_fourcc(*'mp4v') out = cv2.VideoWriter( str(video_path), fourcc, 30.0, # FPS (1920, 1080) # Resolution ) start_time = datetime.now() try: while (datetime.now() - start_time).seconds < 3600: # 1 hour if not self.recording: break ret, frame = cap.read() if ret: out.write(frame) await asyncio.sleep(0.033) # ~30fps finally: cap.release() out.release() async def main(): # Mount point for external HD recordings_path = Path("/mnt/external_hd/blink_recordings") recorder = BlinkRecorder(save_path=str(recordings_path)) await recorder.setup() try: await recorder.start_continuous_recording() except Exception as err: print(f"Error occurred: {err}") finally: recorder.recording = False if __name__ == "__main__": asyncio.run(main())