Understanding FFmpeg Output Streams
FFmpeg manages multiple output streams simultaneously, which can be confusing when trying to isolate specific information like showinfo. By default, most informational messages, warnings, and errors are written to stderr (file descriptor 2). Standard input is read from stdin, and any generated audio or video data goes to stdout or files.
The showinfo filter is a video filter that prints detailed metadata about each frame to the log. Because it is a logging mechanism rather than a data stream, its output follows the same rules as other FFmpeg logs. If you simply run ffmpeg -i input.mp4 -vf showinfo -f null -, all output will appear on stderr. To pipe this specific output to another process via stdout, you need to manipulate how the shell handles these file descriptors.
Using the Report File for General Logging
One common approach to manage verbosity is using the -report option. This generates a timestamped log file containing all FFmpeg output. While this does not directly pipe to stdout, it allows you to decouple the heavy logging from your terminal or primary pipeline. You can then tail this file or parse it programmatically if you need historical data.
However, for real-time piping, relying solely on -report is insufficient because it writes to disk, not to a pipe. You still need to handle the live stream of data. The key is understanding that showinfo data is embedded within the standard FFmpeg log output. Therefore, capturing the entire log stream and filtering it is often more reliable than trying to force the filter itself to write to a different file descriptor natively, as FFmpeg filters do not have a built-in "write to stdout" switch distinct from the global log handler.
Redirecting Stderr to Stdout in Shell Scripts
In bash or zsh, you can merge stderr into stdout using 2>&1. This allows you to capture all FFmpeg output, including showinfo, into a single variable or pipe. For example:
ffmpeg -i input.mp4 -vf showinfo -f null - 2>&1 | grep -A 50 "Frame"
This command runs FFmpeg, redirects stderr to stdout, and pipes the combined stream to grep. You can then process the showinfo lines further. Note that this also captures all other FFmpeg logs, so you may need additional filtering logic to isolate the frame data.
Parsing Showinfo Data Programmatically
If you are building an application, you might prefer to launch FFmpeg as a subprocess and read its stderr stream directly. Most programming languages provide mechanisms to access child process streams independently. In Python, for instance, you can use subprocess.Popen with stderr=subprocess.PIPE.
Once you have the stream, you can iterate through the lines looking for the specific signature of showinfo output, which typically starts with [Parsed_showinfo_0 @ ...]. This method gives you precise control over what happens to the data without polluting your application's own stdout with FFmpeg's internal status updates.
Alternative: Using FFprobe for Metadata
Often, developers ask for showinfo because they want frame-level metadata. If you only need static metadata or summary info, ffprobe is a better tool. It outputs structured JSON or XML, which is much easier to parse than the plain text log format of showinfo. You can pipe ffprobe output directly to stdout using -of json or -of xml.
ffprobe -v quiet -print_format json -show_streams input.mp4
This approach avoids the complexity of stream redirection entirely for non-real-time analysis. However, for real-time frame-by-frame analysis during encoding or transcoding, showinfo remains necessary, requiring the stderr handling techniques described above.
Handling Errors and Edge Cases
When piping FFmpeg output, ensure your downstream consumer can handle the volume of data. showinfo can generate thousands of lines per second for high-resolution video. Buffering issues may arise if your reader is slow. Consider using line-buffered output or binary protocols if performance becomes a bottleneck.
Additionally, be aware that some versions of FFmpeg may change the format of the log output. Always test your parsing logic against the specific version you are deploying. Refer to our guide on Redirect ffmpeg showinfo to Pipe with Stderr for advanced shell scripting examples involving complex redirection chains.
Frequently Asked Questions
Why is my showinfo output mixed with other FFmpeg logs?
This happens because FFmpeg writes all log messages to stderr by default. Since showinfo is a logging filter, its output shares this channel. To separate them, you must either parse the full stderr stream in your application or use shell redirection to merge and filter the output before processing.
Can I make showinfo write directly to stdout without merging stderr?
No, FFmpeg does not provide a native flag to send filter-specific logs to stdout exclusively. All filter logs go through the global log system, which defaults to stderr. You must rely on external redirection or post-processing to isolate this data.
How do I prevent FFmpeg from cluttering my terminal when piping?
You can suppress most terminal output by redirecting stderr to /dev/null in the shell (2>/dev/null) if you don't need error messages. However, since showinfo is part of stderr, this will also hide it. Instead, redirect stderr to a file or pipe it to a logger that filters out non-critical messages while keeping showinfo lines.
Is there a faster alternative to showinfo for frame analysis?
For static metadata, use ffprobe with JSON output. For real-time analysis, consider writing a custom C filter plugin if you need high-performance, low-latency processing, as the overhead of parsing text logs can be significant for high-frame-rate videos.
What happens if FFmpeg encounters an error while piping showinfo?
FFmpeg will write the error message to stderr and continue until the error is fatal. If your parser expects valid showinfo lines, it may crash on error messages. Ensure your parsing logic checks for known prefixes (like [Parsed_showinfo) before attempting to extract data fields.