damianociarla/node-ffmpeg
ffmpeg module for nodejs
概要
node-ffmpeg は、コードからコマンドラインツール ffmpeg および ffprobe を制御できる JavaScript/TypeScript ライブラリです。シェルコマンドを直接入力する代わりに、setVideoCodec('libx264') や save('/output.mp4') といったメソッドを呼び出します。広く使われている古い ffmpeg パッケージの API をラップしつつ、ネイティブ Promise、TypeScript 型定義、ESM/CommonJS の両対応など、現代的な仕様にアップデートしています。
要件
- Node.js 24 以降。
ffmpegおよびffprobeがシステムにインストールされ、PATHに通っている必要があります。または、それぞれの実行ファイルの絶対パスを指定する必要があります。- このライブラリは意図的に FFmpeg バイナリをダウンロードしません。これによりパッケージサイズを小さく保ち、必要な FFmpeg ビルドやコーデックを自由に選択できます。
インストール
npm install ffmpeg
クイックスタート (TypeScript)
import ffmpeg from 'ffmpeg';
const video = await ffmpeg('/media/input.mp4');
video.on('progress', ({ percent, time }) => {
console.log(percent === undefined ? `${time}s` : `${percent.toFixed(1)}% (${time}s)`);
});
await video
.setVideoCodec('libx264')
.setVideoBitRate(2_000)
.setAudioCodec('aac')
.setAudioBitRate(192)
.setVideoSize('1280x?', true, true, 'black')
.save('/media/output.mp4');
メソッドはチェーン可能で、次々と呼び出すことができます。処理は save() のようなターミナルメソッドを呼び出した時点で開始されます。元のパッケージのコールバック形式の API も利用可能で、timeout や overwrite などのオプションをサポートする名前付きファクトリー create() も用意されています。
多数のファイルを処理するサービスでは、createClient() を使用してクライアントを一度作成し、FFmpeg 設定を再利用できます。
実行ファイルのパス
ffmpeg と ffprobe のパスは、グローバル(レガシーアプリ用)または操作ごとに設定できます。絶対パスの ffmpegPath を指定し、ffprobePath を指定しない場合、ライブラリはその隣に ffprobe があると推測します。
設定 (READMEの表)
| 設定 | デフォルト | 意味 |
|---|---|---|
encoding |
utf8 |
プロセス出力のエンコーディング |
timeout |
0 |
最大処理時間 (ms); 0 = タイムアウトなし |
maxBuffer |
16 MiB | 保持する変換出力の量; プローブ出力の最大値も兼ねる |
overwrite |
false |
-y で上書き; それ以外は -n で対話型プロンプトを回避 |
ffmpegPath |
ffmpeg |
FFmpeg 実行ファイル |
ffprobePath |
ffprobe |
ffprobe 実行ファイル |
signal |
— | 操作をキャンセルするための AbortSignal |
cwd, env |
継承 | 子プロセスの作業ディレクトリと環境変数 |
長時間実行される変換では、出力の最後の maxBuffer バイトのみが保持されます。プローブ出力は maxBuffer 内に完全に収まる必要があり、収まらない場合はエラー 119 で失敗します。
API のハイライト
- セッター(すべてチェーン可能):
setDisableVideo,setVideoCodec,setVideoBitRateなどのビデオセッター、setDisableAudio,setAudioCodec,setAudioBitRateなどのオーディオセッター、setMetadata,setThreads,setWatermark,addInput,addCommand,addOutputOption,addFilterComplex,getCommand(構築されたコマンドを返す)などの汎用セッター。 - ターミナルメソッド:
save,fnExtractSoundToMP3,fnExtractFrameToJPG,fnAddWatermark。これらが実際のプロセスを開始します。 copyはコーデック値として受け入れられ、「再エンコードなしでストリームをコピーする」ことを意味します。- カスタムオプションの繰り返し(例: 複数の
-mapや-metadataエントリ)が可能です。
ターミナルメソッド内のバリデーションは、Promise の拒否またはオプションのコールバックを通じてエラーを返します。セッターのバリデーションは同期的に行われます。同一ビデオオブジェクトに対する同時操作は、分離されたオプションスナップショットを使用します。
メタデータとイベント
video.metadataは元の形式(duration,video,audio, タグ)を保持し、video.metadata.rawで完全な ffprobe レスポンスを公開します。- ライフサイクルイベントをリッスンできます:
'start','progress'(パーセント/時間付き),'stderr','end','error'。 'error'リスナーはオプションです。失敗した Promise はリスナーなしでも通常通り拒否されます。
フレーム抽出
const files = await video.fnExtractFrameToJPG('/media/frames', {
start_time: '00:00:10',
every_n_seconds: 5,
number: 10,
size: '640x?',
quality: 2,
file_name: 'preview_%s',
});
every_n_frames, every_n_seconds, every_n_percentage のうち1つだけを設定できます。返されるパスには、抽出パターンに一致するファイルのみが含まれます。
カスタム FFmpeg オプション
addCommand を使用して生の引数を渡します。これらはシェル解釈なしで直接 spawn に渡されるため、シェルクォートを追加しないでください。これらのメソッドは信頼されたエスケープハッチです。検証されていないユーザー入力を決して渡さないでください。- で始まる出力先は拒否されます。代わりに ./-name.ext を使用してください。
0.0.4 からの移行
- Node.js 24+ と
ffprobeが必須になりました。 - ネイティブ Promise が古い
whenライブラリを置き換えました。awaitはこれまで通り動作します。 - エラーは、従来の数値
codeとmsgフィールドを持つFfmpegErrorインスタンスになりました。 - ウォーターマークのコンパス位置は一般的な意味に従うようになりました(
NE= 右上、古い反転を修正)。 - ビットレートは
-b:v/-b:aを使用し、数値は kbit/s として扱われます。 - 既存の出力は
-nで保護されます。上書きするにはoverwrite: trueを設定して-yを使用してください。 - パッケージに TypeScript 宣言が含まれるようになったため、
@types/ffmpegは不要です。
セキュリティ
FFmpeg は信頼できない複雑なメディアを処理します。システムの FFmpeg にパッチを適用し、リソース制限を適用し、信頼できない入力を受け入れる前に SECURITY.md を読んでください。
ライセンス
MIT © Damiano Ciarla
関連
- プロジェクト
- プロジェクト
- プロジェクト
- プロジェクト