powershell - Powershell中的行继续中间字符串
问题描述
我正在尝试在具有两个相同捕获卡的系统上编写 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
我的目标是打破我对视频/音频设备的要求,以更好地适应街区的其余部分。
解决方案
在 PowerShell中的字符串`
内或字符串之间的行尾使用与在 Bash中使用for line continuation的工作方式不同,例如:"..."
\
如果放置在一行的最后,While`
确实会在 PowerShell 中启用续行:
当在跨行
"..."
字符串中使用时,`
转义换行符,而不删除它,这实际上是一个no-op,因为 PowerShell 字符串文字中的换行符不需要转义。当您尝试在应形成单个参数的字符串之间使用时(将在单行上直接相邻放置的字符串,例如,
video="...":audio="..."
),`
有效地充当参数分隔符,因此您无法拆分应该这样就变成了一个字符串。[1]
简而言之:在 PowerShell中,
您只能在arguments之间使用换行符。
为了将单个参数分布在多行中,您需要使用表达式(
(...)
);允许表达式跨越多行而无需续行。
在您的情况下,一种选择是将字符串部分指定为数组的元素,稍后将这些元素连接起来形成单个字符串。
使用一个简化的例子;请注意该-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来传递它:
# 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
笔记:
Splatting 的主要用例是启用命令参数的编程构造,并且需要不同的语法,如图所示。
这个 - 最终被拒绝- RFC 提案提出了新的语法,这将使具有常规参数语法的多行延续更容易,而无需
`
在每个内部行的末尾;被拒绝的决定就在这里。
[1] 有关 PowerShell 如何解析复合标记的更多信息,请参阅此 GitHub 问题。
推荐阅读
- java - DialogFragment 正在将 XML 扩展到全屏?
- wpf - 如何在 WPF 中设置样式和样式触发器
- android - 膨胀类 android.support.v4.widget.SwipeRefreshLayout
- mpi - 计算一个进程中的一个值,发送给根进程mpi
- google-cloud-bigtable - 是否可以针对本地 BigTable 模拟器实例运行 BigQuery 命令行界面 (cli)?
- laravel - Vue js 无法显示数据
- matlab - matlab中较小的表面如何平方
- c++11 - 如何使用 QPushButton 和 OpenCV::imwrite 保存在 QGraphicsView 上加载的增量图像
- html - 无法获取 HTML 选择表单以显示用户先前保存到数据库的选定 home_state
- wolfram-mathematica - 在列表中的点处评估定义的函数