VLC-通过windows上的命令行/python/windows上的编程视频捕获以交互方式终止流/转码

VLC-通过windows上的命令行/python/windows上的编程视频捕获以交互方式终止流/转码,python,windows,command-line,subprocess,vlc,Python,Windows,Command Line,Subprocess,Vlc,我想使用vlc命令行工具从usb摄像头(在Windows上!)捕获视频。问题是不清楚什么时候停止录音。目的是捕捉用户在运行程序时的面部表情。正确的时间安排很重要。我正在像这样启动vlc: cmd = ['C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe', 'dshow://', '--dshow-size=640x480', '--dshow-adev=None', '--dshow-fps=30', '--dshow-vdev=USB_Cam

我想使用vlc命令行工具从usb摄像头(在Windows上!)捕获视频。问题是不清楚什么时候停止录音。目的是捕捉用户在运行程序时的面部表情。正确的时间安排很重要。我正在像这样启动vlc:

cmd = ['C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe', 'dshow://', 
'--dshow-size=640x480', '--dshow-adev=None', '--dshow-fps=30', 
'--dshow-vdev=USB_Camera', 
'--sout=#transcode{vcodec=h264,vb=1024,fps=30,width=640,deinterlace}
:standard{access=file,mux=ps,dst=
"path\\to\\dstfile"}', 
'--qt-start-minimized']

p = subprocess.Popen(cmd)

# ... user interaction and stuff ...

# ???? can i do sth. better here ???
p.kill()
cmd = ['C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe', 'dshow://', 
       '--dshow-size=640x480', '--dshow-adev=None', '--dshow-fps=30', 
       '--dshow-vdev=USB_Camera', 
       '--sout=#transcode{vcodec=h264,vb=1024,fps=30,width=640,deinterlace}
       :standard{access=file,mux=ts,dst=
       "path\\to\\dstfile"}', 
       '--qt-start-minimized']
kill调用的问题是转码过程被中断,这会破坏视频文件(它仍然可以播放,但最后有虚拟帧,并且帧速率/显示时间不一致)

我的问题是:是否有任何明确的可能性来正确终止流程?我想用的其他信号,比如

signal.SIGINT
signal.CTRL_C_EVENT
...
未能终止vlc,或将其杀死,从而产生相同的损坏(我不记得我尝试过的每个信号)

好的,所以answer采取了定期关闭vlc的技巧。在我的例子中,我还需要将sout标准中的muxer设置为“ts”,以便获得具有正确时间索引的视频,因此命令现在如下所示:

cmd = ['C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe', 'dshow://', 
'--dshow-size=640x480', '--dshow-adev=None', '--dshow-fps=30', 
'--dshow-vdev=USB_Camera', 
'--sout=#transcode{vcodec=h264,vb=1024,fps=30,width=640,deinterlace}
:standard{access=file,mux=ps,dst=
"path\\to\\dstfile"}', 
'--qt-start-minimized']

p = subprocess.Popen(cmd)

# ... user interaction and stuff ...

# ???? can i do sth. better here ???
p.kill()
cmd = ['C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe', 'dshow://', 
       '--dshow-size=640x480', '--dshow-adev=None', '--dshow-fps=30', 
       '--dshow-vdev=USB_Camera', 
       '--sout=#transcode{vcodec=h264,vb=1024,fps=30,width=640,deinterlace}
       :standard{access=file,mux=ts,dst=
       "path\\to\\dstfile"}', 
       '--qt-start-minimized']
我的完整解决方案可在此处找到:


使用mux=ts的最佳答案,没有这个神奇的参数,我们无法在命令行中使用VLC来保存文件。我添加了一个案例,当您希望将RTSP流从IP摄像机保存到文件时

vlc -vvv -Idummy "rtsp://admin:yourpassword@192.168.1.12:554/onvif1" --sout #transcode{vcodec=h264,scale=Auto,acodec=none,scodec=none}:standard{access=file,mux=ts,dst="D:\\mov.mp4"}" 
比如10分钟后,你想停下来,跟着

taskkill /f /IM "vlc.exe"
使用上面的命令行将使VLC成为一个NVR来记录IP摄像机
PS:解码、编码需要太多的高级知识,而我们只想应用于我们的简单案例。因此,如果有人能够总结VLC的使用情况并创建github页面,这是最好的选择

如果有人对如何通过编程方式(即从脚本启动/终止)从网络摄像头捕获视频有更好的了解,欢迎使用。尝试使用带套接字的。我在中有一个例子。Windows没有信号,因此您只能通过目标组0将
CTRL\u C\u事件
CTRL\u BREAK\u事件
发送到您所连接的控制台中的进程组,或者发送到控制台的所有进程(包括您自己的进程)。创建流程时,您可以通过创建标志
create_new_process_group
将其指定为新组的负责人,该标志仅在它是控制台流程或以后分配控制台时才有意义。此创建标志在过程中禁用Ctrl+C,因此除非手动启用,否则您可以可靠地发送的只是Ctrl+Break。@eryksun使用rc_接口的解决方案非常酷。谢谢。我将它改编为我的项目,如下所示:它解决了VLC以常规方式终止的问题。但我得到了我所见过的奇怪的错误信息:[0049445c]核心接口错误:读取错误:没有错误,而且它生成的视频仍然没有正确的时间索引,所以我的假设可能是错误的,即这是因为没有终止vlc。好吧,将sout中的muxer设置为ps就成功了