npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@evio/ffai

v1.0.7

Published

一个基于 FFmpeg 的命令行工具,用于批量处理视频和音频文件,支持视频转码、音频合并、字幕添加等功能。

Downloads

785

Readme

FFmpeg 视频处理工具

一个基于 FFmpeg 的命令行工具,用于批量处理视频和音频文件,支持视频转码、音频合并、字幕添加等功能。适用于自动化视频制作、批量视频处理等场景。

✨ 功能特性

  • 🎬 批量视频转码和拼接 - 支持多种视频格式转换为 MP4,自动拼接多个视频片段
  • 🎵 多音频文件混音 - 将多个音频文件混合为一个音轨,支持 glob 模式批量处理
  • 📝 自动添加字幕 - 支持自定义时间格式的字幕文件,自动渲染到视频上
  • 🎲 智能视频选择 - 随机模式根据音频时长智能选择视频片段,避免重复
  • 📦 Glob 模式匹配 - 灵活的文件匹配模式,支持通配符批量处理
  • ⚙️ JSON 配置管理 - 基于配置文件的任务管理,支持批量任务处理
  • 🔄 自动化工作流 - 一键完成从素材到成品的全流程处理

📋 前置要求

  • Node.js >= 14.0.0
  • FFmpeg - 必须在系统中安装并配置到环境变量

安装 FFmpeg

macOS:

brew install ffmpeg

Ubuntu/Debian:

sudo apt update
sudo apt install ffmpeg

Windows:FFmpeg 官网 下载并配置环境变量

🚀 快速开始

安装

# 克隆项目
git clone <repository-url>
cd <project-directory>

# 安装依赖
npm install

# 构建项目
npm run build

# 全局安装(可选)
npm link

基本使用

# 执行任务配置文件
ffai build task.json

📖 详细使用说明

任务配置文件

创建一个 JSON 配置文件来定义处理任务,支持多个任务批量执行:

[
  {
    "audios": ["audio1.mp3", "audio2.mp3"],
    "videos": "videos/*.mp4",
    "narration": "subtitle.txt",
    "videoTranscodeable": true,
    "videoPackMode": "random"
  },
  {
    "audios": "bgm/*.mp3",
    "videos": ["clip1.mp4", "clip2.mp4"],
    "narration": "subtitle2.txt",
    "videoPackMode": "all"
  }
]

配置参数详解

| 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | audios | string \| string[] | ✅ | 音频文件路径,支持数组或 glob 模式(如 bgm/*.mp3⚠️ 重要:如果是数组,最终音频时长由第一个音频文件决定,其他音频会被混音叠加 | | videos | string \| string[] | ✅ | 视频文件路径,支持数组或 glob 模式(如 videos/*.mp4) | | narration | string | ✅ | 字幕文件路径,使用自定义时间格式 | | videoTranscodeable | boolean | ❌ | 是否对视频进行转码,默认 false。启用后会将所有视频统一转码为 H.264/AAC 格式 | | videoPackMode | 'random' \| 'all' | ❌ | 视频打包模式,默认 'all'- random: 根据音频时长随机选择视频片段- all: 使用所有视频文件 | | fontFile | string | ❌ | 自定义字幕字体文件路径。如果不指定,macOS 默认使用宋体,其他系统需要提供字体路径 |

字幕文件格式

字幕文件使用简化的时间格式,每行一条字幕:

00:05-00:10 这是第一条字幕
00:12-00:18 这是第二条字幕
00:20-00:25 支持中文和英文
01:30-01:45 时间可以跨分钟

格式说明:

  • 时间格式:MM:SS-MM:SS 字幕内容
  • 开始时间和结束时间用 - 分隔
  • 时间和文本之间用空格分隔
  • 支持跨分钟的时间范围

字幕样式:

  • 字体大小:36px
  • 字体颜色:白色
  • 文字效果:黑色描边 + 阴影,确保在任何背景下清晰可见
  • 位置:视频底部居中(距底部 300px)
  • 字体:可通过 fontFile 参数自定义,如果不指定则使用系统默认字体

跨平台字体路径参考:

  • macOS: /System/Library/Fonts/Supplemental/Songti.ttc(宋体)
  • Windows: C:/Windows/Fonts/simhei.ttf(黑体)或 C:/Windows/Fonts/msyh.ttc(微软雅黑)
  • Linux: /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc(文泉驿正黑)

🔄 工作流程

工具会按以下步骤自动处理每个任务:

  1. 检查 FFmpeg - 验证 FFmpeg 是否可用
  2. 解析配置 - 读取任务配置文件,支持数组形式的多任务
  3. 解析素材文件 - 根据 glob 模式或数组匹配音频和视频文件
  4. 视频转码(可选)- 将视频统一转码为 MP4 格式(H.264 + AAC,44.1kHz,立体声)
  5. 获取时长信息 - 分析所有音频和视频的播放时长
  6. 音频混音 - 将多个音频文件混合为一个音轨(以第一个音频时长为准)
  7. 视频选择 - 根据 videoPackMode 选择视频片段:
    • random 模式:随机选择视频直到总时长 ≥ 音频时长
    • all 模式:使用所有视频文件
  8. 视频拼接 - 将选中的视频片段拼接成完整视频
  9. 添加音频 - 为视频添加混音后的背景音频(使用 -shortest 参数自动对齐)
  10. 渲染字幕 - 将字幕渲染到视频上(白色文字 + 黑色描边阴影)
  11. 清理临时文件 - 删除中间过程文件,保留最终成品
  12. 输出成品 - 生成最终视频文件到 task-{index}/video.mp4

处理时间估算:

  • 视频转码:取决于视频数量和时长,通常为实际播放时长的 0.5-2 倍
  • 音频混音:通常在几秒内完成
  • 视频拼接:较快,通常在 10 秒内
  • 字幕渲染:取决于视频时长,通常为实际播放时长的 1-3 倍

📂 输出结构

每个任务会在当前目录下创建 task-{index} 文件夹:

task-0/
├── videos/          # 转码后的视频文件(如果启用 videoTranscodeable)
│   ├── 1.mp4
│   ├── 2.mp4
│   └── ...
├── tmp/             # 临时文件目录
├── audio.mp3        # 混音后的音频文件
└── video.mp4        # 最终输出的视频文件 ⭐

💡 使用示例

示例 1:随机视频片段 + 多音频混音

[
  {
    "audios": ["bgm/music1.mp3", "bgm/music2.mp3"],
    "videos": "clips/*.mp4",
    "narration": "subtitles/narration.txt",
    "videoTranscodeable": true,
    "videoPackMode": "random"
  }
]

这个配置会:

  • 混合两个背景音乐(以 music1.mp3 的时长为准)
  • clips/ 目录随机选择视频片段,直到总时长匹配音频
  • 转码所有视频为统一格式(H.264/AAC)
  • 添加字幕并输出到 task-0/video.mp4
  • 使用系统默认字体

适用场景: 制作短视频、Vlog、产品宣传片等需要随机素材组合的场景


示例 2:使用所有视频 + 自定义字体

[
  {
    "audios": "audio/*.mp3",
    "videos": ["intro.mp4", "content.mp4", "outro.mp4"],
    "narration": "subtitle.txt",
    "videoPackMode": "all",
    "fontFile": "/path/to/your/font.ttf"
  }
]

这个配置会:

  • 混合 audio/ 目录下的所有 MP3 文件
  • 按顺序拼接三个视频文件(片头 + 内容 + 片尾)
  • 不进行视频转码(使用原始格式,需确保格式一致)
  • 使用自定义字体文件渲染字幕
  • 添加字幕并输出到 task-0/video.mp4

适用场景: 固定结构的视频制作,如教程视频、演讲录制等


示例 3:批量处理多个任务

[
  {
    "audios": "task1/audio.mp3",
    "videos": "task1/videos/*.mp4",
    "narration": "task1/subtitle.txt",
    "videoPackMode": "random"
  },
  {
    "audios": "task2/audio.mp3",
    "videos": "task2/videos/*.mp4",
    "narration": "task2/subtitle.txt",
    "videoPackMode": "all",
    "fontFile": "C:/Windows/Fonts/msyh.ttc"
  },
  {
    "audios": ["task3/bgm1.mp3", "task3/bgm2.mp3"],
    "videos": "task3/clips/*.mp4",
    "narration": "task3/subtitle.txt",
    "videoTranscodeable": true,
    "videoPackMode": "random"
  }
]

这个配置会:

  • 依次处理三个独立任务
  • 每个任务输出到对应的 task-0/task-1/task-2/ 目录
  • 第二个任务使用 Windows 微软雅黑字体
  • 支持不同的配置组合

适用场景: 批量生产系列视频、多语言版本视频等


示例 4:实际项目配置(参考 workspace/task.json)

[
  {
    "audios": ["workspace/007/007阿勒泰.mp3", "workspace/新疆背景音乐-已编辑.MP3"],
    "videos": "workspace/007/*.mp4",
    "narration": "workspace/007/007.txt",
    "videoTranscodeable": true,
    "videoPackMode": "random"
  }
]

这个配置会:

  • 混合旁白音频和背景音乐(以旁白时长为准)
  • workspace/007/ 目录随机选择视频素材
  • 转码所有视频确保格式统一
  • 添加字幕文件 007.txt 中的内容
  • 输出到 task-0/video.mp4

适用场景: 旅游 Vlog、纪录片、风景视频等需要旁白 + 背景音乐的场景


示例 5:跨平台字体配置

[
  {
    "audios": "audio.mp3",
    "videos": "videos/*.mp4",
    "narration": "subtitle.txt",
    "fontFile": "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"
  }
]

这个配置会:

  • 在 Linux 系统上使用文泉驿正黑字体
  • 确保中文字幕正确显示

跨平台字体路径:

  • macOS: /System/Library/Fonts/Supplemental/Songti.ttc
  • Windows: C:/Windows/Fonts/simhei.ttfC:/Windows/Fonts/msyh.ttc
  • Linux: /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc(需先安装:sudo apt install fonts-wqy-zenhei

🛠️ 开发

# 开发模式(使用 ts-node 直接运行)
npm run dev

# 构建项目
npm run build

# 构建并修复 ESM 导入路径
npm run fix

📝 API 说明

项目提供了一系列可复用的函数,可以在其他项目中引入使用:

import {
  getMediaDuration,      // 获取媒体文件时长
  transcodeVideo,        // 转码单个视频
  transcodeVideos,       // 批量转码视频
  concatVideos,          // 拼接多个视频
  mergeAudioFiles,       // 混音多个音频文件
  addBackgroundAudio,    // 为视频添加背景音频
  addSubTitles,          // 为视频添加字幕
  checkFfmpegAvailable   // 检查 FFmpeg 是否可用
} from '@evio/ffai';

函数详细说明

getMediaDuration(filePath: string): Promise<number>

获取媒体文件(音频或视频)的播放时长。

参数:

  • filePath: 媒体文件的完整路径

返回: Promise,resolve 时返回时长(秒)

示例:

const duration = await getMediaDuration('video.mp4');
console.log(`视频时长: ${duration} 秒`);

transcodeVideo(input: string, output: string): Promise<void>

将单个视频转码为 MP4 格式(H.264 + AAC)。

参数:

  • input: 输入视频文件路径
  • output: 输出视频文件路径

编码参数:

  • 视频编码:H.264 (libx264)
  • 音频编码:AAC
  • 音频采样率:44.1kHz
  • 音频声道:立体声

示例:

await transcodeVideo('input.avi', 'output.mp4');

concatVideos(files: string[], outputFilePath: string, tmp?: string): Promise<void>

拼接多个视频文件为一个完整视频。

参数:

  • files: 视频文件路径数组
  • outputFilePath: 输出文件路径
  • tmp: 可选,临时文件目录(用于存放 videofiles.txt)

注意: 建议所有视频使用相同的编码格式、分辨率和帧率

示例:

await concatVideos(
  ['clip1.mp4', 'clip2.mp4', 'clip3.mp4'],
  'final.mp4',
  './tmp'
);

mergeAudioFiles(audioFiles: string[], outputFilePath: string): Promise<void>

混音多个音频文件,以第一个音频的时长为准。

参数:

  • audioFiles: 音频文件路径数组
  • outputFilePath: 输出文件路径

混音规则:

  • 使用 FFmpeg 的 amix 滤镜
  • 自动调整音量避免爆音
  • 输出时长由第一个音频决定

示例:

await mergeAudioFiles(
  ['narration.mp3', 'bgm.mp3'],
  'mixed.mp3'
);

addBackgroundAudio(inputVideoPath: string, outputVideoPath: string, audioPath: string): Promise<void>

为视频添加背景音频。

参数:

  • inputVideoPath: 输入视频路径
  • outputVideoPath: 输出视频路径
  • audioPath: 音频文件路径

处理规则:

  • 视频流直接复制,不重新编码
  • 音频使用 AAC 编码
  • 使用 -shortest 参数,输出长度取视频和音频中较短的一个

示例:

await addBackgroundAudio(
  'video.mp4',
  'video_with_audio.mp4',
  'bgm.mp3'
);

addSubTitles(inputfile: string, outputfile: string, texts: string, fontfile?: string): Promise<void>

为视频添加字幕。

参数:

  • inputfile: 输入视频路径
  • outputfile: 输出视频路径
  • texts: 字幕文件路径(格式:MM:SS-MM:SS 文本内容
  • fontfile: 可选,字体文件路径

字幕样式:

  • 字体大小:36px
  • 颜色:白色
  • 效果:黑色描边 + 阴影
  • 位置:底部居中(距底部 300px)

示例:

await addSubTitles(
  'video.mp4',
  'video_with_subtitles.mp4',
  'subtitle.txt',
  '/path/to/font.ttf'
);

checkFfmpegAvailable(): Promise<boolean>

检查系统中 FFmpeg 是否可用。

返回: Promise,resolve 时返回 true(可用)或 false(不可用)

示例:

const available = await checkFfmpegAvailable();
if (!available) {
  console.error('FFmpeg 未安装或不可用');
}

⚠️ 注意事项

  1. FFmpeg 必须安装 - 工具依赖 FFmpeg,请确保已正确安装并配置到环境变量
  2. 字幕字体配置 - 可通过 fontFile 参数自定义字体路径,支持跨平台配置:
    • macOS: /System/Library/Fonts/Supplemental/Songti.ttc
    • Windows: C:/Windows/Fonts/simhei.ttfC:/Windows/Fonts/msyh.ttc
    • Linux: /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc
  3. 视频格式统一 - 强烈建议启用 videoTranscodeable 以确保所有视频格式统一,避免拼接时出现黑屏、卡顿或音画不同步
  4. 文件路径规则 - 所有路径都相对于执行命令的当前目录(process.cwd()
  5. 临时文件清理 - 处理完成后会自动清理中间过程文件(video_concat.mp4video_concat_audio.mp4videofiles.txt),仅保留最终成品
  6. 音频时长规则 - 当 audios 为数组时,最终音频时长由第一个音频文件决定,其他音频会被混音叠加
  7. 视频时长匹配 - 添加背景音频时使用 -shortest 参数,输出视频长度会与音频或视频中较短的一个对齐
  8. 字幕文件编码 - 字幕文件必须使用 UTF-8 编码,避免中文乱码
  9. Glob 模式注意 - 使用 glob 模式时,文件匹配顺序可能不是字母顺序,建议使用数组明确指定顺序
  10. 磁盘空间 - 视频处理需要较大的临时存储空间,确保磁盘有足够空间(建议至少为源文件总大小的 2-3 倍)

🎯 最佳实践

  1. 项目结构建议

    project/
    ├── task.json          # 任务配置文件
    ├── audios/            # 音频素材目录
    │   ├── narration.mp3
    │   └── bgm.mp3
    ├── videos/            # 视频素材目录
    │   ├── clip1.mp4
    │   └── clip2.mp4
    ├── subtitles/         # 字幕文件目录
    │   └── subtitle.txt
    └── task-0/            # 输出目录(自动生成)
        └── video.mp4
  2. 视频素材准备

    • 尽量使用相同分辨率和帧率的视频素材
    • 如果素材格式不统一,务必启用 videoTranscodeable: true
    • 建议使用 1920x1080 (1080p) 或 1280x720 (720p) 分辨率
  3. 音频素材准备

    • 旁白音频放在数组第一位,背景音乐放在后面
    • 确保音频采样率一致(建议 44.1kHz)
    • 背景音乐音量建议比旁白低 20-30%(可以预先处理)
  4. 字幕文件编写

    • 使用文本编辑器保存为 UTF-8 编码
    • 每条字幕时长建议 3-8 秒,便于阅读
    • 字幕文本不要过长,建议每行不超过 20 个汉字
    • 预留字幕间隔时间,避免连续出现
  5. 字体文件配置

    • 在配置文件中使用 fontFile 参数指定字体路径
    • 确保字体文件存在且可读
    • 使用支持中文的字体文件
    • 不同操作系统使用对应的字体路径
  6. 性能优化

    • 如果不需要转码,关闭 videoTranscodeable 可以大幅提升速度
    • 批量任务建议分批处理,避免一次处理过多任务
    • 使用 SSD 硬盘可以显著提升处理速度
  7. 质量控制

    • 处理完成后检查输出视频的音画同步
    • 验证字幕显示时间和内容是否正确
    • 检查音频混音效果,确保旁白清晰可听

🐛 常见问题

Q: 提示 "FFmpeg is not available"
A: 请确保已安装 FFmpeg 并配置到系统环境变量中。可以运行 ffmpeg -version 验证安装。

Q: 视频拼接后出现黑屏或卡顿
A: 建议启用 videoTranscodeable: true 将所有视频转码为统一格式。不同编码格式的视频直接拼接可能导致兼容性问题。

Q: 字幕显示不正常或不显示
A:

  • 检查字幕文件格式是否正确,时间格式必须为 MM:SS-MM:SS 文本内容
  • 确保字幕文件使用 UTF-8 编码
  • 检查时间范围是否在视频时长内
  • 确保每行格式正确,时间和文本之间有空格

Q: 音频混音后声音太小或太大
A: FFmpeg 的 amix 滤镜会自动调整音量。如需手动控制,可以在 src/lib.tsmergeAudioFiles 函数中修改 amix 参数,例如添加 weights 选项来调整各音频的权重。

Q: 字幕字体显示异常或乱码
A:

  • 使用 fontFile 参数指定正确的字体文件路径
  • macOS 可以使用 /System/Library/Fonts/Supplemental/Songti.ttc(宋体)
  • Windows 可以使用 C:/Windows/Fonts/simhei.ttf(黑体)或 C:/Windows/Fonts/msyh.ttc(微软雅黑)
  • Linux 需要安装中文字体,如 sudo apt install fonts-wqy-zenhei,然后使用 /usr/share/fonts/truetype/wqy/wqy-zenhei.ttc
  • 确保字体文件支持中文字符

Q: 任务配置文件必须是 .json 后缀吗?
A: 是的,工具会检查文件扩展名,必须使用 .json 后缀。

Q: 可以处理哪些视频格式?
A: FFmpeg 支持几乎所有常见视频格式(MP4、AVI、MOV、MKV、FLV 等)。建议启用 videoTranscodeable 转码为统一的 MP4 格式以确保兼容性。

Q: random 模式如何选择视频?
A: 工具会随机选择视频片段,累加时长直到 ≥ 音频时长。每个视频片段只会被选择一次,避免重复。如果所有视频总时长仍小于音频时长,则使用所有视频。

Q: 处理大文件时速度很慢怎么办?
A:

  • 视频转码是最耗时的步骤,如果源视频已经是 MP4 格式,可以关闭 videoTranscodeable
  • 字幕渲染需要重新编码视频,可以在 src/lib.ts 中调整 -preset 参数(如改为 ultrafast)来加快速度,但会增大文件体积
  • 考虑使用更强大的硬件或启用硬件加速

Q: 如何自定义字幕样式?
A: 在 src/lib.tsaddSubTitles 函数中修改 videoFiltersoptions,可以调整:

  • fontsize: 字体大小
  • fontcolor: 文字颜色
  • shadowcolor/shadowx/shadowy: 阴影效果
  • borderw/bordercolor: 边框效果
  • x/y: 字幕位置

Q: 输出视频的质量如何控制?
A: 在 src/lib.ts 中可以调整编码参数:

  • 转码时的 -c:v libx264 可以改为 -c:v libx265(更高压缩率)
  • 字幕渲染时的 -crf 18 控制质量(0-51,数值越小质量越高,18 为高质量)
  • 音频比特率 -b:a 192k 可以调整为更高或更低的值

📄 License

ISC

🤝 贡献

欢迎提交 Issue 和 Pull Request!

贡献指南

  1. Fork 本项目
  2. 创建特性分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 开启 Pull Request

开发建议

  • 遵循现有代码风格
  • 添加适当的注释和文档
  • 测试新功能确保不影响现有功能
  • 更新 README 文档(如有必要)

📚 相关资源

🔮 未来计划

  • [ ] 支持更多字幕格式(SRT、ASS 等)
  • [ ] 添加视频特效和转场效果
  • [ ] 支持硬件加速编码(NVENC、QSV 等)
  • [ ] 提供 GUI 界面
  • [ ] 支持实时预览
  • [ ] 添加进度条显示
  • [ ] 支持视频裁剪和缩放
  • [ ] 添加水印功能
  • [ ] 支持多语言字幕

📞 联系方式

如有问题或建议,欢迎通过以下方式联系:


版本: 1.0.2
作者: @evio/ffai
最后更新: 2024


⭐ 如果这个项目对你有帮助,欢迎给个 Star!