Pipe FFmpeg Output to Another FFmpeg Instance

Piping the output of one FFmpeg process directly into another allows you to chain multiple processing stages together in memory without the overhead of writing intermediate files to your disk. This workflow relies on standard output (stdout) and standard input (stdin) via the shell pipe operator (|). Because pipes are non-seekable streams, the primary technical requirement is selecting a container format for the intermediate stream that supports sequential writing.

The Basic Command Structure

In FFmpeg, a hyphen (-) or pipe:1 represents standard output when used as an output destination, and a hyphen (-) or pipe:0 represents standard input when used as an input source.

ffmpeg -i input.mp4 [encoding options] -f <format> - | ffmpeg -f <format> -i - [encoding options] output.mp4

Choosing the Right Intermediate Format

Standard MP4 files cannot be piped out of the box because the default container structure requires a seekable medium to finalize the index (moov atom) at the beginning or end of the file. To send data through a pipe, you must force FFmpeg to use a streaming container format using the -f flag.

1. The NUT Container (-f nut)

The nut format is developed by the FFmpeg project. It supports virtually every codec, has minimal container overhead, and is fully streamable, making it the best general-purpose format for intermediate piping.

ffmpeg -i input.mp4 -vf "scale=1280:720" -c:v libx264 -c:a copy -f nut - | ffmpeg -f nut -i - -c:v libx265 -crf 28 final_output.mp4

2. MPEG-TS (-f mpegts)

MPEG Transport Stream is natively designed for broadcast networks and packet-based streaming. It works well if your intermediate video is H.264 or H.265 and your audio is AAC or MP3.

ffmpeg -i input.mov -c:v libx264 -preset ultrafast -c:a aac -f mpegts - | ffmpeg -i - -c:v copy -c:a copy output.mkv

3. Raw Video and Audio (-f rawvideo)

If you want to decode video completely and pipe the raw pixel data directly into the next instance without any intermediate compression artifacts:

ffmpeg -i input.mp4 -f rawvideo -pix_fmt yuv420p - | ffmpeg -f rawvideo -pixel_format yuv420p -video_size 1920x1080 -framerate 30 -i - -c:v libx264 output.mp4

Note: When piping raw data, the receiving instance cannot detect stream parameters automatically. You must explicitly declare the pixel format, frame size, and framerate on the receiving FFmpeg command.

Key Considerations

  • Standard Error Suppression: Both FFmpeg instances write logs and progress metrics to stderr by default. These do not interfere with the video stream flowing through stdout. However, if you want cleaner terminal output, add -loglevel error to one or both instances.
  • CPU and Memory Limits: Both commands execute simultaneously. Ensure your system has sufficient CPU cores and memory bandwidth to run two transcode processes in parallel without causing buffer underruns.