我需要能够按需停止它。我尝试使用taskkill /im ffmpeg.exe
优雅地终止该过程,但它不起作用。如果我用/f
强制它,则视频文件会损坏。
我认为替代方案可能是:
q
击键发送到后台运行的进程的标准输入。这是我用来创建ffmpeg.exe进程的代码(rec.pyw
),隐藏:
import subprocess
import sys
import os
# Creation flags
DETACHED_PROCESS = 0x00000008
CREATE_NO_WINDOW = 0x08000000
CREATE_NEW_PROCESS_GROUP = 0x00000200
cmd = sys._MEIPASS + os.sep + 'ffmpeg.exe -f dshow -i video=screen-capture-recorder -vcodec libx264 -qp 0 -crf 0 -vf scale=1280x720 -preset ultrafast -an -y out.mp4'
r = subprocess.call(cmd.split(), shell=True) #creationflags=
然后我使用pyinstaller创建了一个exe
文件捆绑ffmpeg
:
pyinstaller --onefile --noconsole --add-binary ffmpeg.exe;. rec.pyw
我使用了creationflags
参数,因为我已经通过分离过程读取了这个参数,我可以再次创建窗口。但我还没找到。
我发现,如果我使用.mkv
代替.mp4
,则在从任务管理器中删除ffmpeg进程时,该文件不会被破坏。
答案 0 :(得分:0)
在python脚本中,您需要使用except语句捕获信号。我不是一个Windows用户,所以我不知道unix信号如何准确地转换为你发送的内容taskkill
,但是快速谷歌如何在python中处理它,然后在except块中你想要调用一个函数来完成当前帧的写入并知道在写入该帧之后结束,然后进行清理,这可能涉及或不涉及将更多的头文件/元数据写入文件,然后关闭文件句柄。 / p>
答案 1 :(得分:0)
ffmpeg不会完全关闭,因为ffmpeg不会在Windows上使用窗口句柄运行,并且只有具有窗口句柄的程序才能捕获WM_CLOSE
命令发送的taskkill
事件。实际上,ffmpeg甚至根本没有设计来捕获WM_CLOSE
事件,因此,即使使用start
命令为ffmpeg创建了一个窗口句柄,发送时它也不会正常关闭taskkill
唯一真正的解决方案是修改ffmpeg本身,或者创建一个具有窗口句柄并可以捕获WM_CLOSE
事件的包装程序。
我遇到了同样的问题,并创建了一个包装器程序来处理WM_CLOSE
事件并正常关闭ffmpeg。它是用nim
编写的,因此您必须对其进行编译,或者可以从发行版页面中获取发行版:
https://github.com/Wykleph/ffmpeg_wrapper
您可以使用包装器启动ffmpeg并使用taskkill
杀死包装器的PID。当包装器收到WM_CLOSE
事件时,它将正常关闭ffmpeg进程。您可以使用mp4
或所需的任何编码。
ffmpeg_wrap.exe ffmpeg.exe -rtbufsize 150M -f gdigrab -framerate 30 -offset_x 448 -offset_y 240 -video_size 1024x600 -draw_mouse 1 -show_region 1 -i desktop -r 30 -preset ultrafast -tune zerolatency -movflags +faststart screen-recording.mp4
运行该程序并打开任务管理器,为pid
进程获取ffmpeg_wrap.exe
并发送taskkill
要在python
中使用它,只需启动ffmpeg_wrap
进程并获取PID,然后在需要时对PID运行taskkill
(可以在同一脚本中执行此操作)可以正常关闭ffmpeg。
此程序依赖python dll文件。我是nim
的新手,我知道如何保持ffmpeg进程打开而不会挂起的唯一方法是使用python subprocess
模块。具有subprocess
模块的任何python dll文件均应正常工作。我使用python3.8.dll
,所以绝对可以。该文件应位于:
C:/Users/username/AppData/Local/Microsoft/WindowsApps
答案 2 :(得分:0)
下面的链接文章教我通过模拟“ q”的按键来彻底停止ffmpeg的运行:
您创建了一个空文件,当您准备停止该文件时会写“ q”。
要使用python代码启动ffmpeg流,请执行以下操作:
setState()
准备在您的python代码中停止ffmpeg时,请执行以下操作:
os.system("<stop /usr/bin/ffmpeg ...")