1

I am trying to set up a batch file (currently testing in CMD prompt) to run when there is a change in the directory. I have a command stored in a variable "test" which tells me what the first audio codec is. if it isn't aa3 i plan to re encode the audio with ffmpeg. My first issue is that when i try to run a simple if statement with my var, i get an error.

set test=ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv"

when i run %test% it returns what is expected.

if i run this as:

if %test% == "ac3" echo true

i get:

-v was unexpected at this time.

my end goal is to have something like this when something is added to the folder (haven't go the when something changes part yet...probably just run this once a day idk):

set test=ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "%f"

set outpath=S:\Blu Ray\New folder\"%f"

for %f in (*.mkv) DO
    if %test% <> "ac3" (
        ffmpeg -i “%f” -vcodec copy -scodec copy -acodec ac3 -b:a 640k “%outpath%";
del "%f";
move "%outpath%" "s:\Blu Ray\")

any help would be great

BD

  • You cannot assign the output of a command to a variable in a batch file like you can with BASH. Also you can not use <> with the IF command. You should probably read the help file for the IF command by opening a cmd prompt and typing: `if /?`. Also when doing an IF comparison, you need to realize that it is a true string comparison. So the quotes need to be on each side of the comparison for it to be true. And looking at your `FOR` command you might want to read the help for that as well. It clearly states you need to use two percent symbols when in a batch file. – Squashman Oct 27 '17 at 19:58
  • ah okay. Yes, i know about the %%, i stated i was testing in CMD prompt. thanks – bdrilling33 Oct 27 '17 at 20:34
  • Also, this doesnt explain why i get the -v error. even if i put the FFprobe statement in the if statement, i still get the -v error. – bdrilling33 Oct 27 '17 at 20:43
  • Because you don't have quotes around your variable test. So the if command literally sees the entire string you assigned to the variable test. It sees the space after ffprobe as the end of the string it has to compare. It tries to read the -v as the comparison operator. – Squashman Oct 27 '17 at 21:15
  • ive done it as "%test%" and get the same thing. – bdrilling33 Oct 27 '17 at 21:24

1 Answers1

2

The command line

if %test% == "ac3" echo true

is preprocessed by Windows command interpreter before execution of IF command to

if ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv" == "ac3" echo true

A space character outside a double quoted string is interpreted as argument separator. For that reason the first argument is for command IF ffprobe the second argument is -v and the third argument is error.

-v is for command IF an unknown operator and the result is the error message:

-v was unexpected at this time.

The standard solution is double quoting both strings to compare as within a double quoted string a space character as well as &()[]{}^=;!'+,`~|<> are interpreted as literal characters.

if "%test%" == "ac3" echo true

The command IF compares double quoted strings always with including the double quotes as strings and never runs an integer comparison on using double quotes on any side.

But in this case using if "%test%" == "ac3" echo true also does not work as expected because the executed command line is:

if "ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv"" == "ac3" echo true

Now the first IF argument is "ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my and second argument is movie resulting in error message:

movie was unexpected at this time.

It is necessary to use delayed environment variable expansion with a string containing double quotes assigned to an environment variable and compared with another string with IF command.

set "test=ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv""
setlocal EnableDelayedExpansion
if "!test!" == "ac3" echo true
endlocal

See also the answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? why using set "test=..." and read this answer for details about the commands SETLOCAL and ENDLOCAL.

However, the goal is to compare the output of console executable ffprobe with the string ac3.
This requires the usage of FOR.

for /F "delims=" %%I in ('ffprobe.exe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv" 2^>^&1') do if /I "%%I" == "ac3" echo true

Command FOR runs the command line as specified between '...' in a separate command process started with cmd.exe /C in background without opening a window and captures all output written to handle STDOUT for processing this output line by line whereby empty lines and lines starting with a semicolon are ignored.

2>&1 results in output of ffprobe.exe written to handle STDERR being redirected also in the background command process to handle STDOUT for being also captured and processed by FOR.

The redirection operators > and & must be escaped here both with caret character ^ to be interpreted first as literal characters when Windows command interpreter parses the entire FOR command line.

I don't have installed ffprobe.exe and so could not test the entire FOR command line. But the FOR command line should work in case of ffprobe.exe outputs really just ac3 to either STDOUT or STDERR and nothing else. The output of ffprobe.exe enclosed in double quotes is compared case-insensitive with "ac3".

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.

  • endlocal /?
  • for /?
  • if /?
  • set /?
  • setlocal /?

Read also the Microsoft documentation about Using command redirection operators.

Mofi
  • 46,139
  • 17
  • 80
  • 143
  • Something still didn't work. but thank you for the very detailed reply!!! – bdrilling33 Oct 27 '17 at 22:31
  • @bdrilling33 Perhaps `ac3` is output with additional whitespace characters. You could remove on __FOR__ command line `"delims="` and see if that changes something. Further I suggest to run `ffprobe` with its parameters from cmd window with `>stdoutput.txt 2>stderror.txt` and look on the two text files. Which one is empty? What is the encoding of the none empty text file (ANSI, UTF-8, UTF-16)? Does the non empty text file contain whitespace characters (space, tab, empty lines)? – Mofi Oct 31 '17 at 06:05
  • i ran ffprobe.exe -v error -select_streams a:0 -show_entries stream=codec_n ame -of default=nokey=1:noprint_wrappers=1 "My Movie (2017).mkv" >stdoutput. txt 2>stderror.txt and the stderror.txt is empty, the other has ac3 in it. – bdrilling33 Nov 11 '17 at 01:16