Skip to content

Commit

Permalink
Merge pull request #2 from TrentonBowserFanClub/socket-stream
Browse files Browse the repository at this point in the history
Socket stream
  • Loading branch information
jwmke authored Mar 28, 2024
2 parents 72944de + ed0f0ce commit bcdde46
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 8 deletions.
28 changes: 24 additions & 4 deletions src/api/v1/api.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from typing import Union

from fastapi import FastAPI
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
from websockets.exceptions import ConnectionClosed
from fastapi.templating import Jinja2Templates
import asyncio
import cv2

app = FastAPI()

camera = cv2.VideoCapture(0,cv2.CAP_DSHOW)
templates = Jinja2Templates(directory="templates")

@app.get("/")
def read_root():
Expand All @@ -12,4 +16,20 @@ def read_root():

@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q}
return {"item_id": item_id, "q": q}

# https://stackoverflow.com/a/70626324
@app.websocket("/ws")
async def get_stream(websocket: WebSocket):
await websocket.accept()
try:
while True:
success, frame = camera.read()
if not success:
break
else:
ret, buffer = cv2.imencode('.jpg', frame)
await websocket.send_bytes(buffer.tobytes())
await asyncio.sleep(0.03)
except (WebSocketDisconnect, ConnectionClosed):
print("Client disconnected")
43 changes: 39 additions & 4 deletions src/ui/v1/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,47 @@
"use client"
import { useRef, useEffect, useInsertionEffect } from "react";

export default function Home() {
const trentons = Array(2000).fill("TRENTON");
const ws = new WebSocket('ws://localhost:8000/ws');
const canvasRef = useRef<HTMLCanvasElement>(null);

useInsertionEffect(() => {

ws.onmessage = (event) => {
if (event.data instanceof Blob) {
const reader = new FileReader();
reader.onload = () => {
const img = new Image();
img.onload = () => {
const canvas = canvasRef.current as HTMLCanvasElement;
const context = canvas?.getContext('2d');
if (context && canvas) {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0);
}
};
img.src = reader.result as string;
};
reader.readAsDataURL(event.data);
}
};

// Clean up WebSocket connection on component unmount
return () => {
ws.close();
};
}, []);

useEffect(() => {
const canvas = canvasRef.current;
const context = canvas?.getContext('2d');
}, []);

return (
<main className="min-h-screen w-full">
<div className="flex flex-col items-center justify-center min-h-screen max-h-screen overflow-hidden w-full">
<div className="text-xs font-bold text-wrap w-full text-center">{trentons.map((trenton:string, i: number) => {
return <span key={i} className="inline">{trenton} </span>;
})}</div>
<canvas ref={canvasRef} className="h-3/5 w-3/5" />
</div>
</main>
);
Expand Down

0 comments on commit bcdde46

Please sign in to comment.