【问题标题】:Capture ffmpeg's metadata output in powershell在 powershell 中捕获 ffmpeg 的元数据输出
【发布时间】:2016-03-17 01:06:25
【问题描述】:

我正在尝试在 PowerShell(tm) 中捕获 ffmpeg 的输出,以获取有关某些 ogg 和 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           :

这更有意义,但仍然缺少我关心的部分(“音乐”)。

powershell 将某些内容解释为不是换行符的换行符。

【问题讨论】:

  • slsSelect-String 正在返回一个匹配对象。如果这些都出现在同一个字符串中,则返回整个字符串。此外,您只是单独匹配 GENRE,因此如果您仅扩展匹配的数据,您最终会得到 GENRE,因为那是您的查询。
  • 是的,但是当它是多行时,为什么整个块都算作一个匹配?这不是表示编码/控制字符问题吗?否则sls 将单独接收每一行...
  • 编辑了更多信息
  • 这个(ffmpeg -i file.ogg 2>&1).GetType().FullName的结果是什么
  • System.Object[]?

标签: powershell ffmpeg


【解决方案1】:

当我使用旧的 powershell 时,我仍然看到这种行为,但我已经升级到 PowerShell Core (7.0.2),问题似乎已经解决了。我在某处读到,他们使用 PowerShell Core 将默认编码更改为 UTF-8,所以也许与此有关。

我的理论是,在旧版本中,任何组合输出流的代码通常都会确保单独的行被保留和交错而不是被分割。但我猜这个代码正在寻找默认编码中的换行符,而不是 UTF-8,所以当它接收到两个 UTF-8 流时,它不会正确解析行分隔符,你会得到奇怪的拆分。似乎应该有一种方法可以在混合输出流之前更改编码,但我不确定(现在没关系,因为它可以工作)。为什么输出似乎不确定地改变,我不知道,除非在解析 UTF8 字节时存在不确定性,就好像它们是 UTF16 或任何默认值一样。

【讨论】:

  • & "$folderpath\ffmpeg.exe" -i $path 2>&1 | ForEach {
【解决方案2】:

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

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]
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 2010-11-09
    • 2010-10-29
    • 2012-05-10
    • 2018-05-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多