From 188ba94aad9ed2bf0ae8b95c34d80f8caa8fdb86 Mon Sep 17 00:00:00 2001 From: Siddharth Date: Mon, 24 Nov 2025 17:11:37 -0700 Subject: [PATCH] test win codec fix --- dist-electron/main.js | 24 ++------- electron/ipc/handlers.ts | 16 +----- electron/main.ts | 9 ++-- package-lock.json | 55 +++++++++++++++++++-- package.json | 3 +- src/components/video-editor/VideoEditor.tsx | 10 ---- src/lib/exporter/videoExporter.ts | 34 +++++++++++-- 7 files changed, 94 insertions(+), 57 deletions(-) diff --git a/dist-electron/main.js b/dist-electron/main.js index cf3ccf3..7c61531 100644 --- a/dist-electron/main.js +++ b/dist-electron/main.js @@ -143,18 +143,14 @@ function registerIpcHandlers(createEditorWindow2, createSourceSelectorWindow2, g ipcMain.handle("store-recorded-video", async (_, videoData, fileName) => { try { const videoPath = path.join(RECORDINGS_DIR, fileName); - console.log("[STORE-VIDEO] Saving to:", videoPath); - console.log("[STORE-VIDEO] RECORDINGS_DIR:", RECORDINGS_DIR); - console.log("[STORE-VIDEO] Platform:", process.platform); await fs.writeFile(videoPath, Buffer.from(videoData)); - console.log("[STORE-VIDEO] Success! File size:", Buffer.from(videoData).length, "bytes"); return { success: true, path: videoPath, message: "Video stored successfully" }; } catch (error) { - console.error("[STORE-VIDEO] Failed to store video:", error); + console.error("Failed to store video:", error); return { success: false, message: "Failed to store video", @@ -164,23 +160,16 @@ function registerIpcHandlers(createEditorWindow2, createSourceSelectorWindow2, g }); ipcMain.handle("get-recorded-video-path", async () => { try { - console.log("[GET-VIDEO] RECORDINGS_DIR:", RECORDINGS_DIR); - console.log("[GET-VIDEO] Platform:", process.platform); const files = await fs.readdir(RECORDINGS_DIR); - console.log("[GET-VIDEO] All files:", files); const videoFiles = files.filter((file) => file.endsWith(".webm")); - console.log("[GET-VIDEO] Video files:", videoFiles); if (videoFiles.length === 0) { - console.log("[GET-VIDEO] No video files found"); return { success: false, message: "No recorded video found" }; } const latestVideo = videoFiles.sort().reverse()[0]; const videoPath = path.join(RECORDINGS_DIR, latestVideo); - console.log("[GET-VIDEO] Latest video path:", videoPath); - console.log("[GET-VIDEO] Path separators:", videoPath.includes("\\") ? "backslash" : "forward slash"); return { success: true, path: videoPath }; } catch (error) { - console.error("[GET-VIDEO] Failed to get video path:", error); + console.error("Failed to get video path:", error); return { success: false, message: "Failed to get video path", error: String(error) }; } }); @@ -252,13 +241,10 @@ async function cleanupOldRecordings() { async function ensureRecordingsDir() { try { await fs.mkdir(RECORDINGS_DIR, { recursive: true }); - console.log("=".repeat(60)); - console.log("[STARTUP] Platform:", process.platform); - console.log("[STARTUP] RECORDINGS_DIR:", RECORDINGS_DIR); - console.log("[STARTUP] User Data Path:", app.getPath("userData")); - console.log("=".repeat(60)); + console.log("RECORDINGS_DIR:", RECORDINGS_DIR); + console.log("User Data Path:", app.getPath("userData")); } catch (error) { - console.error("[STARTUP] Failed to create recordings directory:", error); + console.error("Failed to create recordings directory:", error); } } process.env.APP_ROOT = path.join(__dirname, ".."); diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index 2ef34c1..5f92ed3 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -59,19 +59,14 @@ export function registerIpcHandlers( ipcMain.handle('store-recorded-video', async (_, videoData: ArrayBuffer, fileName: string) => { try { const videoPath = path.join(RECORDINGS_DIR, fileName) - console.log('[STORE-VIDEO] Saving to:', videoPath) - console.log('[STORE-VIDEO] RECORDINGS_DIR:', RECORDINGS_DIR) - console.log('[STORE-VIDEO] Platform:', process.platform) await fs.writeFile(videoPath, Buffer.from(videoData)) - console.log('[STORE-VIDEO] Success! File size:', Buffer.from(videoData).length, 'bytes') - return { success: true, path: videoPath, message: 'Video stored successfully' } } catch (error) { - console.error('[STORE-VIDEO] Failed to store video:', error) + console.error('Failed to store video:', error) return { success: false, message: 'Failed to store video', @@ -84,26 +79,19 @@ export function registerIpcHandlers( ipcMain.handle('get-recorded-video-path', async () => { try { - console.log('[GET-VIDEO] RECORDINGS_DIR:', RECORDINGS_DIR) - console.log('[GET-VIDEO] Platform:', process.platform) const files = await fs.readdir(RECORDINGS_DIR) - console.log('[GET-VIDEO] All files:', files) const videoFiles = files.filter(file => file.endsWith('.webm')) - console.log('[GET-VIDEO] Video files:', videoFiles) if (videoFiles.length === 0) { - console.log('[GET-VIDEO] No video files found') return { success: false, message: 'No recorded video found' } } const latestVideo = videoFiles.sort().reverse()[0] const videoPath = path.join(RECORDINGS_DIR, latestVideo) - console.log('[GET-VIDEO] Latest video path:', videoPath) - console.log('[GET-VIDEO] Path separators:', videoPath.includes('\\') ? 'backslash' : 'forward slash') return { success: true, path: videoPath } } catch (error) { - console.error('[GET-VIDEO] Failed to get video path:', error) + console.error('Failed to get video path:', error) return { success: false, message: 'Failed to get video path', error: String(error) } } }) diff --git a/electron/main.ts b/electron/main.ts index 95ca4aa..8a7fdb9 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -34,13 +34,10 @@ async function cleanupOldRecordings() { async function ensureRecordingsDir() { try { await fs.mkdir(RECORDINGS_DIR, { recursive: true }) - console.log('='.repeat(60)) - console.log('[STARTUP] Platform:', process.platform) - console.log('[STARTUP] RECORDINGS_DIR:', RECORDINGS_DIR) - console.log('[STARTUP] User Data Path:', app.getPath('userData')) - console.log('='.repeat(60)) + console.log('RECORDINGS_DIR:', RECORDINGS_DIR) + console.log('User Data Path:', app.getPath('userData')) } catch (error) { - console.error('[STARTUP] Failed to create recordings directory:', error) + console.error('Failed to create recordings directory:', error) } } diff --git a/package-lock.json b/package-lock.json index f87cfe3..0cc70cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", + "@uiw/color-convert": "^2.9.2", "@uiw/react-color-colorful": "^2.9.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -3728,9 +3729,9 @@ } }, "node_modules/@uiw/color-convert": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.0.tgz", - "integrity": "sha512-tFm6iac8iN3VL9IIAXKAVpBX6ZQH7ucCvb+EgZNM5y8prRWlk53cERnP4RycE3wnYb/HUKW0lrngoygQnEWAHg==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.2.tgz", + "integrity": "sha512-ibw9OS29S7GlL+vDwU3p5XG3vhR7XdzUecydpZbakUeg2Td6nfsnrCAX9sbLwQ73p0abO42v+V4qRaWq+7/BjQ==", "license": "MIT", "funding": { "url": "https://jaywcjlove.github.io/#/sponsor" @@ -3757,6 +3758,18 @@ "react-dom": ">=16.9.0" } }, + "node_modules/@uiw/react-color-alpha/node_modules/@uiw/color-convert": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.0.tgz", + "integrity": "sha512-tFm6iac8iN3VL9IIAXKAVpBX6ZQH7ucCvb+EgZNM5y8prRWlk53cERnP4RycE3wnYb/HUKW0lrngoygQnEWAHg==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, "node_modules/@uiw/react-color-colorful": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/@uiw/react-color-colorful/-/react-color-colorful-2.9.0.tgz", @@ -3777,6 +3790,18 @@ "react-dom": ">=16.9.0" } }, + "node_modules/@uiw/react-color-colorful/node_modules/@uiw/color-convert": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.0.tgz", + "integrity": "sha512-tFm6iac8iN3VL9IIAXKAVpBX6ZQH7ucCvb+EgZNM5y8prRWlk53cERnP4RycE3wnYb/HUKW0lrngoygQnEWAHg==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, "node_modules/@uiw/react-color-hue": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/@uiw/react-color-hue/-/react-color-hue-2.9.0.tgz", @@ -3795,6 +3820,18 @@ "react-dom": ">=16.9.0" } }, + "node_modules/@uiw/react-color-hue/node_modules/@uiw/color-convert": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.0.tgz", + "integrity": "sha512-tFm6iac8iN3VL9IIAXKAVpBX6ZQH7ucCvb+EgZNM5y8prRWlk53cERnP4RycE3wnYb/HUKW0lrngoygQnEWAHg==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, "node_modules/@uiw/react-color-saturation": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/@uiw/react-color-saturation/-/react-color-saturation-2.9.0.tgz", @@ -3813,6 +3850,18 @@ "react-dom": ">=16.9.0" } }, + "node_modules/@uiw/react-color-saturation/node_modules/@uiw/color-convert": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.0.tgz", + "integrity": "sha512-tFm6iac8iN3VL9IIAXKAVpBX6ZQH7ucCvb+EgZNM5y8prRWlk53cERnP4RycE3wnYb/HUKW0lrngoygQnEWAHg==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, "node_modules/@uiw/react-drag-event-interactive": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/@uiw/react-drag-event-interactive/-/react-drag-event-interactive-2.9.0.tgz", diff --git a/package.json b/package.json index 6f6568f..17563dd 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", + "@uiw/color-convert": "^2.9.2", "@uiw/react-color-colorful": "^2.9.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -58,4 +59,4 @@ "vite-plugin-electron-renderer": "^0.14.5" }, "main": "dist-electron/main.js" -} \ No newline at end of file +} diff --git a/src/components/video-editor/VideoEditor.tsx b/src/components/video-editor/VideoEditor.tsx index a3c6501..c793034 100644 --- a/src/components/video-editor/VideoEditor.tsx +++ b/src/components/video-editor/VideoEditor.tsx @@ -49,41 +49,32 @@ export default function VideoEditor() { // Helper to convert file path to proper file:// URL const toFileUrl = (filePath: string): string => { - console.log('[VIDEO-EDITOR] Converting path to URL:', filePath); // Normalize path separators to forward slashes const normalized = filePath.replace(/\\/g, '/'); - console.log('[VIDEO-EDITOR] Normalized path:', normalized); // Check if it's a Windows absolute path (e.g., C:/Users/...) if (normalized.match(/^[a-zA-Z]:/)) { const fileUrl = `file:///${normalized}`; - console.log('[VIDEO-EDITOR] Windows file URL:', fileUrl); return fileUrl; } // Unix-style absolute path const fileUrl = `file://${normalized}`; - console.log('[VIDEO-EDITOR] Unix file URL:', fileUrl); return fileUrl; }; useEffect(() => { async function loadVideo() { try { - console.log('[VIDEO-EDITOR] Loading video...'); const result = await window.electronAPI.getRecordedVideoPath(); - console.log('[VIDEO-EDITOR] getRecordedVideoPath result:', result); if (result.success && result.path) { const videoUrl = toFileUrl(result.path); - console.log('[VIDEO-EDITOR] Setting video path:', videoUrl); setVideoPath(videoUrl); } else { - console.error('[VIDEO-EDITOR] Failed to get video path:', result.message); setError(result.message || 'Failed to load video'); } } catch (err) { - console.error('[VIDEO-EDITOR] Error loading video:', err); setError('Error loading video: ' + String(err)); } finally { setLoading(false); @@ -95,7 +86,6 @@ export default function VideoEditor() { function togglePlayPause() { const playback = videoPlaybackRef.current; const video = playback?.video; - console.log('Toggle play/pause:', { hasVideo: !!video, isPlaying, action: isPlaying ? 'pause' : 'play' }); if (!playback || !video) return; if (isPlaying) { diff --git a/src/lib/exporter/videoExporter.ts b/src/lib/exporter/videoExporter.ts index e2dcf17..f4e3cdb 100644 --- a/src/lib/exporter/videoExporter.ts +++ b/src/lib/exporter/videoExporter.ts @@ -205,7 +205,7 @@ export class VideoExporter { const metadata: EncodedVideoChunkMetadata = { decoderConfig: { - codec: this.config.codec || 'avc1.640033', + codec: this.config.codec || 'avc1.64001f', codedWidth: this.config.width, codedHeight: this.config.height, description: this.videoDescription, @@ -230,9 +230,9 @@ export class VideoExporter { }, }); - const codec = this.config.codec || 'avc1.640033'; + const codec = this.config.codec || 'avc1.64001f'; - this.encoder.configure({ + const encoderConfig: VideoEncoderConfig = { codec, width: this.config.width, height: this.config.height, @@ -241,7 +241,33 @@ export class VideoExporter { latencyMode: 'realtime', bitrateMode: 'variable', hardwareAcceleration: 'prefer-hardware', - } as VideoEncoderConfig); + }; + + try { + console.log('[VideoExporter] Configuring encoder with hardware acceleration...', { + codec, + resolution: `${this.config.width}x${this.config.height}`, + bitrate: this.config.bitrate, + framerate: this.config.frameRate, + }); + + this.encoder.configure(encoderConfig as VideoEncoderConfig); + + console.log('[VideoExporter] Hardware encoder configured successfully'); + } catch (error) { + console.warn('[VideoExporter] Hardware encoding failed, falling back to software encoding...', error); + + // Fallback to software encoding if hardware fails + encoderConfig.hardwareAcceleration = 'prefer-software'; + + try { + this.encoder.configure(encoderConfig as VideoEncoderConfig); + console.log('[VideoExporter] Software encoder configured successfully'); + } catch (softwareError) { + console.error('[VideoExporter] Software encoding also failed:', softwareError); + throw new Error(`Failed to initialize video encoder: ${softwareError instanceof Error ? softwareError.message : String(softwareError)}`); + } + } } cancel(): void {