【nodejs】视频压缩示例代码
const { spawn } = require("child_process");
const ffmpegPath = require("@ffmpeg-installer/ffmpeg").path;
const os = require('os')
function parseDuration(str) {
const match = str.match(/Duration: (\d+):(\d+):(\d+\.\d+)/);
if (!match) return 0;
const [, h, m, s] = match;
return Number(h) * 3600 + Number(m) * 60 + Number(s);
}
function parseTime(str) {
const match = str.match(/time=(\d+):(\d+):(\d+\.\d+)/);
if (!match) return 0;
const [, h, m, s] = match;
return Number(h) * 3600 + Number(m) * 60 + Number(s);
}
function compressVideo(input, output, onProgress) {
return new Promise((resolve, reject) => {
let totalDuration = 0;
const threads = os.cpus().length;
console.log('线程数:', threads)
const useThreads = threads / 2
const args = [
"-i", input,
"-vf", "scale='min(1280,iw)':-2",
"-c:v", "libx265",
"-crf", "23",
"-preset", "fast",
"-c:a", "aac",
"-b:a", "128k",
"-y",
"-threads", useThreads, // 使用所有线程压缩视频
output,
];
const child = spawn(ffmpegPath, args);
child.stderr.on("data", (data) => {
const text = data.toString();
// 获取总时长
if (!totalDuration && text.includes("Duration")) {
totalDuration = parseDuration(text);
}
// 获取当前进度
if (text.includes("time=")) {
const current = parseTime(text);
if (totalDuration > 0) {
const percent = ((current / totalDuration) * 100).toFixed(2);
onProgress && onProgress(percent);
}
}
// 输出日志(可注释)
// console.log(text);
});
child.on("close", (code) => {
if (code === 0) resolve("视频压缩完成:" + output);
else reject(new Error("压缩失败,退出码:" + code));
});
child.on("error", reject);
});
}
// CLI 模式
if (require.main === module) {
const [, , input, output] = process.argv;
if (!input || !output) {
console.log("用法:node main.js input.mp4 output.mp4");
process.exit(1);
}
// const os = require('os');
// console.log("CPU 信息:", os.cpus());
// console.log("物理内核数:", os.cpus().length / 2); // 如果 CPU 支持超线程,大约是逻辑核数的一半
// console.log("逻辑核数:", os.cpus().length);
// console.log("CPU 架构:", os.arch());
// console.log("操作系统:", os.platform(), os.release());
const time = Date.now()
compressVideo(
input,
output,
(percent) => console.log("进度:", percent + "%")
)
.then(console.log)
.catch(console.error)
.finally(() => {
const now = Date.now()
console.log(`总耗时:${(now - time) / 1000} 秒`)
})
}
module.exports = compressVideo;
使用方式:
node main.js input.mp4 output.mp4
许可协议:
CC BY 4.0