Quazim0t0 commited on
Commit
6869157
·
verified ·
1 Parent(s): 5a03d8c

Upload 36 files

Browse files
src/components/MultiSourceCaptioningView.tsx CHANGED
@@ -28,6 +28,8 @@ export default function MultiSourceCaptioningView() {
28
  const [uploadedUrl, setUploadedUrl] = useState<string>("");
29
  const [videoProcessing, setVideoProcessing] = useState(false);
30
  const [imageProcessed, setImageProcessed] = useState(false);
 
 
31
 
32
  const videoRef = useRef<HTMLVideoElement | null>(null);
33
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
@@ -109,9 +111,9 @@ export default function MultiSourceCaptioningView() {
109
  };
110
  }, [mode, isLoaded, prompt, runInference, webcamActive]);
111
 
112
- // Process video frames for URL mode (unchanged)
113
  useEffect(() => {
114
- if (mode !== "URL" || !isLoaded) return;
115
  let interval: ReturnType<typeof setInterval> | null = null;
116
  const processFrame = async () => {
117
  if (!videoRef.current || !canvasRef.current) return;
@@ -147,7 +149,7 @@ export default function MultiSourceCaptioningView() {
147
  return () => {
148
  if (interval) clearInterval(interval);
149
  };
150
- }, [mode, isLoaded, prompt, runInference]);
151
 
152
  // File mode: process uploaded image (only on button click)
153
  const handleProcessImage = async () => {
@@ -219,6 +221,46 @@ export default function MultiSourceCaptioningView() {
219
  };
220
  }, [mode, isLoaded, prompt, runInference, uploadedFile, videoProcessing]);
221
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  // Handle file upload
223
  const handleFileChange = (e: any) => {
224
  const file = e.target.files?.[0] || null;
@@ -227,6 +269,7 @@ export default function MultiSourceCaptioningView() {
227
  setError(null);
228
  setImageProcessed(false);
229
  setVideoProcessing(false);
 
230
  };
231
 
232
  // Handle start/stop for video processing
@@ -234,6 +277,16 @@ export default function MultiSourceCaptioningView() {
234
  setVideoProcessing((prev) => !prev);
235
  };
236
 
 
 
 
 
 
 
 
 
 
 
237
  return (
238
  <div className="absolute inset-0 text-white">
239
  <div className="flex flex-col items-center justify-center h-full w-full">
@@ -328,6 +381,12 @@ export default function MultiSourceCaptioningView() {
328
  className="absolute top-0 left-0 w-full h-full pointer-events-none"
329
  style={{ zIndex: 10, pointerEvents: "none" }}
330
  />
 
 
 
 
 
 
331
  </div>
332
  {processing && <div className="text-blue-400 mt-2">Processing frame...</div>}
333
  {error && <div className="text-red-400 mt-2">Error: {error}</div>}
@@ -418,6 +477,12 @@ export default function MultiSourceCaptioningView() {
418
  className="absolute top-0 left-0 w-full h-full pointer-events-none"
419
  style={{ zIndex: 10, pointerEvents: "none" }}
420
  />
 
 
 
 
 
 
421
  </div>
422
  )}
423
  {processing && <div className="text-blue-400 mt-2">Processing frame...</div>}
 
28
  const [uploadedUrl, setUploadedUrl] = useState<string>("");
29
  const [videoProcessing, setVideoProcessing] = useState(false);
30
  const [imageProcessed, setImageProcessed] = useState(false);
31
+ const [exampleProcessing, setExampleProcessing] = useState(false);
32
+ const [urlProcessing, setUrlProcessing] = useState(false);
33
 
34
  const videoRef = useRef<HTMLVideoElement | null>(null);
35
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
 
111
  };
112
  }, [mode, isLoaded, prompt, runInference, webcamActive]);
113
 
114
+ // URL mode: process video frames only when urlProcessing is true
115
  useEffect(() => {
116
+ if (mode !== "URL" || !isLoaded || !urlProcessing) return;
117
  let interval: ReturnType<typeof setInterval> | null = null;
118
  const processFrame = async () => {
119
  if (!videoRef.current || !canvasRef.current) return;
 
149
  return () => {
150
  if (interval) clearInterval(interval);
151
  };
152
+ }, [mode, isLoaded, prompt, runInference, urlProcessing]);
153
 
154
  // File mode: process uploaded image (only on button click)
155
  const handleProcessImage = async () => {
 
221
  };
222
  }, [mode, isLoaded, prompt, runInference, uploadedFile, videoProcessing]);
223
 
224
+ // File mode: process example video frames (start/stop)
225
+ useEffect(() => {
226
+ if (mode !== "File" || uploadedFile || !isLoaded || !exampleProcessing) return;
227
+ let interval: ReturnType<typeof setInterval> | null = null;
228
+ const processFrame = async () => {
229
+ if (!videoRef.current || !canvasRef.current) return;
230
+ const video = videoRef.current;
231
+ const canvas = canvasRef.current;
232
+ if (video.paused || video.ended || video.videoWidth === 0) return;
233
+ canvas.width = video.videoWidth;
234
+ canvas.height = video.videoHeight;
235
+ const ctx = canvas.getContext("2d");
236
+ if (!ctx) return;
237
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
238
+ try {
239
+ setProcessing(true);
240
+ setError(null);
241
+ const fakeVideo = {
242
+ videoWidth: canvas.width,
243
+ videoHeight: canvas.height,
244
+ getContext: () => ctx,
245
+ } as unknown as HTMLVideoElement;
246
+ const result = await runInference(fakeVideo, prompt);
247
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
248
+ const boxes = extractJsonFromMarkdown(result) || [];
249
+ drawBoundingBoxesOnCanvas(ctx, boxes);
250
+ } catch (e) {
251
+ setError(e instanceof Error ? e.message : String(e));
252
+ } finally {
253
+ setProcessing(false);
254
+ }
255
+ };
256
+ interval = setInterval(() => {
257
+ processFrame();
258
+ }, 1000);
259
+ return () => {
260
+ if (interval) clearInterval(interval);
261
+ };
262
+ }, [mode, isLoaded, prompt, runInference, uploadedFile, exampleProcessing]);
263
+
264
  // Handle file upload
265
  const handleFileChange = (e: any) => {
266
  const file = e.target.files?.[0] || null;
 
269
  setError(null);
270
  setImageProcessed(false);
271
  setVideoProcessing(false);
272
+ setExampleProcessing(false);
273
  };
274
 
275
  // Handle start/stop for video processing
 
277
  setVideoProcessing((prev) => !prev);
278
  };
279
 
280
+ // Handle start/stop for example video processing
281
+ const handleToggleExampleProcessing = () => {
282
+ setExampleProcessing((prev) => !prev);
283
+ };
284
+
285
+ // Handle start/stop for URL video processing
286
+ const handleToggleUrlProcessing = () => {
287
+ setUrlProcessing((prev) => !prev);
288
+ };
289
+
290
  return (
291
  <div className="absolute inset-0 text-white">
292
  <div className="flex flex-col items-center justify-center h-full w-full">
 
381
  className="absolute top-0 left-0 w-full h-full pointer-events-none"
382
  style={{ zIndex: 10, pointerEvents: "none" }}
383
  />
384
+ <button
385
+ className="mt-4 px-6 py-2 rounded-lg bg-blue-600 text-white font-semibold"
386
+ onClick={handleToggleUrlProcessing}
387
+ >
388
+ {urlProcessing ? "Stop Processing" : "Start Processing"}
389
+ </button>
390
  </div>
391
  {processing && <div className="text-blue-400 mt-2">Processing frame...</div>}
392
  {error && <div className="text-red-400 mt-2">Error: {error}</div>}
 
477
  className="absolute top-0 left-0 w-full h-full pointer-events-none"
478
  style={{ zIndex: 10, pointerEvents: "none" }}
479
  />
480
+ <button
481
+ className="mt-4 px-6 py-2 rounded-lg bg-blue-600 text-white font-semibold"
482
+ onClick={handleToggleExampleProcessing}
483
+ >
484
+ {exampleProcessing ? "Stop Processing" : "Start Processing"}
485
+ </button>
486
  </div>
487
  )}
488
  {processing && <div className="text-blue-400 mt-2">Processing frame...</div>}