From 7d1b5ceb0d79ab8428750f68e7f105bf662696b0 Mon Sep 17 00:00:00 2001 From: Shubbu03 Date: Mon, 23 Jun 2025 22:10:15 +0530 Subject: [PATCH 1/3] Completed the getVideoInfo func according to the comment specified --- apps/web/src/lib/ffmpeg-utils.ts | 52 ++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/apps/web/src/lib/ffmpeg-utils.ts b/apps/web/src/lib/ffmpeg-utils.ts index 56085a2..de203fd 100644 --- a/apps/web/src/lib/ffmpeg-utils.ts +++ b/apps/web/src/lib/ffmpeg-utils.ts @@ -102,26 +102,52 @@ export const getVideoInfo = async (videoFile: File): Promise<{ fps: number; }> => { const ffmpeg = await initFFmpeg(); - + const inputName = 'input.mp4'; - + // Write input file await ffmpeg.writeFile(inputName, new Uint8Array(await videoFile.arrayBuffer())); - - // Get video info + + // Capture FFmpeg stderr output + let ffmpegOutput = ''; + const listener = (data: string) => { + ffmpegOutput += data; + }; + ffmpeg.on('log', ({ message }) => listener(message)); + + // Run ffmpeg to get info (stderr will contain the info) await ffmpeg.exec(['-i', inputName, '-f', 'null', '-']); - - // Note: In a real implementation, you'd parse the FFmpeg output - // For now, we'll return default values and enhance this later - + + // Remove listener + // (No off() method in ffmpeg.wasm, so this is a no-op, but included for clarity) + // Cleanup await ffmpeg.deleteFile(inputName); - + + // Parse output for duration, resolution, and fps + // Example: Duration: 00:00:10.00, start: 0.000000, bitrate: 1234 kb/s + // Example: Stream #0:0: Video: h264 (High), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc + + const durationMatch = ffmpegOutput.match(/Duration: (\d+):(\d+):([\d.]+)/); + let duration = 0; + if (durationMatch) { + const [, h, m, s] = durationMatch; + duration = parseInt(h) * 3600 + parseInt(m) * 60 + parseFloat(s); + } + + const videoStreamMatch = ffmpegOutput.match(/Video:.* (\d+)x(\d+)[^,]*, ([\d.]+) fps/); + let width = 0, height = 0, fps = 0; + if (videoStreamMatch) { + width = parseInt(videoStreamMatch[1]); + height = parseInt(videoStreamMatch[2]); + fps = parseFloat(videoStreamMatch[3]); + } + return { - duration: 10, // Placeholder - would parse from FFmpeg output - width: 1920, // Placeholder - height: 1080, // Placeholder - fps: 30 // Placeholder + duration, + width, + height, + fps }; }; From 327196356c56361136fbed740addcf52813d3933 Mon Sep 17 00:00:00 2001 From: Shubbu03 Date: Mon, 23 Jun 2025 22:22:43 +0530 Subject: [PATCH 2/3] code-rabbit suggested fixes --- apps/web/src/lib/ffmpeg-utils.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/web/src/lib/ffmpeg-utils.ts b/apps/web/src/lib/ffmpeg-utils.ts index de203fd..1fd6ce6 100644 --- a/apps/web/src/lib/ffmpeg-utils.ts +++ b/apps/web/src/lib/ffmpeg-utils.ts @@ -108,18 +108,19 @@ export const getVideoInfo = async (videoFile: File): Promise<{ // Write input file await ffmpeg.writeFile(inputName, new Uint8Array(await videoFile.arrayBuffer())); - // Capture FFmpeg stderr output + // Capture FFmpeg stderr output with a one-time listener pattern let ffmpegOutput = ''; + let listening = true; const listener = (data: string) => { - ffmpegOutput += data; + if (listening) ffmpegOutput += data; }; ffmpeg.on('log', ({ message }) => listener(message)); // Run ffmpeg to get info (stderr will contain the info) await ffmpeg.exec(['-i', inputName, '-f', 'null', '-']); - // Remove listener - // (No off() method in ffmpeg.wasm, so this is a no-op, but included for clarity) + // Disable listener after exec completes + listening = false; // Cleanup await ffmpeg.deleteFile(inputName); @@ -220,4 +221,4 @@ export const extractAudio = async ( await ffmpeg.deleteFile(outputName); return blob; -}; \ No newline at end of file +}; \ No newline at end of file From 6a701ee8c064a4652db475c93ee89c3ffe112986 Mon Sep 17 00:00:00 2001 From: Shubbu03 Date: Mon, 23 Jun 2025 22:22:43 +0530 Subject: [PATCH 3/3] better error handling --- apps/web/src/lib/ffmpeg-utils.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/web/src/lib/ffmpeg-utils.ts b/apps/web/src/lib/ffmpeg-utils.ts index de203fd..ae0c267 100644 --- a/apps/web/src/lib/ffmpeg-utils.ts +++ b/apps/web/src/lib/ffmpeg-utils.ts @@ -108,18 +108,26 @@ export const getVideoInfo = async (videoFile: File): Promise<{ // Write input file await ffmpeg.writeFile(inputName, new Uint8Array(await videoFile.arrayBuffer())); - // Capture FFmpeg stderr output + // Capture FFmpeg stderr output with a one-time listener pattern let ffmpegOutput = ''; + let listening = true; const listener = (data: string) => { - ffmpegOutput += data; + if (listening) ffmpegOutput += data; }; ffmpeg.on('log', ({ message }) => listener(message)); // Run ffmpeg to get info (stderr will contain the info) - await ffmpeg.exec(['-i', inputName, '-f', 'null', '-']); + try { + await ffmpeg.exec(['-i', inputName, '-f', 'null', '-']); + } catch (error) { + listening = false; + await ffmpeg.deleteFile(inputName); + console.error('FFmpeg execution failed:', error); + throw new Error('Failed to extract video info. The file may be corrupted or in an unsupported format.'); + } - // Remove listener - // (No off() method in ffmpeg.wasm, so this is a no-op, but included for clarity) + // Disable listener after exec completes + listening = false; // Cleanup await ffmpeg.deleteFile(inputName); @@ -220,4 +228,4 @@ export const extractAudio = async ( await ffmpeg.deleteFile(outputName); return blob; -}; \ No newline at end of file +}; \ No newline at end of file