Этот пакетный код присваивает первую строку устройства для переменной DeviceVideo
и вторую строку устройства для переменной DeviceAudio
.
@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "DeviceCount=0"
for /F "tokens=4,5*" %%A in ('ffmpeg.exe -stats -hide_banner -list_devices true -f dshow -i dummy 2^>^&1') do (
if "%%A %%B" == "Alternative name" (
set /A DeviceCount+=1
if "!DeviceCount!" == "1" (
set "DeviceVideo=%%~C"
) else (
set "DeviceAudio=%%~C"
goto DevicesOutput
)
)
)
:DevicesOutput
set Device
endlocal
ffmpeg
выводит текстовые сообщения для обработки STDERR вместо STDOUT, который, безусловно, не характерно для консольных приложений. Команда ДЛЯ захватывает и обрабатывает только текст, напечатанный до STDOUT.
По этой причине необходимо, чтобы перенаправить все, выход на ffmpeg
для обработки STDERR обрабатывать STDOUT с использованием 2>&1
как объясняет Microsoft TechNet в статье Using command redirection operators. Необходимо выполнить с ^
операторы >
и &
, поскольку это перенаправление должно применяться при выполнении ffmpeg
, а не при выполнении ЗА.
Команда для процессов рядом выходных линии ffmpeg
с пропуском пустых строк, а также строки, начинающейся точкой с запятой (по умолчанию eol
).
Каждая строка разделена на строки с использованием пробелов/вкладок в качестве разделителей (по умолчанию delims
). Он задан с помощью tokens=4,5*
, что представляют интерес только строки 4, 5 и остальная часть строки после пятой строки/разделителей строк, которые должны быть присвоены переменным цикла A
, B
и C
.
Например линия
[dshow @ 02cec400] Alternative name "@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
разделен на строки
[dshow
... игнорируется, как маркер 1 не определен.
@
... игнорируется как токен 2 не указывается.
02cec400]
... игнорируется как токен 3 не указывается.
Alternative
... токен 4 присвоен переменной цикла A
.
name
... токен 5 присвоен переменной цикла B
.
"@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
... токен 6, указанный с *
, соответствующий остальной части линии (с пробелами и вкладками), присвоенный переменной цикла C
.
Внутри цикла чувствительный к регистру сравнение строк производится, чтобы проверить, если переменная цикла A
и B
, с одним пространством между ними, в двойных кавычках, равна строка "Alternative name"
. Двойные кавычки не удаляются IF перед сравнением двух строк.
В равных строках переменная окружения увеличивается на единицу, используя простое арифметическое выражение, потому что новое имя устройства находится в выводе.
Команда интерпретатор Windows, заменяет все переменные окружения ссылки с синтаксисом %VariableName%
текущим значением каждого ссылочного переменной окружения в блоке команды, определенной с (
... )
уже найти такой блок. Если в командном блоке будет использоваться %DeviceCount%
, каждый цикл будет выполняться со значением 0, как определено в строке выше цикла FOR. Поэтому замедленное расширение используется с использованием синтаксиса !DeviceCount!
и позволяет явно отсрочить расширение в верхней части пакетного сценария, поскольку по умолчанию замедленное расширение не включено.
Примечание: командной SETLOCAL выталкивает также текущие состояния расширений командных и замедленные разложения, а также текущий каталог и указатель на текущую таблицу переменных окружения в стеке и создает копию таблицы целых переменных окружений для использование до (соответствия) endlocal или для выхода из пакетной обработки файлов.
Строка устройства без окружающих двойных кавычек из-за %%~C
вместо просто %%C
присваивается либо переменная DeviceVideo
или переменной DeviceAudio
в зависимости от значения переменной среды DeviceCount
.
Поскольку интерес представляют только первые 2 строки устройства, цикл выходит уже после назначения второй строки устройства DeviceAudio
.
Все переменные, начинающийся с подстрокой Device
выводятся в алфавитном порядке на следующий обработанную линии, что приводит к примеру на выходе:
[email protected]_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Desktop Microphone (3- Studio -
DeviceCount=2
[email protected]_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global
Наконец с помощью команды Endlocal текущей таблица переменной среды с DeviceAudio
, DeviceCount
и DeviceVideo
удаляется из памяти, состояния расширений команд (включено по умолчанию включено) и замедленное расширение (отключено по умолчанию отключено), а текущий каталог (не изменен вообще) восстанавливается, а таблица исходных переменных среды выполнена снова активен ,
Для лучшего понимания использованных команд откройте окно командной строки, выполните там следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.
echo /?
endlocal /?
for /?
goto /?
if /?
set /?
setlocal /?
Работайте как шарм !! Большое спасибо! Имейте предложение, как действовать в пакетном скрипте с зарегистрированным знаком товарного знака. Веб-камеры Microsoft имеют этот знак в имени и дают мне команду странный символ. Я думаю, что это связано с шрифтом, используемым консолью. – vlad2005
@ vlad2005 Это очень сложная проблема, это зависит от ваших локальных настроек, пожалуйста, прочитайте [здесь] (http://stackoverflow.com/a/17177904/2098699). Пожалуйста, отметьте мой ответ как принято, если да. Благодарю. – Endoro