在powershell中捕获ffmpeg的元数据输出

时间:2016-03-17 01:06:25

标签: powershell ffmpeg

我试图在PowerShell(tm)中捕获ffmpeg的输出,以获取某些ogg& amp;的某些元数据。 mp3文件。但是当我这样做时:

ffmpeg -i file.ogg 2>&1 | sls GENRE

输出包含一堆没有匹配字符串的行," GENRE":

      album_artist    : Post Human Era
      ARTIST          : Post Human Era
      COMMENT         : Visit http://posthumanera.bandcamp.com
      DATE            : 2013
      GENRE           : Music
      TITLE           : Supplies
      track           : 1
At least one output file must be specified

我猜测编码中有些不同。 ffmpeg的输出是彩色的,所以输出中的颜色控制字符可能会破坏它们吗?或者,也许ffmpeg的输出并不能与PowerShell的默认UTF-16很好地配合?我无法弄清楚是否有其他方法可以重定向stderr并删除颜色字符或更改stderr的编码。

编辑: 奇怪的是,我也得到了不确定的输出。有时输出如上所示。有时使用完全相同的命令输出:

      GENRE           :

enter image description here

这更有意义,但仍然缺少我关心的部分(' Music')。

某些地方,PowerShell将某些东西解释为不是换行符的换行符。

2 个答案:

答案 0 :(得分:1)

当我使用旧的Powershell时,我仍然看到此行为,但是此后我已升级到PowerShell Core(7.0.2),并且该问题似乎已解决。我读到某个地方使用PowerShell Core,他们已经将默认编码更改为UTF-8,所以也许与此有关。

enter image description here

我的理论是,在旧版本中,无论代码如何正常组合输出流,都将确保保留并交错单个行,而不是将其剪切掉。但是我猜想这段代码将以默认编码而不是UTF-8查找换行符,因此当它接收到两个UTF-8流时,它不会正确解析行定界符,并且您会得到怪异的拆分。似乎应该有一种方法可以在混合输出流之前更改编码,但是我不确定(由于它可以工作,所以现在不重要了)。我不知道为什么输出似乎会不确定地变化,除非解析UTF8字节就像是UTF16或其他默认值时有不确定性。

答案 1 :(得分:0)

我的脚本可以使用正则表达式捕获所有输出并通过管道传输到自定义对象

Function Rotate-Video {
param(
[STRING]$FFMPEGEXE = "P:\Video Editing\ffmpeg-4.3.1-2020-10-01-full_build\bin\ffmpeg.exe",
    [parameter(ValueFromPipeline = $true)]
[STRING]$Source      = "D:\Video\Source",
[STRING]$Destination = 'D:\Video\Destination',
[STRING]$DestinationExtention='mp4'
)

    (Get-ChildItem $Source) | ForEach-Object {
        $FileExist  = $false
        $Source     = $_.fullname
        $Name       = $_.basename
        $outputName = $name+'.'+$DestinationExtention
        $Fullpath   = Join-Path -Path $Destination -ChildPath $outputName
        $Regex      = "(\w+)=\s+(\d+)\s+(\w+)=(\d+.\d+)\s+(\w)=(\d+.\d+)\s+(\w+)=\s+(\d+)\w+\s+(\w+)=(\d+:\d+:\d+.\d+)\s+(\w+)=(\d+.\d+)\w+\/s\s+(\w+)=(\d+.\d+)"
        &$FFMPEGEXE -i $Source -vf transpose=clock $Fullpath 2>&1 | Select-String -Pattern $Regex  | ForEach-Object {       
            $output = ($_ | Select-String -Pattern $regex).Matches.Groups
            [PSCUSTOMOBJECT]@{
                Source      = $source
                Destination = $Fullpath
                $output[1]  = $output[2]
                $output[3]  = $output[4]
                $output[5]  = $output[6]
                $output[7]  = $output[8]
                $output[9]  = $output[10]
                $output[11] = $output[12]
                $output[13] = $output[14]
            }
        }
    }
}