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.mp4Choosing 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.mp42. 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.mkv3. 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.mp4Note: 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
stderrby default. These do not interfere with the video stream flowing throughstdout. However, if you want cleaner terminal output, add-loglevel errorto 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.