この記事でわかること
- FFmpegのパイププロトコル(
pipe:0、pipe: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にする
つまずきやすいポイント
-
症状: stdout に出した MP4 が再生できない/壊れる。 原因: 通常の MP4 は
moovアトムをファイル末尾に書くため、シーク不可な stdout と相性が悪い。対処:-movflags frag_keyframe+empty_moovを付けて fragmented MP4 にします。本記事の例の通りです。 -
症状: stdin から読むと
Invalid data found when processing input。 原因: FFmpeg が入力フォーマットを自動判定できない。対処:-f mp4などフォーマットを-iの前に明示します。raw データなら-f rawvideoとサイズ・fps・pix_fmt の指定が必要です。 -
症状:
-ssでのシークが効かない/遅い。 原因: stdin はランダムアクセスできないため、シークは先頭からの読み飛ばしになる。対処: シークが重要な処理では、可能なら-i ファイル名で直接ファイルを渡すか、-i "URL"を使います。 -
症状: Python で stderr が混ざってデータが壊れる。 原因: FFmpeg のログ(stderr)と出力(stdout)を区別していない。対処: 本記事の例のように
stdout=subprocess.PIPE、stderr=subprocess.DEVNULLを分けて指定します。
よくある質問
Q. pipe:0 と - は同じですか。
A. はい。入力で -i pipe:0 と -i - は同義です。出力では pipe:1 と - が標準出力を指します。
Q. なぜわざわざパイプを使うのですか。 A. 中間ファイルを作らずにディスク I/O を減らせる、curl や Python など他プログラムと直結できる、メモリ上のデータをそのまま流せる、といった利点があります。
Q. URL の動画はパイプと直接 -i のどちらがよいですか。
A. シークやフォーマット判定が絡む場合は -i "URL" で直接渡す方が安定します。単純に流すだけなら curl ... | ffmpeg -i pipe:0 でも動きます。
Q. Windows でもパイプは使えますか。
A. 使えます。ただし /dev/null の代わりに NUL を使うなど、シェル固有の表記に置き換えます。pipe:0・pipe:1 自体は共通です。
Q. 出力を別の FFmpeg にそのまま渡せますか。
A. はい。ffmpeg ... -f mp4 pipe:1 | ffmpeg -i pipe:0 ... のように連結できます。ただし fragmented MP4 など、stdout で扱えるフォーマットを選んでください。
関連リソース
よく使うオプション・フィルタ・コーデック設定をまとめた PDF チートシートです。手元に置いておくと調べる時間を短縮できます。
関連記事
一次ソース: ffmpeg.org/ffmpeg-protocols.html#pipe / ffmpeg.org/ffmpeg.html