Продолжение линии Mid String In Powershell - PullRequest
0 голосов
/ 02 декабря 2018

Я пытаюсь написать команду FFmpeg в системе, которая имеет две идентичные карты захвата, поэтому я должен использовать их «альтернативные имена», иначе FFmpeg не поймет, какую из них я вызываю.

Единственная проблема в том, что альтернативные имена очень длинные, особенно при вызове аудио и видео через dshow:

-i video="@device_pnp_\\?\usb#vid_07ca&pid_0570&mi_00#7&3886ab1a&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global":audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{0E6F0DEF-2B29-4117-8D30-13F01160AC5B}"

Я хотел бы разорвать эту "строку" в середине строки перед вызовомаудио, чтобы сделать его более читабельным, вот так:

-i video="@device_pnp_\\?\usb#vid_07ca&pid_0570&mi_00#7&3886ab1a&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"`
:audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{0E6F0DEF-2B29-4117-8D30-13F01160AC5B}"

Однако, похоже, обратный удар не работает в этом сценарии, я полагаю, потому что он граничит с персонажем?Если я и пробел перед обратным трюком, он разбивает строку и выдает ошибки FFmpeg:

    -i video="@device_pnp_\\?\usb#vid_07ca&pid_0570&mi_00#7&3886ab1a&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" `
:audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{0E6F0DEF-2B29-4117-8D30-13F01160AC5B}"

Есть ли способ разделить это на несколько строк в Powershell?

Редактировать - полнофункциональная команда:

ffmpeg -y -hide_banner -thread_queue_size 9999 -indexmem 9999 -guess_layout_max 0 -f dshow -rtbufsize 2147.48M `
-video_size 1920x1080 -framerate 60 `
-i video="@device_pnp_\\?\usb#vid_07ca&pid_0570&mi_00#7&3886ab1a&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global":audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{0E6F0DEF-2B29-4117-8D30-13F01160AC5B}" `
-thread_queue_size 9999 -indexmem 9999 -guess_layout_max 0 -f dshow -rtbufsize 2147.48M `
-video_size 1920x1080 -framerate 60 `
-i video="@device_pnp_\\?\usb#vid_07ca&pid_0570&mi_00#7&24df76f&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global":audio="@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{0A494693-5F33-4304-88D7-394757E09648}" `
-map 0:0,0:1 -map 0:1 -map 1:0,1:1 -map 1:1 -c:v h264_nvenc -r 60 -rc-lookahead 120 -forced-idr 1 -strict_gop 1 `
-sc_threshold 0 -flags +cgop -force_key_frames "expr:gte(t,n_forced*2)" -preset: llhp -pix_fmt yuv420p -b:v 250M `
-minrate 250M -maxrate 250M -bufsize 250M -c:a aac -ar 44100 -b:a 384k -ac 2 -af "aresample=async=250" -vsync 1 `
-max_muxing_queue_size 9999 -f segment -segment_time 600 -segment_wrap 9 -reset_timestamps 1 `
-segment_format_options max_delay=0 C:\Users\Jordan\Videos\FFmpeg\FFmpeg%02d.ts

Моя цель - прервать мои звонки на видео / аудиоустройства, чтобы лучше соответствовать остальной части блока.

1 Ответ

0 голосов
/ 02 декабря 2018

Использование ` в конце строки внутри строки "..." или между строками в PowerShell не работает так же, как использование \ для продолжения строки inНапример, Bash:

В то время как ` разрешает продолжение строки в PowerShell, если он находится в самом конце строки:

  • при использовании внутри строки "..." строки , ` экранирует новой строки без ее удаления , что фактически no-op , учитывая, что переводы строк внутри строковых литералов PowerShell не требуют экранирования.

  • , когда, как в вашей попытке,используется между строками, которые должны формировать одиночный аргумент (строки, которые будут размещены непосредственно рядом друг с другом в одной строке, например, video="...":audio="..."),` эффективно действует как разделитель аргументов , поэтому вы не можете разбить то, что должно стать одной строкой.в пути. [1]

Короче: В PowerShell ,

  • Вы может использовать только продолжение строки между аргументами .

  • Чтобы распределить единственный аргумент по нескольким строкам, вам нужно использовать выражение ((...)) ;выражения могут занимать несколько строк без продолжения строки.


Один из вариантов в вашем случае - указывать части строки как элементы массива которые позже присоединились , чтобы сформировать одну строку.

Используя упрощенный пример;обратите внимание, как техника -join может сосуществовать с использованием конца строки ` для распределения команды по нескольким строкам между аргументами:

ffmpeg -framerate 60 `
  -i ((
    'video=@device_pnp_\\?\1', 
    'audio=@device_cm_2'
  ) -join ':') `
  -f dshow

Это переводит на следующую строкупри выполнении:

ffmpeg -framerate 60 -i video=@device_pnp_\\?\1:audio=@device_cm_2 -f dshow

Обратите внимание, что исходное внутреннее цитирование аргумента (video="...":audio="...") не использовалось, потому что оно обычно не требуется (хотя некоторые программы, такие как msiexec, к сожалению, требуется).

PowerShell автоматически заключает в кавычки аргументы для внешних программ по требованию, а именно, если они содержат пробелы, которые, как считает PowerShell, не находятся внутри внедренных двойных кавычек.См. этот ответ для получения дополнительной информации, в том числе, когда это может быть проблематично.


Другая альтернатива заключается в построении (только) длиннойаргументы заранее и ссылаться на них через переменную :

$inputSpec = (
  'video=@device_pnp_\\?\1', 
  'audio=@device_cm_2'
) -join ':'

ffmpeg -framerate 60 -i $inputSpec -f dshow

Чтобы вообще распределить аргументы команды по нескольким строкам без использования `в конце строки между аргументами создайте аргументы в массиве впереди и используйте splatting для передачиit:

# Construct an array containing all arguments.
# Note: Each parameter (+ operand, if any) is placed on its own line
#       here for clarity, but you're free to choose as many or few 
#       lines desired.
$ffmpegArgs =
  '-y', 
  'hide_banner', 
  '-thread_queue_size', '9999', 
  '-indexmem', '9999', 
  '-guess_layout_max', '0', 
  '-f', 'dshow', 
  '-rtbufsize', '2147.48M',
  '-video_size', '1920x1080', 
  '-framerate', '60',
  '-i', ((
    'video=@device_pnp_\\?\usb#vid_07ca&pid_0570&mi_00#7&3886ab1a&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global',        
    'audio=@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{0E6F0DEF-2B29-4117-8D30-13F01160AC5B}'
  ) -join ':')

  # ...

# Pass the array via splatting - note the '@'
ffmpeg @ffmpegArgs

[1] Подробнее о том, как PowerShell анализирует составные токены , см. эту проблему GitHub .

...