Parse ffmpeg output into batch variable


help please. I am on Windows command line and I want ffmpeg error returned as variable. Tried many things, still not working.

@echo off&setlocal disabledelayedexpansion
SET S="path\to\ffmpeg.exe" -hide_banner -i InputFile.FLV -vframes 1 -an -s 400x222 -ss 30 OutputFile.jpg
!S!
for /f "usebackq delims=" %%A in ('!S!') do set var=%%A
echo !var!

The result is that the statement !S! produces the correct output on the console (InputFile.FLV: No such file or directory) but does not put that into the variable. The output of echo !var! statement simply shows as "path\to\ffmpeg.exe" -hide_banner -i InputFile.FLV -vframes 1 -an -s 400x222 -ss 30 OutputFile.jpg

How do I get the output of !S! into !var!?


Answers:


The command setlocal disabledelayedexpansion explicitly disables delayed expansion and so !S! is not expanded delayed at all. For that reason the command line with just !S! results in an error message on execution of the batch file and definitely not in output InputFile.FLV: No such file or directory. And last line just outputs the string !var!.

The usage of for option usebackq results in interpreting the string between '...' as string and not as command line to execute with %ComSpec% /c in a background command process. For that reason the string !S! is assigned to variable var.

Therefore it can be expected that batch file was executed with setlocal EnableDelayedExpansion in real to get the outputs as written in question.

This not tested batch file should work for this task.

@echo off
set "var="
for /F delims^=^ eol^= %%I in ('""path\to\ffmpeg.exe" -hide_banner -i InputFile.FLV -vframes 1 -an -s 400x222 -ss 30 OutputFile.jpg 2>&1"') do set "var=%%I"
if defined var set var

Command FOR with option /F without using option usebackq and with a command line defined between the two ' executes in background %ComSpec% /c and the string between the two ' appended. So executed with Windows being installed in C:\Windows is:

C:\Windows\System32\cmd.exe /c ""path\to\ffmpeg.exe" -hide_banner -i InputFile.FLV -vframes 1 -an -s 400x222 -ss 30 OutputFile.jpg 2>&1"

The started Windows command processor instanced running in background removes in this case first and last " before executing the remaining command line:

"path\to\ffmpeg.exe" -hide_banner -i InputFile.FLV -vframes 1 -an -s 400x222 -ss 30 OutputFile.jpg 2>&1

ffmpeg.exe not installed by me at all outputs information like this one as far as I know to handle STDERR (standard error) instead of STDOUT (standard output). But FOR captures just output written to handle STDOUT of started command process. For that reason 2>&1 is needed to redirect output written to handle STDERR of background command process by ffmpeg.exe to handle STDOUT of background command process for being also captured by FOR of command process which is processing the batch file.

With FOR options argument string delims^=^ eol^= an empty list of string delimiters and no end of line character is defined to really get always the entire line as captured by FOR assigned to specified loop variable I. The two options are specified here by way of an exception not enclosed in " as otherwise it is not possible to define an empty list of delimiters and no end of line character. The two equal signs and the space must be escaped with caret character ^ to be interpreted as literal characters and not as argument string separators because of not being enclosed in a double quoted argument string.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • cmd /? ... explains how double quotes in string(s) after option /C or /K are interpreted by Windows command processor and when a file name (or any other argument string) must be enclosed in " on containing a space or one of these characters &()[]{}^=;!'+,`~<|>.
  • for /?
  • if /?
  • set /?

See also the Microsoft article about Using command redirection operators.