From 29c515edafbe6e64223ab7eb8c66bf07409acbdc Mon Sep 17 00:00:00 2001 From: Donghyun Lee Date: Mon, 9 Dec 2024 01:40:55 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20ai=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0,=20throttle=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/.env | 3 ++- web/src/ui/component/domain/SignDetector.tsx | 8 +++++++- web/vite.config.ts | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/web/.env b/web/.env index 96c129e..aee035b 100644 --- a/web/.env +++ b/web/.env @@ -1,3 +1,4 @@ # VITE_SONISORI_API_URL=https://api.sonisori.site VITE_SONISORI_API_URL=/ -VITE_SONISORI_AI_API_URL=http://127.0.0.1:5002 \ No newline at end of file +# VITE_SONISORI_AI_API_URL=ws://ai.sonisori.site +VITE_SONISORI_AI_API_URL=:5002 \ No newline at end of file diff --git a/web/src/ui/component/domain/SignDetector.tsx b/web/src/ui/component/domain/SignDetector.tsx index b969642..c56cb11 100644 --- a/web/src/ui/component/domain/SignDetector.tsx +++ b/web/src/ui/component/domain/SignDetector.tsx @@ -5,6 +5,7 @@ import { } from "@mediapipe/tasks-vision"; import { createEventListener } from "@solid-primitives/event-listener"; import { createPresence } from "@solid-primitives/presence"; +import { throttle } from "@solid-primitives/scheduled"; import ky from "ky"; import { io, Socket } from "socket.io-client"; import { @@ -100,6 +101,10 @@ const SignDetectorBody = (props: { let socket: Socket; const task = new Task(); + const send = throttle((landmarks: NormalizedLandmark[][]) => { + socket.emit("predict", landmarks); + }); + const streamMedia = async () => { if (!navigator.mediaDevices?.getDisplayMedia) { throw new Error("카메라를 사용할 수 없는 디바이스입니다."); @@ -149,7 +154,7 @@ const SignDetectorBody = (props: { const { landmarks } = handLandmarker.detectForVideo(videoRef!, time); drawLandmarks(landmarks); - socket.emit("predict", landmarks); + send(landmarks); if (typeof animationFrame == "number") { animationFrame = requestAnimationFrame(predictMedia); @@ -185,6 +190,7 @@ const SignDetectorBody = (props: { animationFrame = null; } handLandmarker.close(); + send.clear(); socket.disconnect(); stream?.getTracks().forEach((track) => track.stop()); setLoaded(false); diff --git a/web/vite.config.ts b/web/vite.config.ts index 1ae01d0..b00ff5b 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -12,9 +12,9 @@ export default defineConfig({ cookieDomainRewrite: "localhost", }, "^:5002/.*": { - target: "ws://api.sonisori.site:5002", - ws: true, + target: "ws://ai.sonisori.site", changeOrigin: true, + ws: true, }, }, }, From 54c6ef21a9b4042acfbf13ce69905fbf99012f66 Mon Sep 17 00:00:00 2001 From: Donghyun Lee Date: Wed, 11 Dec 2024 11:30:36 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EA=B0=80=EC=9D=B4=EB=93=9C=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/.env | 4 +- web/src/ui/component/domain/SignDetector.tsx | 2 +- web/src/ui/screen/Dictionary.tsx | 98 +++++++++++++------- 3 files changed, 69 insertions(+), 35 deletions(-) diff --git a/web/.env b/web/.env index aee035b..ca9f5d2 100644 --- a/web/.env +++ b/web/.env @@ -1,4 +1,4 @@ # VITE_SONISORI_API_URL=https://api.sonisori.site VITE_SONISORI_API_URL=/ -# VITE_SONISORI_AI_API_URL=ws://ai.sonisori.site -VITE_SONISORI_AI_API_URL=:5002 \ No newline at end of file +VITE_SONISORI_AI_API_URL=ws://ai.sonisori.site +# VITE_SONISORI_AI_API_URL=:5002 \ No newline at end of file diff --git a/web/src/ui/component/domain/SignDetector.tsx b/web/src/ui/component/domain/SignDetector.tsx index c56cb11..5b197ad 100644 --- a/web/src/ui/component/domain/SignDetector.tsx +++ b/web/src/ui/component/domain/SignDetector.tsx @@ -103,7 +103,7 @@ const SignDetectorBody = (props: { const send = throttle((landmarks: NormalizedLandmark[][]) => { socket.emit("predict", landmarks); - }); + }, 200); const streamMedia = async () => { if (!navigator.mediaDevices?.getDisplayMedia) { diff --git a/web/src/ui/screen/Dictionary.tsx b/web/src/ui/screen/Dictionary.tsx index 0615f9a..d11032b 100644 --- a/web/src/ui/screen/Dictionary.tsx +++ b/web/src/ui/screen/Dictionary.tsx @@ -1,45 +1,79 @@ -import { useNavigate } from "@solidjs/router"; +import { useNavigate, useParams } from "@solidjs/router"; +import { createResource, For, Show } from "solid-js"; +import { client } from "../../service/util/api"; import { ScrollArea } from "../component/base/ScrollAreaV2"; import { SignDetector } from "../component/domain/SignDetector"; export const Dictionary = () => { const navigate = useNavigate(); - const word = { - word: "사과", - videoUrl: "https://www.youtube.com/watch?v=9bZkp7q19f0", - }; + const { id } = useParams(); + const [data] = createResource(() => + client.get(`api/words/${id}`).json<{ + description: string; + resources: { + resourceType: "image" | "video"; + resourceUrl: string; + }[]; + word: string; + }>(), + ); return (
navigate(-1)} open signPhraseType="평서문" /> - -
-
-

{word.word}

- {/* video placeholder */} -