This batch code assigns first device string to variable DeviceVideo
and the second device string to variable DeviceAudio
.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "DeviceVideo="
for /F "tokens=4,5*" %%I in ('ffmpeg.exe -stats -hide_banner -list_devices true -f dshow -i dummy 2^>^&1') do (
if "%%I %%J" == "Alternative name" (
if not defined DeviceVideo (
set "DeviceVideo=%%~K"
) else (
set "DeviceAudio=%%~K"
goto DevicesOutput
)
)
)
:DevicesOutput
set Device
endlocal
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 using 2>&1
as Microsoft documented in article Using command redirection operators. It is necessary to escape with ^
the operators >
and &
because this redirection should be applied on execution of ffmpeg
with using a separate command process started in background with %ComSpec% /c
and the command line within '
appended as additional arguments and not on execution of command FOR by the command process which is processing the batch file.
Command FOR processes next the output lines of ffmpeg
with skipping blank lines and also lines starting with a semicolon (default eol
).
Each line is split up to strings using spaces/tabs as separators (default delims
). It is specified with tokens=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 variables I
, J
and K
.
For example the line
[dshow @ 02cec400] Alternative name "@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
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 specified loop variable I
.
name
... token 5 assigned to loop variable J
being the next character in ASCII table.
"@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 variable K
being next but one character in ASCII table.
Inside the loop a case-sensitive string comparison is made to check if loop variable I
and J
, 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.
A new device string is found in output on equal strings. In this case is checked next if the environment variable DeviceVideo
explicitly undefined at top is still not defined which means the first device string is currently processed by the commands in body of FOR.
The device string is assigned without the surrounding double quotes because of %%~K
instead of just %%K
to either environment variable DeviceVideo
on DeviceVideo
not yet defined (first device string) or environment variable DeviceAudio
(second device string).
As only the first two 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:
DeviceAudio=@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Desktop Microphone (3- Studio -
DeviceVideo=@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global
Finally with command endlocal the current environment variables table with DeviceAudio
and DeviceVideo
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 /?