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

関連

  • プロジェクト
  • プロジェクト
  • プロジェクト
  • プロジェクト