我有一个Java程序,它使用来自framegrabber卡的视频。该程序通过python launcher.py
启动。
读取我发现的视频流的最简单方法是在命名管道上读取Java,这非常有效。所以我的会议就像:
$ mkfifo videopipe
$ cat /dev/video1>videopipe
并在第二个终端中(因为cat
命令正在阻止):
$ python launcher.py
我想自动化这个过程。不幸的是,结果始终是相同的:Java应用程序启动(通过java程序中的print语句确认),但终端停止并且没有任何内容出现,异常或其他。
由于这个过程是手动的,我猜我在python程序中做错了。为简化起见,我将管道部分隔离开来:
from subprocess import call, Popen, PIPE, check_call
BASH_SWITCHTO_WINTV = ['v4l2-ctl', '-d /dev/video1', '-i 2', '--set-standard=4']
BASH_CREATE_FIFO_PIPE = ['mkfifo', 'videopipe']
BASH_PIPE_VIDEO = 'cat /dev/video1>videopipe'
def run():
try:
print('running bash commands...')
call(BASH_SWITCHTO_WINTV)
call(BASH_CREATE_FIFO_PIPE)
Popen(['cat', '/dev/video1'], stdout=open('videopipe', 'w'))
except:
raise RuntimeError('An error occured while piping the video')
if __name__ == '__main__':
run()
运行时输出:
running bash commands...
Failed to open /dev/video1: No such file or directory
非常感谢一点帮助: - )
答案 0 :(得分:2)
如果你正在使用shell=True
,只需传递一个字符串:
BASH_PIPE_VIDEO = 'cat /dev/video1 > videopipe'
目前,cat
作为脚本传递给shell,/dev/video>videopipe
作为文字参数传递给该shell - 根本不作为脚本文本的一部分进行解析,并且没有因为脚本(只是调用cat
)不会查看其参数。
或者,为了避免不必要的shell使用(以及因此与shell相关的错误,例如shellshock,以及如果您接受来自非硬编码源的任何参数,可能会发生注入攻击):
Popen(['cat', '/dev/video1'], stdout=open('videopipe, 'w'))
在与“cat to named pipe”问题无关的说明中 - 请确保您的空格正确无误。
BASH_SWITCHTO_WINTV = ['v4l2-ctl', '-d /dev/video1', ...]
...使用名称<space>/dev/video1
,和前导空格作为输入设备;它与在shell中运行v4l2-ctl "-d /dev/video1"
相同,这会导致同样的问题。
请确保正确拆分参数:
BASH_SWITCHTO_WINTV = ['v4l2-ctl', '-d', '/dev/video1', ...]