Commit ·
accd6c8
1
Parent(s): 6c9dd43
still initial commit
Browse files
app.py
CHANGED
|
@@ -28,9 +28,8 @@ else:
|
|
| 28 |
voxel_backend = None
|
| 29 |
status_text = "🔴 Offline (Connection Error)"
|
| 30 |
|
| 31 |
-
|
| 32 |
# ── Core Backend Execution ──────────────────────────────────────────────────
|
| 33 |
-
def run_modal_backend(frame: np.ndarray) -> np.ndarray:
|
| 34 |
"""Compresses the frame, sends it to Modal, and decodes the returned bytes."""
|
| 35 |
if voxel_backend is None:
|
| 36 |
return frame
|
|
@@ -41,8 +40,8 @@ def run_modal_backend(frame: np.ndarray) -> np.ndarray:
|
|
| 41 |
return frame
|
| 42 |
|
| 43 |
try:
|
| 44 |
-
# Fire bytes to Modal serverless container
|
| 45 |
-
processed_bytes = voxel_backend.remote(encoded.tobytes())
|
| 46 |
# Decode the returning bytes back into an OpenCV image
|
| 47 |
result = cv2.imdecode(np.frombuffer(processed_bytes, dtype=np.uint8), cv2.IMREAD_COLOR)
|
| 48 |
return result if result is not None else frame
|
|
@@ -56,7 +55,7 @@ def run_modal_backend(frame: np.ndarray) -> np.ndarray:
|
|
| 56 |
|
| 57 |
|
| 58 |
# ── Activation & Pre-Warming Logic ──────────────────────────────────────────
|
| 59 |
-
def start_and_warmup_container():
|
| 60 |
"""Forces the Modal container to start up before enabling the webcam stream."""
|
| 61 |
print("🚀 [START CLICKED] Waking up Modal container to prevent cold-start lag...")
|
| 62 |
|
|
@@ -66,19 +65,17 @@ def start_and_warmup_container():
|
|
| 66 |
dummy_frame = np.zeros((1, 1, 3), dtype=np.uint8)
|
| 67 |
success, encoded = cv2.imencode(".jpg", dummy_frame)
|
| 68 |
if success:
|
| 69 |
-
# Trigger a remote execution to force container ignition
|
| 70 |
-
voxel_backend.remote(encoded.tobytes())
|
| 71 |
print("✅ [CONTAINER READY] Modal container is hot and ready for frames.")
|
| 72 |
except Exception as e:
|
| 73 |
-
# Catching gracefully in case the backend throws an error on 1x1 dimensions,
|
| 74 |
-
# the container will still have been forced to start up regardless.
|
| 75 |
print(f"ℹ️ [CONTAINER NOTIFICATION] Warmup call dispatched: {e}")
|
| 76 |
|
| 77 |
return True
|
| 78 |
|
| 79 |
|
| 80 |
# ── Streaming Logic ─────────────────────────────────────────────────────────
|
| 81 |
-
def process_video_stream(frame: np.ndarray, mode: str, is_running: bool) -> np.ndarray:
|
| 82 |
"""Handles the webcam feed and respects the Start/Stop toggle."""
|
| 83 |
if frame is None:
|
| 84 |
return None
|
|
@@ -88,8 +85,8 @@ def process_video_stream(frame: np.ndarray, mode: str, is_running: bool) -> np.n
|
|
| 88 |
if not is_running:
|
| 89 |
return frame
|
| 90 |
|
| 91 |
-
# 1. Process the frame through the Modal network
|
| 92 |
-
processed = run_modal_backend(frame)
|
| 93 |
|
| 94 |
# 2. Format the output based on the selected UI mode
|
| 95 |
if mode == "Minecraft Filter":
|
|
|
|
| 28 |
voxel_backend = None
|
| 29 |
status_text = "🔴 Offline (Connection Error)"
|
| 30 |
|
|
|
|
| 31 |
# ── Core Backend Execution ──────────────────────────────────────────────────
|
| 32 |
+
async def run_modal_backend(frame: np.ndarray) -> np.ndarray:
|
| 33 |
"""Compresses the frame, sends it to Modal, and decodes the returned bytes."""
|
| 34 |
if voxel_backend is None:
|
| 35 |
return frame
|
|
|
|
| 40 |
return frame
|
| 41 |
|
| 42 |
try:
|
| 43 |
+
# Fire bytes to Modal serverless container ASYNCHRONOUSLY
|
| 44 |
+
processed_bytes = await voxel_backend.remote.aio(encoded.tobytes())
|
| 45 |
# Decode the returning bytes back into an OpenCV image
|
| 46 |
result = cv2.imdecode(np.frombuffer(processed_bytes, dtype=np.uint8), cv2.IMREAD_COLOR)
|
| 47 |
return result if result is not None else frame
|
|
|
|
| 55 |
|
| 56 |
|
| 57 |
# ── Activation & Pre-Warming Logic ──────────────────────────────────────────
|
| 58 |
+
async def start_and_warmup_container():
|
| 59 |
"""Forces the Modal container to start up before enabling the webcam stream."""
|
| 60 |
print("🚀 [START CLICKED] Waking up Modal container to prevent cold-start lag...")
|
| 61 |
|
|
|
|
| 65 |
dummy_frame = np.zeros((1, 1, 3), dtype=np.uint8)
|
| 66 |
success, encoded = cv2.imencode(".jpg", dummy_frame)
|
| 67 |
if success:
|
| 68 |
+
# Trigger a remote execution to force container ignition ASYNCHRONOUSLY
|
| 69 |
+
await voxel_backend.remote.aio(encoded.tobytes())
|
| 70 |
print("✅ [CONTAINER READY] Modal container is hot and ready for frames.")
|
| 71 |
except Exception as e:
|
|
|
|
|
|
|
| 72 |
print(f"ℹ️ [CONTAINER NOTIFICATION] Warmup call dispatched: {e}")
|
| 73 |
|
| 74 |
return True
|
| 75 |
|
| 76 |
|
| 77 |
# ── Streaming Logic ─────────────────────────────────────────────────────────
|
| 78 |
+
async def process_video_stream(frame: np.ndarray, mode: str, is_running: bool) -> np.ndarray:
|
| 79 |
"""Handles the webcam feed and respects the Start/Stop toggle."""
|
| 80 |
if frame is None:
|
| 81 |
return None
|
|
|
|
| 85 |
if not is_running:
|
| 86 |
return frame
|
| 87 |
|
| 88 |
+
# 1. Process the frame through the Modal network (AWAIT IT)
|
| 89 |
+
processed = await run_modal_backend(frame)
|
| 90 |
|
| 91 |
# 2. Format the output based on the selected UI mode
|
| 92 |
if mode == "Minecraft Filter":
|