ffmpeg:使用脚本获取持续时间:无法为 '2>&1 | 找到合适的输出格式grep“持续时间”' [重复]

Posted

技术标签:

【中文标题】ffmpeg:使用脚本获取持续时间:无法为 \'2>&1 | 找到合适的输出格式grep“持续时间”\' [重复]【英文标题】:ffmpeg: get duration using a script: Unable to find a suitable output format for '2>&1 | grep "Duration"' [duplicate]ffmpeg:使用脚本获取持续时间:无法为 '2>&1 | 找到合适的输出格式grep“持续时间”' [重复] 【发布时间】:2018-04-18 16:29:48 【问题描述】:

我试图通过从 python 脚本运行这些行来获取媒体文件的持续时间:

test_file = 'path_to_file.mp4'
ffmpeg_get_mediafile_length = ["ffmpeg", "-i", test_file, '2>&1 | grep "Duration"']
output = subprocess.Popen(ffmpeg_get_mediafile_length,
                        stdout = subprocess.PIPE
                        ).stdout.read()
print output # this gives None
matches = re_length.search(output)
print matches

这是我得到的ffmpeg 日志以及我得到的错误:

ffmpeg version 3.4 Copyright (c) 2000-2017 the FFmpeg developers
  built with Apple LLVM version 9.0.0 (clang-900.0.37)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.4 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-gpl --enable-libmp3lame --enable-libx264 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma
  libavutil      55. 78.100 / 55. 78.100
  libavcodec     57.107.100 / 57.107.100
  libavformat    57. 83.100 / 57. 83.100
  libavdevice    57. 10.100 / 57. 10.100
  libavfilter     6.107.100 /  6.107.100
  libavresample   3.  7.  0 /  3.  7.  0
  libswscale      4.  8.100 /  4.  8.100
  libswresample   2.  9.100 /  2.  9.100
  libpostproc    54.  7.100 / 54.  7.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'path_to_media_file':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.83.100
  Duration: 00:22:25.89, start: 0.000000, bitrate: 6059 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 6057 kb/s, 15 fps, 30 tbr, 90k tbn, 180k tbc (default)
    Metadata:
      handler_name    : VideoHandler
[NULL @ 0x7fedac802200] Unable to find a suitable output format for '2>&1 | grep "Duration"'
2>&1 | grep "Duration": Invalid argument

【问题讨论】:

你不能在没有 shell 的命令中传递 shell 重定向。 这不是一个有效的 ffmpeg 命令。你是说 ffprobe 吗? 如果您想知道为什么这是重复的,您应该知道管道| 和重定向> 都是shell 功能。默认情况下,子进程不调用 shell。 ***.com/questions/3172470/… 【参考方案1】:

2>&1 | grep Duration 是一个 shell 重定向。您只能将其与 shell 一起使用。

最短的事情,然后,就是生成一个shell脚本并设置shell=True

ffmpeg_get_mediafile_length = 'ffmpeg -i %s 2>&1 | grep "Duration"' % (pipes.quote(test_file))

或者,不需要更改其他代码行:

ffmpeg_get_mediafile_length = [
  'sh', '-c', 'ffmpeg -i "$1" 2>&1 | grep Duration',
  '_', test_file
]

【讨论】:

_ 在最后一个解决方案中做了什么? "$1" 在 subshel​​l 中是如何解释的? _$0 的占位符,因此test_file 变为$1 那么,和调用sh -c 'ffmpeg -i "$1" 2>&1 | grep Duration' _ path_to_file.mp4一样吗? 是的,无需担心名称是如何被引用/转义的(因为它是一个文字 argv 元素,并且只有紧跟在 -c 之后的参数被解析为代码)。【参考方案2】:

您可以尝试 ffprobe,它能够输出 JSON,并且您不需要 grep 和 regexp 结果 - 但持续时间以秒为单位返回:

import shlex
import subprocess
import json    

filePath = '/home/f3k/Downloads/tr5.mp4'
command = shlex.split('/usr/bin/ffprobe -v quiet -print_format json -show_format -show_streams')
command.append(filePath)
proc = subprocess.Popen(command, stdout = subprocess.PIPE)
stdout, _ = proc.communicate()

output = json.loads(stdout)
print  (output['format']['duration'])

返回:

1483.081723

【讨论】:

以上是关于ffmpeg:使用脚本获取持续时间:无法为 '2>&1 | 找到合适的输出格式grep“持续时间”' [重复]的主要内容,如果未能解决你的问题,请参考以下文章

FFMPEG - 将FFPROBE的持续时间输出存储为变量

FFMPEG - 获取创建和/或修改日期

FFMPEG-将视频转换为图像

使用ffmpeg libavcodec将视频流编码为H264,为啥持续时间为零

FFMPEG - 在编码后获取精确计算的音频文件大小

拆分长度不正确的音轨 - FFMPEG