Spaces:
Sleeping
Sleeping
| from fastapi.staticfiles import StaticFiles | |
| from fastapi import FastAPI, Form | |
| from moviepy.editor import VideoFileClip | |
| from datetime import datetime, timedelta | |
| from pathlib import Path | |
| from PIL import Image | |
| import threading | |
| app = FastAPI(title="Frame Generator") | |
| app.mount("/frames", StaticFiles(directory="frames"), name="frames") | |
| VIDEO_PATH = "demo1.mp4" | |
| FRAME_DIR = Path("frames") | |
| FRAME_STEP = 15 | |
| MAX_FRAMES = 4 | |
| # Global session state (OK for your current testing) | |
| session = { | |
| "camera_id": None, | |
| "start_time": None, | |
| "date": None, | |
| "current_index": 0, | |
| "frames": [] | |
| } | |
| def generate_frames_once(): | |
| FRAME_DIR.mkdir(exist_ok=True) | |
| clip = VideoFileClip(VIDEO_PATH) | |
| duration = int(clip.duration) | |
| frames = [] | |
| for i, t in enumerate(range(0, duration, FRAME_STEP)): | |
| if i >= MAX_FRAMES: | |
| break | |
| frame = clip.get_frame(t) | |
| img = Image.fromarray(frame) | |
| fname = f"frame_{i:03d}.jpg" | |
| fpath = FRAME_DIR / fname | |
| img.save(fpath, "JPEG", quality=90) | |
| frames.append({ | |
| "index": i, | |
| "offset": t, | |
| "path": f"/frames/{fname}" | |
| }) | |
| clip.close() | |
| return frames | |
| # Generate frames at startup (ONCE) | |
| def startup_event(): | |
| session["frames"] = generate_frames_once() | |
| def start_session( | |
| camera_id: str = Form(...), | |
| current_time: str = Form(...) | |
| ): | |
| """ | |
| current_time format: DD-MM-YYYY HH:MM:SS | |
| """ | |
| start_dt = datetime.strptime(current_time, "%d-%m-%Y %H:%M:%S") | |
| session["camera_id"] = camera_id | |
| session["start_time"] = start_dt | |
| session["date"] = start_dt.strftime("%d-%m-%Y") | |
| session["current_index"] = 0 | |
| return { | |
| "status": "started", | |
| "camera_id": camera_id, | |
| "date": session["date"], | |
| "total_frames": len(session["frames"]) | |
| } | |
| def get_next_frame(): | |
| idx = session["current_index"] | |
| if idx >= len(session["frames"]): | |
| return {"done": True} | |
| frame = session["frames"][idx] | |
| ts = session["start_time"] + timedelta(seconds=frame["offset"]) | |
| session["current_index"] += 1 | |
| return { | |
| "done": False, | |
| "frame_index": frame["index"], | |
| "timestamp": ts.strftime("%H:%M:%S"), | |
| "image_url": frame["path"] | |
| } |