From 957bb7ff2ff97b18152df05b24bc51c60d97a476 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Thu, 13 Nov 2025 13:26:27 +0700 Subject: [PATCH] dont load videos as blobs --- .../VideoFrameExtractor.tsx | 56 +++++++++++++------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/frontend/apps/editor3d/app/src/pages/PageVideoFrameExtractor/VideoFrameExtractor.tsx b/frontend/apps/editor3d/app/src/pages/PageVideoFrameExtractor/VideoFrameExtractor.tsx index eff2da548b..312e7851fb 100644 --- a/frontend/apps/editor3d/app/src/pages/PageVideoFrameExtractor/VideoFrameExtractor.tsx +++ b/frontend/apps/editor3d/app/src/pages/PageVideoFrameExtractor/VideoFrameExtractor.tsx @@ -53,6 +53,7 @@ export const VideoFrameExtractor = () => { const [convertingFrames, setConvertingFrames] = useState>( new Set(), ); + const [isLoadingFromGallery, setIsLoadingFromGallery] = useState(false); const videoRef = useRef(null); const fileInputRef = useRef(null); @@ -151,9 +152,20 @@ export const VideoFrameExtractor = () => { const handleGallerySelect = async (selectedItems: GalleryItem[]) => { const item = selectedItems[0]; if (!item || !item.fullImage) { + toast.error("No video selected"); return; } + if (isLoadingFromGallery) { + return; + } + + setIsLoadingFromGallery(true); + + if (videoUrl && videoUrl.startsWith("blob:")) { + URL.revokeObjectURL(videoUrl); + } + setIsPlaying(false); setCurrentTime(0); setStartTime(0); @@ -162,24 +174,11 @@ export const VideoFrameExtractor = () => { setSavingFrames(new Set()); setSavedFrames(new Set()); setConvertingFrames(new Set()); - - try { - const response = await fetch(item.fullImage); - const blob = await response.blob(); - const blobUrl = URL.createObjectURL(blob); - - if (videoUrl && videoUrl.startsWith("blob:")) { - URL.revokeObjectURL(videoUrl); - } - - setVideoUrl(blobUrl); - } catch (error) { - console.error("Failed to load video from library:", error); - setVideoUrl(item.fullImage); - } + setVideoUrl(item.fullImage); setIsGalleryModalOpen(false); setSelectedGalleryVideos([]); + setIsLoadingFromGallery(false); }; const togglePlayPause = () => { @@ -285,6 +284,7 @@ export const VideoFrameExtractor = () => { canvas.height = video.videoHeight; const frames: { id: string; url: string; timestamp: number }[] = []; + let corsError = false; for (let i = 0; i < numFrames; i++) { const timestamp = startTime + (i * frameDistance) / 1000; @@ -306,6 +306,9 @@ export const VideoFrameExtractor = () => { }); } catch (error) { console.error("Error extracting frame:", error); + if (error instanceof Error && error.name === "SecurityError") { + corsError = true; + } } video.removeEventListener("seeked", handleSeeked); @@ -314,6 +317,8 @@ export const VideoFrameExtractor = () => { video.addEventListener("seeked", handleSeeked, { once: true }); }); + + if (corsError) break; } video.currentTime = originalTime; @@ -330,6 +335,20 @@ export const VideoFrameExtractor = () => { video.play(); } + if (corsError) { + toast.error( + "CORS error: Cannot extract frames from this video. Try uploading the video file directly instead.", + ); + setIsExtracting(false); + return; + } + + if (frames.length === 0) { + toast.error("Failed to extract any frames"); + setIsExtracting(false); + return; + } + setExtractedFrames(frames); setIsExtracting(false); @@ -547,6 +566,7 @@ export const VideoFrameExtractor = () => { onClick={togglePlayPause} preload="metadata" playsInline + crossOrigin="anonymous" />
{ { - setIsGalleryModalOpen(false); - setSelectedGalleryVideos([]); + if (!isLoadingFromGallery) { + setIsGalleryModalOpen(false); + setSelectedGalleryVideos([]); + } }} mode="select" selectedItemIds={selectedGalleryVideos}