Revert "feat: implement 10s image caching by stream id in /app/{id}.jpg"
All checks were successful
Lint and Syntax Check / build (push) Successful in 5s

This reverts commit 500c42f59f.
This commit is contained in:
2026-04-02 14:07:12 +02:00
parent 500c42f59f
commit b23a17f811

138
main.py
View File

@@ -2,11 +2,7 @@ import cv2
import yt_dlp import yt_dlp
import numpy as np import numpy as np
import json import json
import time
import base64
_snapshot_cache = {}
CACHE_TTL = 10
def capture_stream_snapshot(youtube_url, output_file="snapshot.jpg", toBuffer=False): def capture_stream_snapshot(youtube_url, output_file="snapshot.jpg", toBuffer=False):
# 1. Configure yt-dlp to get the direct stream URL # 1. Configure yt-dlp to get the direct stream URL
@@ -33,7 +29,7 @@ def capture_stream_snapshot(youtube_url, output_file="snapshot.jpg", toBuffer=Fa
if not cap.isOpened(): if not cap.isOpened():
print("Error: Could not open video stream.") print("Error: Could not open video stream.")
return None return None if toBuffer else None
# Read a single frame # Read a single frame
success, frame = cap.read() success, frame = cap.read()
@@ -43,126 +39,138 @@ def capture_stream_snapshot(youtube_url, output_file="snapshot.jpg", toBuffer=Fa
# Encode frame as JPEG to memory buffer # Encode frame as JPEG to memory buffer
ret, buf = cv2.imencode(".jpg", frame) ret, buf = cv2.imencode(".jpg", frame)
if ret: if ret:
print("Snapshot captured to buffer.")
cap.release() cap.release()
return buf.tobytes() return buf.tobytes()
else: else:
print("Error: Could not encode frame to buffer.")
cap.release() cap.release()
return None return None
else: else:
# 3. Save the frame as an image # 3. Save the frame as an image
cv2.imwrite(output_file, frame) cv2.imwrite(output_file, frame)
cap.release() print(f"Snapshot saved to {output_file}")
return True
else: else:
print("Error: Could not read frame from stream.") print("Error: Could not read frame from stream.")
# Cleanup
cap.release() cap.release()
return None
# Shsf Handler # Shsf Handler
def main(args): def main(args):
route = args.get("route", "") route = args.get("route")
# Handle /app/{id}.jpg
if route.startswith("app/") and route.endswith(".jpg"):
url_id = route.split("/")[-1].replace(".jpg", "")
now = time.time()
if url_id in _snapshot_cache:
ts, encoded = _snapshot_cache[url_id]
if now - ts < CACHE_TTL:
return {
"_shsf": "v1", # Changed to v1 for simpler binary response if v2 is picky
"_code": 200,
"_res": encoded,
"_is_base64": True,
"_headers": { "Content-Type": "image/jpeg", "X-Cache": "HIT" }
}
# Cache miss
yt_url = f"https://www.youtube.com/watch?v={url_id}"
image_bytes = capture_stream_snapshot(yt_url, toBuffer=True)
if image_bytes:
encoded_content = base64.b64encode(image_bytes).decode('utf-8')
_snapshot_cache[url_id] = (now, encoded_content)
return {
"_shsf": "v1",
"_code": 200,
"_res": encoded_content,
"_is_base64": True,
"_headers": { "Content-Type": "image/jpeg", "X-Cache": "MISS" }
}
if route == "snapshot": if route == "snapshot":
url = args.get("body", "") url = args.get("body", "")
try: try:
url = json.loads(url) url = json.loads(url)
except json.JSONDecodeError: except json.JSONDecodeError:
print("Error: Invalid JSON input.")
return { return {
"_shsf": "v2", "_shsf": "v2",
"_code": 400, "_code": 400,
"_res": {"message": "Invalid JSON input."}, "_res": {"message": "Invalid JSON input."},
"_headers": { "Content-Type": "application/json" }, "_headers": {
"Content-Type": "application/json",
},
} }
url = url.get("url", "") url = url.get("url", "")
if not url: if not url:
print("Error: URL not provided.")
return { return {
"_shsf": "v2", "_shsf": "v2",
"_code": 400, "_code": 400,
"_res": {"message": "URL not provided."}, "_res": {"message": "URL not provided."},
"_headers": { "Content-Type": "application/json" }, "_headers": {
"Content-Type": "application/json",
},
} }
try: try:
image_bytes = capture_stream_snapshot(url, toBuffer=True) capture_stream_snapshot(url, output_file="/tmp/snapshot.jpg")
if image_bytes: content = None
encoded_content = base64.b64encode(image_bytes).decode('utf-8') with open("/tmp/snapshot.jpg", "rb") as f:
return { content = f.read()
"_shsf": "v2",
"_code": 200,
"_res": { "message": "done", "buffer": encoded_content },
"_headers": { "Content-Type": "application/json" },
}
except Exception as e: except Exception as e:
print(f"Error: {e}")
return { return {
"_shsf": "v2", "_shsf": "v2",
"_code": 500, "_code": 500,
"_res": {"message": str(e)}, "_res": {"message": f"Could not capture snapshot: {str(e)}"},
"_headers": { "Content-Type": "application/json" }, "_headers": {
"Content-Type": "application/json",
},
} }
if content is None:
print("Error: Could not capture snapshot.")
return { return {
"_shsf": "v2", "_shsf": "v2",
"_code": 500, "_code": 500,
"_res": {"message": "Could not capture snapshot."}, "_res": {"message": "Could not capture snapshot."},
"_headers": { "Content-Type": "application/json" }, "_headers": {
"Content-Type": "application/json",
},
} }
# Convert content to base64 for JSON response
import base64
encoded_content = base64.b64encode(content).decode('utf-8')
return {
"_shsf": "v2",
"_code": 200,
"_res": {
"message": "done",
"buffer": encoded_content
},
"_headers": {
"Content-Type": "application/json",
},
}
elif route == "health": elif route == "health":
return { return {
"_shsf": "v2", "_shsf": "v2",
"_code": 200, "_code": 200,
"_res": {"message": "Service is healthy."}, "_res": {"message": "Service is healthy."},
"cache_size": len(_snapshot_cache), "_headers": {
"_headers": { "Content-Type": "application/json" }, "Content-Type": "application/json",
},
} }
elif route == "default": # UI Route elif route == "default": # UI Route
try: try:
content = ""
with open("/app/ui.html", "r") as f: with open("/app/ui.html", "r") as f:
content = f.read() content = f.read()
except FileNotFoundError:
print("Error: /app/ui.html not found.")
return {
"_shsf": "v2",
"_code": 404,
"_res": {"message": "UI file not found."},
"_headers": {
"Content-Type": "application/json",
},
}
except Exception as e:
print(f"Error loading UI: {e}")
return {
"_shsf": "v2",
"_code": 500,
"_res": {"message": f"Server error: {str(e)}"},
"_headers": {
"Content-Type": "application/json",
},
}
return { return {
"_shsf": "v2", "_shsf": "v2",
"_code": 200, "_code": 200,
"_res": content, "_res": content,
"_headers": { "Content-Type": "text/html" }, "_headers": {
} "Content-Type": "text/html",
except Exception as e: },
return {
"_shsf": "v2",
"_code": 404,
"_res": {"message": "UI file not found or error."},
} }
if __name__ == "__main__": if __name__ == "__main__":
print("running stream-shot") print("omg im on main")
capture_stream_snapshot("https://www.youtube.com/watch?v=n15V_fCsl_c", output_file="snapshot.jpg")