gpt4 book ai didi

python - 从 FFProbe STDERR 打印字符串时输出错误

转载 作者:行者123 更新时间:2023-12-04 23:25:51 28 4
gpt4 key购买 nike

我正在尝试制作一个简单的函数来环绕 FFProbe ,并且大部分数据都可以正确检索。

问题是,当实际使用 Windows 命令提示符和 Git Bash for Windows 将字符串打印到命令行时,输出会出现困惑和无序。

某些歌曲(特别是文件 Imagine Dragons - Hit Parade_ Best of the Dance Music Charts\80 - Beazz - Lime (Extended Mix).flac )缺少元数据。我不知道为什么,但下面的函数返回的字典是空的。

FFProbe 将其结果输出到 stderr可以通过管道传送到 subprocess.PIPE ,解码和解析。我为解析位选择了正则表达式。

这是我下面代码的精简版本,输出请查看 Github gist .

#! /usr/bin/env python3
# -*- coding: utf-8 -*-

import os

from glob import glob
from re import findall, MULTILINE
from subprocess import Popen, PIPE


def glob_from(path, ext):
"""Return glob from a directory."""
working_dir = os.getcwd()
os.chdir(path)

file_paths = glob("**/*." + ext)

os.chdir(working_dir)

return file_paths


def media_metadata(file_path):
"""Use FFPROBE to get information about a media file."""
stderr = Popen(("ffprobe", file_path), shell=True, stderr=PIPE).communicate()[1].decode()

metadata = {}

for match in findall(r"(\w+)\s+:\s(.+)$", stderr, MULTILINE):
metadata[match[0].lower()] = match[1]

return metadata


if __name__ == "__main__":
base = "C:/Users/spike/Music/Deezloader"

for file in glob_from(base, "flac"):
meta = media_metadata(os.path.join(base, file))
title_length = meta.get("title", file) + " - " + meta.get("length", "000")

print(title_length)

输出 Gist
输出 Raw

我不明白为什么只有在使用 python 的 print 打印到控制台时,输出(可以有效地从正则表达式模式中检索字符串,但是输出的格式很奇怪)才会出现困惑。功能。不管我如何构建要打印的字符串、连接、逗号分隔的参数,等等。

我首先得到歌曲的长度,然后是歌曲名称,但两者之间没有空格。由于某种原因,破折号卡在最后。根据之前代码中的打印语句,格式应该是 Title - 000 ( {title} - {length} ) 但输出看起来更像 000Title - .为什么?

最佳答案

我通过我的 related question 中接受的答案解决了这个问题.

我忘记了每行末尾的回车。给出的解决方案如下:

  • 使用universal_newlines=True在子进程调用中。
  • stderr = Popen(("ffprobe", file_path), shell=True, stderr=PIPE, universal_newlines=True).communicate()[1]
  • stderr 中去除行周围的空白.
  • *.communicate()[1].decode().rstrip()最后去除所有空格。
  • *.communicate()[1].decode().strip()剥离所有的空间。
  • *.communicate()[1].decode()[:-2]删除最后两个字符。
  • 吞咽\r在正则表达式模式中。
  • findall(r"(\w+)\s+:\s(.+)\r$", stderr, MULTILINE)

  • 这一切都非常有帮助,但是我没有使用这些建议。

    我不知道 FFPROBE 向 STDOUT 提供 JSON 输出,但确实如此。执行此操作的代码如下。
    #! /usr/bin/env python3
    # -*- coding: utf-8 -*-
    from json import loads
    from subprocess import check_output, DEVNULL, PIPE


    def arg_builder(args, kwargs, defaults={}):
    """Build arguments from `args` and `kwargs` in a shell-lexical manner."""
    for key, val in defaults.items():
    kwargs[key] = kwargs.get(key, val)

    args = list(args)

    for arg, val in kwargs.items():
    if isinstance(val, bool):
    if val:
    args.append("-" + arg)
    else:
    args.extend(("-" + arg, val))

    return args


    def run_ffprobe(file_path, *args, **kwargs):
    """Use FFPROBE to get information about a media file."""
    return loads(check_output(("ffprobe", arg_builder(args, kwargs, defaults={"show_format": True}),
    "-of", "json", file_path), shell=True, stderr=DEVNULL))

    您还可以使用 arg_builder() . 它并不完美,但对于简单的 shell 命令来说已经足够了。它不是为了证明白痴,而是假设程序员不会破坏任何东西而编写了一些漏洞。

    关于python - 从 FFProbe STDERR 打印字符串时输出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48672124/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com