我有一个脚本可以在本地保存5秒长的视频,但它会省略文件名。
这是bash命令
ffmpeg -i http://0.0.0.0:8080/stream/video.mjpeg -vcodec copy -map 0 -f segment -segment_time 2 -loglevel 40 -segment_format mp4 capture-%05d.mp4 2>&1 | grep --line-buffered -Eo "segment:.+ended" | gawk -F "'" '{print $2; system("")}' | xargs -n1
如果我在终端中运行此命令,它将返回预期的文件名,因此
capture-00001.mp4
请注意,最后的xargs
命令可以让我将文件名作为新参数传递给python脚本。但现在我想在Python本身中执行此命令,特别是使用subprocess
获取文件名。
这是我到目前为止所做的。运行脚本时,终端将按预期打印文件名,但不会将其作为字符串传递给fName
。我已经尝试了subprocess.check_output
但它从未传递任何内容,因为命令会持续捕获视频并将其保存在本地。
FFMPEG_SCRIPT = r"""ffmpeg -i http://0.0.0.0:8080/stream/video.mjpeg -vcodec copy -map 0 -f segment -segment_time 2 -loglevel 40 -segment_format mp4 capture-%05d.mp4 2>&1 | grep --line-buffered -Eo "segment:.+ended" | gawk -F "'" '{print $2; system("")}' | xargs -n1 """
try:
fName = subprocess.check_call(FFMPEG_SCRIPT, stderr=subprocess.STDOUT, shell=True).decode('utf-8')
print(">>> {}".format(fName))
except subprocess.CalledProcessError as e:
print(e.output)
答案 0 :(得分:0)
import subprocess
from subprocess import PIPE
fName = subprocess.Popen("test.bat", stdin=PIPE, stdout=PIPE)
(stdout, stderr) = fName.communicate()
print(">>> {}".format(fName))
print(stdout)
test.bat是一个简单的echo yes
,因为我无法使用您的脚本进行测试,结果print(stdout)
的输出为b'yes\r\n'
。如果文件名是脚本打印的唯一内容,那么提取它就不会太难。
答案 1 :(得分:0)
管道命令时,这是一个常见问题。 IO子系统在终端和文件或管道上处理不同的输出。在终端上,输出在每个换行符上刷新,除非程序明确要求显式刷新,否则不会附加到文件或管道上。
第一个命令在文件末尾结束的管道上不存在问题,因为在命令存在之前刷新所有内容,并关闭管道的写入结束。因此,下一个命令会看到文件结束,一切都会顺利传播。
但是当第一个程序包含无限读取循环时,它会对其输出进行排队,但在缓冲区已满之前不会刷新任何内容,并且缓冲区在现代系统上是巨大的。在这种情况下,一切正常,但你看不到任何输出。
答案 2 :(得分:0)
这是基于Alexandre Cox提议的版本,带有通过管道命令检查安装的命令:
import subprocess
fName = subprocess.Popen('mount | grep sda3 | cut -d " " -f 3', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
(stdout, stderr) = fName.communicate()
print(">>> {}".format(fName))
print(stdout)
如果安装存在,则输出为:
>>> <subprocess.Popen object at 0x7f9b5eb2fdd8>
b'/mnt/sda3\n'