PowerShell和控制台应用程序输出

7

我正在尝试使用PowerShell和FFmpeg工具自动化视频转换。

如果没有所有必要的参数,调用FFmpeg通常会详细报告有关视频的输出。通常,它会报告错误并显示输入文件信息(如果指定了一个)。例如,我交互式执行了这样的命令:

d:\video.Enc\ffmpeg.exe -i d:\video.Enc\1.wmv

这是PowerShell控制台的输出。

ffmpeg.exe : FFmpeg version SVN-r20428, Copyright (c) 2000-2009 Fabrice Bellard, et al.
row:1 char:24
+ d:\video.Enc\ffmpeg.exe <<<<  -i d:\video.Enc\1.wmv
    + CategoryInfo          : NotSpecified: (FFmpeg version ...Bel 
   lard, et al.:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

  built on Nov  1 2009 04:03:50 with gcc 4.2.4
  configuration: --enable-memalign-hack --prefix=/mingw --cross-pre
fix=i686-mingw32- --cc=ccache-i686-mingw32-gcc --target-os=mingw32 
--arch=i686 --cpu=i686 --enable-avisynth --enable-gpl --enable-vers
ion3 --enable-zlib --enable-bzlib --enable-libgsm --enable-libfaad 
--enable-pthreads --enable-libvorbis --enable-libtheora --enable-li
bspeex --enable-libmp3lame --enable-libopenjpeg --enable-libxvid --
enable-libschroedinger --enable-libx264 --enable-libopencore_amrwb 
--enable-libopencore_amrnb
  libavutil     50. 3. 0 / 50. 3. 0
  libavcodec    52.37. 1 / 52.37. 1
  libavformat   52.39. 2 / 52.39. 2
  libavdevice   52. 2. 0 / 52. 2. 0
  libswscale     0. 7. 1 /  0. 7. 1
[wmv3 @ 0x144dc00]Extra data: 8 bits left, value: 0

Seems stream 1 codec frame rate differs from container frame rate: 
1000.00 (1000/1) -> 15.00 (15/1)
Input #0, asf, from 'd:\video.Enc\1.wmv':
  Duration: 00:12:0
2.00, start: 5.000000, bitrate: 197 kb/s
    Stream #0.0(eng): Audio: wmav2, 44100 Hz, 1 channels, s16, 48 k
b/s
    Stream #0.1(eng): Video: wmv3, yuv420p, 1024x768, 137 kb/s, 15 tbr, 1k tbn, 1k tbc Metadata
    title           : Silverlight 2.0 Hello World Application
    author          : Sergey Pugachev
    copyright       : 
    comment         : 
    WMFSDKVersion   : 11.0.6001.7000
    WMFSDKNeeded    : 0.0.0.0000
    IsVBR           : 1
    ASFLeakyBucketPairs: 
    VBR Peak        : 715351
    Buffer Average  : 127036
At least one output file must be specified

但我无法弄清楚如何编写脚本并捕获输出到任何一种 Posh 对象。我尝试了直接编写脚本,其中 ps1 文件包含确切的表达式“d:\video.Enc\ffmpeg.exe -i d:\video.Enc\1.wmv” - 但它没有起作用。我还尝试使用 invoke-command 和 invoke expression 完成这个任务。第一个返回一个带有命令的确切字符串,第二个将错误转储到输出控制台,但不是我指定的 -ErrorVariable(我设置了所有输出变量,而不仅仅是错误变量 - 所有变量都为空)。

有人能指出在 Posh 中调用控制台应用程序和捕获输出的正确语法吗?

第二个问题是关于解析该输出 - 我需要视频分辨率数据来计算转换的正确纵横比。因此,如果有人指出如何处理捕获的错误输出并解析像

Stream #0.1(eng): Video: wmv3, yuv420p, 1024x768,

的字符串,那就太好了。

1个回答

8
尝试将错误流重定向到标准输出,如下所示,然后您就可以在一个变量中捕获标准输出和标准错误了,例如:
$res = d:\video.Enc\ffmpeg.exe -i d:\video.Enc\1.wmv 2>&1

为了获取数据,请尝试以下方法:
$res | Select-String '(?ims)^Stream.*?(\d{3,4}x\d{3,4})' -all | 
    %{$_.matches} | %{$_.Groups[1].Value}

我不确定$res是一个字符串还是多个字符串,但上面的方法应该适用于两种情况。

标准错误输出到标准输出正常工作。谢谢。 有没有办法分别获取stderr和stdout?数据捕获有点不同(有2个或更多的分离流输出信息-用于音频和视频),需要回溯或排除“Stream”,但这一点我可以自己完成。感谢您给我的起点。 - Alexey Shcherbak
是的,你可以分别捕获它们 - ffmpeg.exe ... > foo.txt 2>foo.err - Keith Hill
我不是很清楚,是否有一种高端的方法可以分别获取数据流。例如,Invoke-Expression具有指定ErrorVariable和OutVariables的键。是否有一种使用此类语法获取输出的方法,而不使用临时文件? - Alexey Shcherbak
2
">"和"2>"是Posh的方式,使用远比"-ev"和"-ov"多,并且除了cmdlets之外,它们只能在EXEs上使用。 :-) 现在,如果您不想转到文件,则仅将命令的结果分配给变量将捕获stdout,但您仍需要将stderr重定向到文件(这是最简单的)。 $res = ffmpeg.exe ... 2>err.txt; $err = gc err.txt 在调用ffmpeg.exe之前和之后,您可以检查$error变量。如果发生错误(检查$lastexitcode),则$error[0]应包含stderr信息。 - Keith Hill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接