I am totally unfamiliar with scripts in Windows, but are forced to use such a script. I would like someone to help me with the following problem. I want to process the output from ffmpeg command to save information about access an webcam to be used later. More precisely command is following:
ffmpeg -stats -hide_banner -list_devices true -f dshow -i dummy
and output is like this:
[dshow @ 02cec400] DirectShow video devices (some may be both video and audio devices)
[dshow @ 02cec400] "Microsoft LifeCam Studio"
[dshow @ 02cec400] Alternative name "@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 02cec400] DirectShow audio devices
[dshow @ 02cec400] "Desktop Microphone (3- Studio -"
[dshow @ 02cec400] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Desktop Microphone (3- Studio -"
[dshow @ 02cec400] "Line In (High Definition Audio "
[dshow @ 02cec400] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Line In (High Definition Audio "
[dshow @ 02cec400] "Microphone (High Definition Aud"
[dshow @ 02cec400] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Microphone (High Definition Aud"
Typically, the first two occurence for ”Alternative name” from DirectShow correspond to video and audio, so for simplicity I want these two information saved in two variables. In this example is:
@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global
and
@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Desktop Microphone (3- Studio -
Can someone more experienced to help me with this task? Thanks in advance!
You might try this (untestet!)
This batch code assigns first device string to variable
DeviceVideo
and the second device string to variableDeviceAudio
.ffmpeg
outputs text messages to handle STDERR instead of STDOUT which is definitely not typical for console applications. Command FOR captures and processes just text printed to STDOUT.For that reason it is necessary to redirect everything output by
ffmpeg
to handle STDERR to handle STDOUT using2>&1
as Microsoft explains in TechNet article Using command redirection operators. It is necessary to escape with^
the operators>
and&
because this redirection should be applied on execution offfmpeg
and not on execution of FOR.Command FOR processes next the output lines of
ffmpeg
with skipping blank lines and also lines starting with a semicolon (defaulteol
).Each line is split up to strings using spaces/tabs as separators (default
delims
). It is specified withtokens=4,5*
that only the strings 4, 5 and rest of the line after fifth spaces/tabs separated string are of interest and should be assigned to the loop variablesA
,B
andC
.For example the line
is split up to the strings
[dshow
... ignored as token 1 is not specified.@
... ignored as token 2 is not specified.02cec400]
... ignored as token 3 is not specified.Alternative
... token 4 assigned to loop variableA
.name
... token 5 assigned to loop variableB
."@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
... token 6 specified with*
matching rest of the line (with spaces and tabs) assigned to loop variableC
.Inside the loop a case-sensitive string comparison is made to check if loop variable
A
andB
, with a single space between, enclosed in double quotes is equal the string"Alternative name"
. The double quotes are not removed by IF before comparing the two strings.On equal strings an environment variable is incremented by one using a simple arithmetic expression because a new device name is found in output.
The command interpreter of Windows replaces all environment variable references with syntax
%VariableName%
by the current value of each referenced environment variable within a command block defined with(
...)
already on finding such a block. If%DeviceCount%
would be used in the command block, each loop run would be done with value 0 as defined in the line above the FOR loop. Therefore delayed expansion is used by using syntax!DeviceCount!
and enable delayed expansion explicitly at top of the batch script because delayed expansion is not enabled by default.Note: The command setlocal pushes also the current states of command extensions and delayed expansions as well as current directory and a pointer to current environment variables table on stack and creates a copy of the entire environment variables table for usage up to (matching) endlocal or to exit of batch file processing.
The device string without the surrounding double quotes because of
%%~C
instead of just%%C
is assigned to either variableDeviceVideo
or variableDeviceAudio
depending on value of the environment variableDeviceCount
.As only the first 2 device strings are of interest, the loop is exited already after assigning the second device string to
DeviceAudio
.All variables starting with the substring
Device
are output alphabetically sorted on next processed line which results for the example in the output:Finally with command endlocal the current environment variables table with
DeviceAudio
,DeviceCount
andDeviceVideo
is removed from memory, states of command extensions (enabled as by default enabled) and delayed expansion (disabled as by default disabled), and the current directory (not changed at all) are restored, and the initial environment variables table is made active again.For even better understanding the used commands, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
goto /?
if /?
set /?
setlocal /?