この記事でわかること

  • FFmpegのパイププロトコル(pipe:0pipe:1)の使い方
  • 標準入力からデータを読み込む(-i pipe:0 または -i -
  • 標準出力に出力する(pipe:1 または -
  • curl との連携でURLの動画を直接処理する
  • PythonからFFmpegをパイプ経由で呼び出す
  • 注意点とシーク不可の制約

テスト済みバージョン: FFmpeg 6.1
対象 OS: Windows / macOS / Linux


パイプを使う理由

FFmpegのパイプ機能を使うと:

  • ファイルを書かずに処理:中間ファイルが不要でディスクI/Oを削減
  • ストリーミング処理:データをリアルタイムで受け取りながら処理
  • 他のプログラムとの連携:curl、Python、Node.jsなどと組み合わせ
  • メモリ上のデータを処理:ディスクに一時ファイルを作らない

pipe: プロトコルの基本

記法意味
pipe:0 または -標準入力(stdin)
pipe:1標準出力(stdout)
pipe:2標準エラー(stderr、通常はFFmpegのログ)

標準入力から読み込む

stdin から MP4 を読んで変換

cat input.mp4 | ffmpeg -i pipe:0 -c:v libx264 -crf 23 -c:a aac output.mp4

または短縮記法 -i -

cat input.mp4 | ffmpeg -i - -c:v libx264 -crf 23 output.mp4

標準出力に出力する

変換結果をstdoutに出力してパイプで送る

ffmpeg -i input.mp4 -c:v libx264 -crf 23 -f mp4 pipe:1 | cat > output.mp4

注意: stdoutへのMP4出力は -movflags frag_keyframe+empty_moov が必要です(通常のMP4は moov をファイル末尾に書くため):

ffmpeg -i input.mp4 -c:v libx264 -crf 23 -movflags frag_keyframe+empty_moov -f mp4 pipe:1 > output.mp4

curl との連携

URLの動画を直接FFmpegに渡す(一時ファイルなし):

curl -s "https://example.com/video.mp4" | ffmpeg -i pipe:0 -c:v libx264 -crf 23 output.mp4

または -i でURLを直接指定する方が安定しています:

ffmpeg -i "https://example.com/video.mp4" -c:v libx264 -crf 23 output.mp4

サムネイル画像をstdoutに出力する

ffmpeg -i input.mp4 -ss 00:00:01 -frames:v 1 -f image2 pipe:1 > thumbnail.jpg

Webサーバーから直接バイナリレスポンスを返す場合に便利です。


Pythonからパイプ経由でFFmpegを呼び出す

python3 -c "
import subprocess, sys

proc = subprocess.run(
    ['ffmpeg', '-i', 'input.mp4', '-c:v', 'libx264', '-crf', '23',
     '-movflags', 'frag_keyframe+empty_moov', '-f', 'mp4', 'pipe:1'],
    stdout=subprocess.PIPE,
    stderr=subprocess.DEVNULL
)
with open('output.py.mp4', 'wb') as f:
    f.write(proc.stdout)
print('Done, size:', len(proc.stdout))
"

Pythonでstdin/stdoutの双方向パイプ

python3 -c "
import subprocess

with open('input.mp4', 'rb') as inp:
    proc = subprocess.run(
        ['ffmpeg', '-i', 'pipe:0', '-c:v', 'libx264', '-crf', '23',
         '-movflags', 'frag_keyframe+empty_moov', '-f', 'mp4', 'pipe:1'],
        stdin=inp,
        stdout=subprocess.PIPE,
        stderr=subprocess.DEVNULL
    )
with open('output.pipe.mp4', 'wb') as out:
    out.write(proc.stdout)
print('完了')
"

パイプの制限事項

パイプ(stdin/stdout)を使う際の重要な制限:

制限内容
シーク不可stdinはシーク(ランダムアクセス)ができない
入力フォーマット指定が必要-f rawvideo などフォーマットを明示することがある
MP4出力は要注意通常のMP4は末尾にmoovを書くためfragmented MP4が必要

rawvideoをパイプで処理する(上級)

rawビデオフレーム(カメラや自作プログラムからの生データ)をFFmpegに渡す場合:

# rawvideoストリームをパイプで受け取る例(環境依存)
# フォーマット、サイズ、フレームレートを明示的に指定する必要があります
ffmpeg -f rawvideo -vcodec rawvideo -s 1920x1080 -r 30 -pix_fmt rgb24 -i pipe:0 \
  -c:v libx264 -crf 23 output.mp4

よくある問題

Invalid data found when processing input(stdinから読む場合)

  • 入力フォーマットをFFmpegが検出できない場合に発生
  • -f mp4 などフォーマットを明示する

stdoutへのMP4出力でファイルが壊れる

  • 通常のMP4フォーマットはstdoutと非互換
  • -movflags frag_keyframe+empty_moov を指定してfragmented MP4にする

関連リソース

よく使うオプション・フィルタ・コーデック設定をまとめた PDF チートシートです。手元に置いておくと調べる時間を短縮できます。

FFmpeg チートシート

関連記事


一次ソース: ffmpeg.org/ffmpeg-protocols.html#pipe / ffmpeg.org/ffmpeg.html