我正在使用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)中连续连续两次执行它时,可以轻松地重现它。
我想出来了,这不是正则表达式问题,实际上我从命令输出中得到了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
获得最后的结果似乎是正确的解决方案。