【问题标题】:Unexpected result from Python re.search for command line outputPython re.search 命令行输出的意外结果
【发布时间】:2020-05-23 18:51:02
【问题描述】:

我正在使用 subprocess.Popen 运行 ffmpeg 命令(在 Windows 中),然后使用 re.search 使用正则表达式提取具有帧计数的输出部分。有时,即使打印的命令输出字符串清楚地显示了我的预期,我也会从搜索中得到错误的结果。

当我使用re.findall 时,我得到 2 个结果,“错误”一个和预期的一个,但在命令的输出字符串中我仍然只看到一个选项。我想了解为什么会这样。

这是我正在运行的代码:

import re
import subprocess

# path to video with 300 frames
cmd = r'ffmpeg -i C:\...\300frames_HUD.avi -map 0:v:0 -c copy -f null -'
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output_info = p.communicate()[0]

regex = r'(frame=\s*)([0-9]+)'
search_result = re.search(regex, output_info)
findall_result = re.findall(regex, output_info)
print "SEARCH"
print '0', search_result.group(0)
print '1', search_result.group(1)
print '2', search_result.group(2)

print "FIND ALL"
print findall_result

这是我得到的结果:

SEARCH
0 frame=  293
1 frame=  
2 293
FIND ALL
[('frame=  ', '293'), ('frame=  ', '300')]

这是打印出来的output_info,我正在搜索的ffmpeg命令输出:

ffmpeg version git-2020-03-15-c467328 Copyright (c) 2000-2020 the FFmpeg developers
  built with gcc 9.2.1 (GCC) 20200122
  configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
  libavutil      56. 42.100 / 56. 42.100
  libavcodec     58. 75.100 / 58. 75.100
  libavformat    58. 41.100 / 58. 41.100
  libavdevice    58.  9.103 / 58.  9.103
  libavfilter     7. 77.100 /  7. 77.100
  libswscale      5.  6.101 /  5.  6.101
  libswresample   3.  6.100 /  3.  6.100
  libpostproc    55.  6.100 / 55.  6.100
Input #0, avi, from 'C:\...\300frames_HUD.avi':
  Duration: 00:00:10.00, start: 0.000000, bitrate: 373255 kb/s
    Stream #0:0: Video: rawvideo, bgr24, 960x540, 374496 kb/s, 30 fps, 30 tbr, 30 tbn, 30 tbc
    Metadata:
      title           : V
Output #0, null, to 'pipe:':
  Metadata:
    encoder         : Lavf58.41.100
    Stream #0:0: Video: rawvideo, bgr24, 960x540, q=2-31, 374496 kb/s, 30 fps, 30 tbr, 30 tbn, 30 tbc
    Metadata:
      title           : V
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame=  300 fps=0.0 q=-1.0 Lsize=N/A time=00:00:10.00 bitrate=N/A speed=19.4x    
video:455625kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown

我实际上是在寻找frame= 300 中的 300 号码。 当我在我的 IDE (pycharm) 中连续两次快速执行它时,我可以轻松地重现它。

【问题讨论】:

  • 抱歉,您似乎获得了多个frame=num 选项。而re.search 只是返回找到的第一个。所以问题不在于正则表达式,而在于为什么你首先打印了 2 个这样的选项
  • @NikosM。我也是这么想的,奇怪的是,当我打印时它只在控制台中输出最后一个,也许命令输出两次,但python不知何故只将最后一个传递给我的打印语句。
  • @NikosM。我想通了,在下面的答案中发布了解释。

标签: python regex windows search ffmpeg


【解决方案1】:

我想通了,这不是正则表达式问题,我实际上从命令输出中得到了不止 1 个结果,但是有一个回车符 ('\r'),所以只有最后一个显示了。

我可以通过转义特殊字符看到它:

import subprocess
# path to video with 300 frames
cmd = r'ffmpeg -i C:\...\300frames_HUD.avi -map 0:v:0 -c copy -f null -'
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output_info = str(p.communicate()[0]).encode('string-escape')
print output_info

结果基本上是这样的:

"\r\nframe=  239 fps=0.0 q=-1.0 size=N/A time=00:00:07.96 bitrate=N/A speed=15.9x    \rframe=  300 fps=0.0 q=-1.0 Lsize=N/A time=00:00:10.00 bitrate=N/A speed=16.5x"

简而言之,使用 ffmpeg 命令有点奇怪,使用 re.findall 获得最后的结果似乎是正确的解决方案。

【讨论】:

  • 可能第一帧是原始帧,接下来是输出结果帧,如果发生了一些处理(只是猜测)
猜你喜欢
  • 1970-01-01
  • 2017-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 2013-08-11
  • 2016-03-10
  • 2014-04-04
相关资源
最近更新 更多