如何使用node-ffmpeg在NodeJS中压缩MP4视频体积?
Hey there, I get your frustration—sometimes npm FFmpeg wrappers can have confusing parameter mappings, especially when docs are sparse. Let’s break down two solid approaches to replicate that exact native FFmpeg command in your Node.js app:
Option 1: Use Node.js child_process to Run the Exact Native Command
This is the most straightforward way since you’re directly executing the same command you know works. No wrapper layers to introduce unexpected issues.
First, make sure FFmpeg is installed on your system and available in your PATH (or you can specify the full path to the FFmpeg executable).
Here’s a complete example:
const { exec } = require('child_process'); function compressVideo(inputPath, outputPath) { // Your exact native command, with quotes to handle paths with spaces const ffmpegCommand = `ffmpeg -i "${inputPath}" -s 640x480 -b:v 512k -vcodec mpeg1video -acodec copy "${outputPath}"`; exec(ffmpegCommand, (error, stdout, stderr) => { if (error) { console.error(`Compression failed: ${error.message}`); return; } if (stderr) { console.warn(`FFmpeg runtime notes: ${stderr}`); return; } console.log(`Video compressed successfully! Output at: ${outputPath}`); }); } // Usage example compressVideo('./input.mp4', './compressed_output.mp4');
Quick Notes:
- Wrap file paths in double quotes (
") to avoid issues with spaces in filenames or directories. - For real-time progress tracking or handling large files, swap
execwithspawn—it streams output instead of buffering everything at once.
Option 2: Fix fluent-ffmpeg Parameter Configuration
If you prefer using a wrapper library, the issue with your previous attempt was likely incorrect parameter formatting. Let’s map each part of your native command directly to fluent-ffmpeg’s API:
First, install fluent-ffmpeg if you haven’t:
npm install fluent-ffmpeg
Then here’s the correct implementation:
const ffmpeg = require('fluent-ffmpeg'); // Optional: Specify FFmpeg path if it's not in your system PATH // ffmpeg.setFfmpegPath('/usr/local/bin/ffmpeg'); function compressVideoWithFluent(inputPath, outputPath) { ffmpeg(inputPath) .size('640x480') // Matches the `-s 640x480` flag .videoBitrate('512k') // Maps to `-b:v 512k` .videoCodec('mpeg1video') // Corresponds to `-vcodec mpeg1video` .audioCodec('copy') // Reuses original audio stream, same as `-acodec copy` .save(outputPath) .on('end', () => { console.log(`Video compressed successfully! Output at: ${outputPath}`); }) .on('error', (err) => { console.error(`Compression failed: ${err.message}`); }); } // Usage example compressVideoWithFluent('./input.mp4', './compressed_output.mp4');
Why This Works:
.size('640x480')needs to be a string with no extra spaces or units—this was probably the issue with your earlier attempt..audioCodec('copy')skips re-encoding the audio, just like your native command, which saves time and preserves quality.
Critical Prerequisite
Whichever approach you pick, FFmpeg must be installed on your system. For servers, install it via your package manager (e.g., apt install ffmpeg on Ubuntu, brew install ffmpeg on macOS).
内容的提问来源于stack exchange,提问作者Chanaka De Silva

