この記事でわかること
- 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にする
関連リソース
よく使うオプション・フィルタ・コーデック設定をまとめた PDF チートシートです。手元に置いておくと調べる時間を短縮できます。
関連記事
一次ソース: ffmpeg.org/ffmpeg-protocols.html#pipe / ffmpeg.org/ffmpeg.html