avatar

林间有风

人类用沙想捏出梦里通天塔

  • 首页
  • AI
  • 前端
  • 客户端
  • 后端
主页 【nodejs】视频压缩示例代码
文章

【nodejs】视频压缩示例代码

发表于 3天前 更新于 3天前
作者 林间有风
6~7 分钟 阅读
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
分享

相关文章

12月 12, 2025

【nodejs】视频压缩示例代码

const { spawn } = require("child_process"); const ffmpegPath = require("@ffmpeg-installer/ffmpeg").path; const os = require('os') function parseDurat

12月 5, 2025

【nest】nest+jest单元测试规范

版本:v1.0 适用范围:NestJS/nodejs企业后端项目 目标:提高可维护性、可测试性、系统稳定性 1. 测试总体要求 项目必须包含 Unit Test(单元测试)、E2E Test(端到端测试)。 必须使用 Jest 作为统一测试框架。 所有业务逻辑必须可测试、可 Mock。 合并进主分支

12月 2, 2025

【nest】TypeORM数据库迁移脚本配置

一、安装必要依赖 pnpm install --save @nestjs/typeorm typeorm mysql2 pnpm install dotenv -D 二、创建配置文件 // src/config/typeorm.config.ts import { config } from 'd

下一篇

【nest】nest+jest单元测试规范

上一篇

最近更新

  • 【nodejs】视频压缩示例代码
  • 【nest】nest+jest单元测试规范
  • 【nest】TypeORM数据库迁移脚本配置
  • 【Agent Prompt】nest项目
  • 【docker】开发环境部署

热门标签

jest swift swift 视频压缩 mysql docker nest migration flutter 单元测试

目录

©2025 林间有风. 保留部分权利。

使用 Halo 主题 Chirpy