isidroco
isidroco

Reputation: 43

Get mediainfo Height in Batch: wrong answer returned if property is defined (%% var escape)

I have this batch which works as expected giving the video height using mediainfo

@echo off
setlocal enableextensions enabledelayedexpansion
  REM set "HEIGTH=1081"
for /f "tokens=* delims=" %%j in ('
  "mediainfo --Inform=Video;%%Height%% "b:\VID\myVideo.avi""
') do set "HEI=%%j"
echo=!HEI!

Other working way in line 5: mediainfo --Inform^="Video;%%Height%%" "b:\VID\myVideo.avi"

If HEIGHT is already defined as a variable (remove REM to enable it), result will change to HEIGHT content instead (1081 in this example). Couldn't find a working way to avoid %var% replacing and at the same time getting mediainfo to work as expected (it gives all info or nothing, instead of expected Height property of given video). Already read about %% escape and other answers, but couldn't solve this problem. Only workaround is to previously blank HEIGHT var to make sure command will work and avoid all those var names of mediainfo properties used in batch. Is there a way to fix this behaviour or will have to live with workaround?

Tried line 5: mediainfo^ --Inform^=Video^;^%Height^%^ "b:\VID\myVideo.avi" But wrong property is returned.

Upvotes: 1

Views: 32

Answers (2)

jeb
jeb

Reputation: 82418

The problem occurs, because the command inside FOR/F will be executed in a new cmd.exe instance.

In that instance the command is executed in the command line context instead of a batch file context.
This changes the behavior of the percent expansion.
Undefined variables are not expanded to nothing (like in batch file context), they simply remain unmodified.

To use this you can add a caret (or more carets) to your variable name.

for /f "tokens=* delims=" %%j in ('
  "mediainfo --Inform=Video;%%^Hei^gh^t%% "b:\VID\myVideo.avi""
') do set "HEI=%%j"

Now cmd.exe searches for a variable named ^Hei^gh^t, but removes the carets before it calls mediainfo. This still fails when you define such a variable

set "^Hei^gh^t=1081"
for /f "tokens=* delims=" %%j in ('
  "mediainfo --Inform=Video;%%^Hei^gh^t%% "b:\VID\myVideo.avi""
') do set "HEI=%%j"

But you could use a trampoline jump and use batch file context in your FOR/F loop.

@echo off
REM *** Trampoline jump for function calls of the form ex. "%~d0\:functionLabel:\..\%~pnx0"
FOR /F "tokens=3 delims=:" %%L in ("%~0") DO goto :%%L

setlocal enableextensions enabledelayedexpansion
set "Height=1081"


for /f "tokens=* delims=" %%j in ('call "%~d0\:media:\..\%~pnx0" "b:\VID\myVideo.avi"') do (
    set "HEI=%%j"
)   
echo=!HEI!    
exit /b

:media    
echo DEBUG: %* > CON
mediainfo --Inform=Video;%%Height%% %*
exit /b

The advantage is that you can now use mediainfo without having to change your arguments

Upvotes: 1

Magoo
Magoo

Reputation: 80211

Really need the syntax of the mediainfo command to be explicitly stated and the requirement for %height% to be supplied literally to the command.

I'd suggest that your solution, to empty height is the correct approach which may be applied in two ways:

saving in and cleaning up a save-variable

SET "washeight=%height%"&SET "height="
for /f "tokens=* delims=" %%j in ('
...
SET "height=%washeight%"&SET "washeight="
SET hei

and executing in a local area and transporting the required data out

SETLOCAL
set "HEIGHT="
for /f "tokens=* delims=" %%j in ('
...
ENDLOCAL&SET "hei=%hei%"
SET hei

Upvotes: 0

Related Questions