2016-07-01 2 views
1

Я совершенно не знаком со сценариями в Windows, но вынужден использовать такой скрипт. Я хотел бы, чтобы кто-то помог мне со следующей проблемой. Я хочу обработать вывод из команды ffmpeg, чтобы сохранить информацию о доступе к веб-камере, которая будет использоваться позже. Точнее команда имеет следующий вид:ffmpeg output parse in batch script

ffmpeg -stats -hide_banner -list_devices true -f dshow -i dummy 

и вывод таков:

[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" 

Как правило, первые два встречаемости для «Альтернативного имени» из DirectShow соответствует видео и аудио, поэтому для простоты я хотите, чтобы эти две данные были сохранены в двух переменных. В этом примере:

@device_pnp_\\?\usb#vid_045e&pid_0772&mi_00#6&2a15e69b&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global 

и

@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\Desktop Microphone (3- Studio - 

Может кто-то более опытный, чтобы помочь мне с этой задачей? Спасибо заранее!

ответ

1

Вы могли бы попробовать это (untestet!)

 
@echo off&setlocal disabledelayedexpansion 
set "Alt1=" 
set "Alt2=" 
For /f tokens^=1^,2delims^=^" %%a in ('ffmpeg -stats -hide_banner -list_devices true -f dshow -i dummy 2^>^&1 ^| findstr /c:"Alternative name"') do (
    if not defined Alt1 (
     set "Alt1=%%~b" 
    ) else (
     if not defined Alt2 (
     set "Alt2=%%~b" 
    ) 
    ) 
) 
echo Alternative name 1: "%Alt1%" 
echo Alternative name 2: "%Alt2%" 
+0

Работайте как шарм !! Большое спасибо! Имейте предложение, как действовать в пакетном скрипте с зарегистрированным знаком товарного знака. Веб-камеры Microsoft имеют этот знак в имени и дают мне команду странный символ. Я думаю, что это связано с шрифтом, используемым консолью. – vlad2005

+0

@ vlad2005 Это очень сложная проблема, это зависит от ваших локальных настроек, пожалуйста, прочитайте [здесь] (http://stackoverflow.com/a/17177904/2098699). Пожалуйста, отметьте мой ответ как принято, если да. Благодарю. – Endoro

1

Этот пакетный код присваивает первую строку устройства для переменной 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" 

разделен на строки

  1. [dshow ... игнорируется, как маркер 1 не определен.
  2. @ ... игнорируется как токен 2 не указывается.
  3. 02cec400] ... игнорируется как токен 3 не указывается.
  4. Alternative ... токен 4 присвоен переменной цикла A.
  5. name ... токен 5 присвоен переменной цикла B.
  6. "@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 /?